-
-
Save mathiasbynens/944168 to your computer and use it in GitHub Desktop.
var elemDisplays = {}, | |
// Store the iframe outside the function to reuse it | |
iframe, | |
iframeDoc; | |
function defaultDisplay( nodeName ) { | |
if ( !elemDisplays[ nodeName ] ) { | |
// Try the classical method first, which is far faster | |
var elem = document.createElement( nodeName ), | |
display; | |
document.body.appendChild( elem ); | |
display = window.getComputedStyle( elem ).getPropertyValue( "display" ); | |
document.body.removeChild( elem ); | |
// if the display value is "none", use an iframe | |
if ( display === "none" || display === "false" ) { | |
// No iframe to use yet, so create it | |
if ( !iframe ) { | |
iframe = document.createElement( "iframe" ); | |
iframe.frameBorder = iframe.width = iframe.height = 0; | |
} | |
document.body.appendChild( iframe ); | |
/* Create a cacheable copy of the iframe document on | |
* first call. | |
* IE and Opera will allow us to reuse the iframeDoc | |
* without re-writing the fake html document to it, | |
* WebKit & Firefox won't allow reusing the iframe document | |
*/ | |
if ( !iframeDoc || !iframe.createElement ) { | |
iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; | |
iframeDoc.write( "<!doctype><html><body></body></html>" ); | |
} | |
elem = iframeDoc.createElement( nodeName ); | |
iframeDoc.body.appendChild( elem ); | |
display = jQuery.css( elem, "display" ); | |
document.body.removeChild( iframe ); | |
} | |
elemDisplays[ nodeName ] = display; | |
} | |
return elemDisplays[ nodeName ]; | |
} |
var elemDisplays = {}, | |
// Store the iframe outside the function to reuse it | |
iframe, | |
iframeDoc; | |
function defaultDisplay( nodeName ) { | |
if ( !elemDisplays[ nodeName ] ) { | |
// Try the classical method first, which is far faster | |
var elem = document.createElement( nodeName ), | |
body = document.body, | |
display, | |
style; | |
body.appendChild( elem ); | |
display = window.getComputedStyle ? window.getComputedStyle( elem ).getPropertyValue( "display" ) : "none"; | |
body.removeChild( elem ); | |
// if the display value is "none", use an iframe | |
if ( display === "none" || display === "" ) { | |
// No iframe to use yet, so create it | |
if ( !iframe ) { | |
iframe = document.createElement( "iframe" ); | |
iframe.frameBorder = iframe.width = iframe.height = 0; | |
} | |
body.appendChild( iframe ); | |
/* Create a cacheable copy of the iframe document on | |
* first call. | |
* IE and Opera will allow us to reuse the iframeDoc | |
* without re-writing the fake html document to it, | |
* WebKit & Firefox won't allow reusing the iframe document | |
*/ | |
if ( !iframeDoc || !iframe.createElement ) { | |
iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; | |
iframeDoc.write( "<!doctype html><html><body>" ); | |
iframeDoc.close(); | |
} | |
elem = iframeDoc.createElement( nodeName ); | |
style = element.currentStyle || element.style; | |
iframeDoc.body.appendChild( elem ); | |
if ( document.defaultView && document.defaultView.getComputedStyle ) { | |
display = elem.ownerDocument.defaultView.getComputedStyle( elem, null ).getPropertyValue( 'display' ); | |
if ( display == "" ) { | |
display = style.display; | |
} | |
} else { | |
display = style.display; | |
} | |
body.removeChild( iframe ); | |
} | |
elemDisplays[ nodeName ] = display; | |
} | |
return elemDisplays[ nodeName ]; | |
} |
You’re forgetting IE support. Also see this for other considerations. I think this technique requires moar testing.
Ah I missed your rewrite when commenting. Looks a lot better \o/. Though, I still see the ( iframe.contentWindow || iframe.contentDocument ).document
, if the iframe.contentDocument
side is used it would be like doing document.document
and should return undefined
for the iframe document.
I think some browsers barf when not passing something like null
as the second argument of getComputedStyle
, Also I think you should avoid window.getComputedStyle
and instead store a reference to elem.ownerDocument.defaultView
in a var so it can be reused throughout the snippet.
display === "false"
should be display == ""
.
I understand that this is very very old code, however it was helpful in one scenario I believe.
Background: jQuery version 2.1.3 (https://code.jquery.com/jquery-2.1.3.js) has following snippet:
iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
Can I replace it with following code (from your example)
if ( !iframe ) {
iframe = document.createElement( "iframe" );
iframe.frameBorder = iframe.width = iframe.height = 0;
}
doc.documentElement.appendChild( iframe );
The purpose is very strange, in short, web firewall's stupid rule is preventing jQuery code to be executed saying that this is an iframe injection. Will the snippet serve the original purpose?
Please let me know.
Thank you.
Mad props to @gf3 and @jdalton!
Quick demo / test case: http://mathiasbynens.be/demo/default-display Still a work in progress.