Just like the jQuery's one http://api.jquery.com/jQuery.isWindow/. But more relible.
-
-
Save tsaniel/1264086 to your computer and use it in GitHub Desktop.
function( | |
a, // input | |
b // placeholder for property document of a | |
){ | |
return | |
// cannot be falsy value, mainly to prevent null and undefined (regarded as global object in some browsers) | |
!!a && | |
// checking types with Object.prototype.toString.call is always a good way | |
// however, for window, is a bit difficult | |
// let's see the results in different browsers (except IE678, which return "[object Object]") | |
// "[object Window]" | |
// "[object DOMWindow]" | |
// "[object global]" | |
// so, we can simply check if the input's [[Class]] is ended with w] or l] | |
/[wl]]/.test({}.toString.call(a)) || | |
// believe me, IE is not a good guy | |
// why? | |
// because in which, window == document but document != window | |
// what a wtf feature! | |
a == (b=a.document) && b != a | |
} |
(function(a,b){return!!a&&/[wl]]/.test({}.toString.call(a))||a==(b=a.document)&&b!=a}) |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "isWindow", | |
"description": "Check if the input is window.", | |
"keywords": [ | |
"window", | |
"isWindow", | |
"DOM", | |
"jQUery" | |
] | |
} |
<!DOCTYPE html> | |
<title>Foo</title> | |
<div>Expected value: <b>true</b></div> | |
<div>Actual value: <b id="ret"></b></div> | |
<script> | |
// write a small example that shows off the API for your example | |
// and tests it in one fell swoop. | |
var myFunction = (function(a,b){return!!a&&/[wl]]/.test({}.toString.call(a))||a==(b=a.document)&&b!=a}) | |
document.getElementById( "ret" ).innerHTML = myFunction(window) | |
</script> |
You could try a&&a.alert
additionally
@atk: Thanks again! But an fake object {alert:1,toString:function(){return 'w]'}}
still passes the test.
That's true. How about (a||0).constructor===this.Window
? Works in all modern browsers (not in IE 7 or older).
Not in Chrome 14.
this.constructor !== window
Damn, there it's DOMWindow... /Wi/.test(a.constructor)
, maybe?
{constructor:'Wi'}
Let's try this:
function(a,b){b=this.Window||this.DOMWindow;return!!a&&b?a instanceof b:a==(b=a.document)&&b!=a}
It is sad that it won't work with iframes...
Rewritten to probably work with (i)frames:
function(a,b){return!!a&&(b=a.Window||a.DOMWindow)?a instanceof b:a==(b=a.document)&&b!=a}
It cannot work with my chromium 12...
Alas, it's not exposed in Chrome. OK, let's try this:
function(a,b){return!!a&&(b=top.constructor)?a instanceof b:a==(b=a.document)&&b!=a}
It won't work with (i)frame as well, because the scope of top
differs from (i)frame.
Right. Any idea how to get DOMWindow in Chrome if its not exposed?
The magic __proto__
?
Doesn't help very much, because it is different between frames.
I think it is hard. In fact, the original code is enough.
Try this:
function(a,b){return a&&a==a[b='window']&&a==a[b][b]}
Clever. Exploiting the fact that any global object is exposed as a property of window, and window itself is a global object.
@phoetry: It's clever but it won't work.
var a = {};
a.window = a;
(function(a,b){return a&&a==a[b='window']&&a==a[b][b]})(a) // true
You can even eliminate the toString call completely, because .test() coerces its first argument into String.