Same as me “jeresig” does not like to spend much time on some code just because some jokers, can produce a use-case which is breaking it. Where in the same time the same use-case is never seen and never used, in real application code situation.
One of the examples of this attitude is jQuery.isWindow(). It is rather simple (or “crude”) implementation and yes it is indeed rather easy to be a joker and break it.
1 2 |
jQuery.isWindow({ setInterval: true }); // returns true .. which is wrong answer, of course |
This is the original jQuery function which John has decided not to improve.
1 2 3 4 5 6 7 8 |
// the current jQuery.isWindow() jQuery.isWindow = function( obj ) { return obj && typeof obj === "object" && "setInterval" in obj; } |
Above is apparently “good enough” and jQuery leader and his team have decided to close comments on it’s API DOC page. And I can understand them being very tired of exchanges with over-excited kids on jQuery core forum.
But. If there is a simple and robust solution would it be possible to use it? I think I have one.
1 2 3 4 5 6 7 8 |
// jQuery isWindow replacement // (c) dbj.org (function (theWindow) { jQuery.isWindow = function (obj) { return obj === theWindow || obj === theWindow.top ; } }(window)) |
I see no reason for above not to work flawlessly anywhere where there is DOM, i.e. in any browser? Perhaps there is acceptable real-life use-case based on frames where this version of isWindow()
breaks?
Actually thinking of which why not expanding a bit more on this useful idiom?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// (c) 2011 by DBJ.ORG (function (theWindow, undefined) { "use strict" ; // no point in proceeding if there is no dom if ( ! theWindow ) throw "object window not found, is there no DOM here?" ; if ( dbj == undefined ) dbj = {} ; dbj.isWindow = function (obj) { // check the top window // if we do not match this window return obj === theWindow || obj === theWindow.top ; } dbj.isDocument = function (obj) { // check the top document // if we do not match this document return obj === theWindow.document || obj === theWindow.top.document ; } dbj.isBody = function (obj) { // check the top body // if we do not match this body return obj === theWindow.document.body || obj === theWindow.top.document.body ; } }(window)) |
This tree little utilities should be a pretty firm confirmation (or denial) when checking the identity of three top level DOM objects. Even in the presence of frames, or jokers.
Update 14.Aug.11
Actually, why not being pure and true to oneself :) In above utilities I have done a “cardinal sin”, I have produced a function which does “two things”. And not one but three of them. I was trying to find my quick way, around DOM issue of having frames. But that is not the same issue as checking if given object is a top level immediate global object. Instead why not having rock solid, consistent method of checking is object an immediate top level run-time environment object. Which in DOM happens to be “window”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/* (c) 2011 by DBJ.ORG return true if argument given is a top level and immediate global run-time object does not require DOM NOTE: if case ES5 "use strict" directive is used, global 'this' is undefined */ "use strict"; (function (theTop, undefined ) { if (undefined === dbj) dbj = {} ; dbj.isTop = function (obj) { return obj === theTop ; } }(this)); /* now 100% safe isWindow() can be made using the dbj.isTop() NOTE: DOM not required here */ function isWindow( obj ) { return dbj.isTop(obj); } |
There you have it. A utility function which exhibits clear-cut responsibility, and works anywhere where there is JavaScript. DOM not necessary.
DOM is one of the very few, if not the only JavaScript run-time environment where there is a single global ‘this’
object available. Provided ES5 “use strict” is not used.
2 thoughts on “jQuery better isWindow() is not for window”
If you want to be consistent then window.top is not enough, you’d have to check all the other frames as well (window.frames). But maybe a more troubling question is: why is such a “crude” function even exposed publicly, without any notice?
@Balazs
I think You might believe me when I say that I know that I could check all the other frames. But this is where I think unreal use-case comes in, which is not worthy of solving?
One another example might be deeply nested IFRAMES. Like hundreds of levels deep. In such a joke scenario dbj.isWindow() will certainly fail. But is that actually a real problem?