I maintain some donation forms that include the GeoTrust SSL 'smart icon'. This is generated by including a script reference as so within the document where you want the seal to appear:
<script type="text/javascript" src="//smarticon.geotrust.com/si.js"></script>
Their script is obviously doing a document.write(), and if/when geotrust is being slow it blocks rendering of my donation form for up to a few seconds.
I can't use the 'async' attribute, because of the document.write(). I can't edit or rewrite GeoTrust's javascript of course. And loading the js in the footer or doing the 'append to the head' approach doesn't help either because the script needs to execute within the markup where we want the icon to appear. A further complication is that these donate pages are also part of a different third-party system full of their own javascript etc.
Here's an approach that seems to work, but I'm wondering if there's a better way:
<div id="vs_seal"></div>
<script type="text/javascript">
r(function() {
var div = document.getElementById('vs_seal');
writebackup = document.write;
document.write = function(markup) {
div.innerHTML = markup;
document.write = writebackup;
}
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= '//smarticon.geotrust.com/si.js';
document.body.appendChild(script);
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
</script>
(PS I totally stole that domready test from http://www.dustindiaz.com/smallest-domready-ever )
EDIT: If it isn't clear, what I'm doing is
- writing a div
- waiting for the dom to be ready (last line)
- saving document.write as a variable
- overriding document.write to instead insert the output into a div
- loading the script dynamically via appendChild
- when the script calls the overriden document.write, the last line of the override is to reset document.write to the original version (that I saved as a variable).
EDIT: After the comments below, I've simply put it into an IFRAME instead.
<style>#vs_seal iframe{border:0 none;}</style>
<div id="vs_seal"></div>
<script type="text/javascript">
r(function() {
var div = document.getElementById('vs_seal');
var iframe = document.createElement('iframe');
iframe.width = 118;
iframe.height = 55;
iframe.frameborder = 0;
iframe.scrolling = "no";
iframe.seamless = "true";
iframe.src = 'about:blank';
var content = '<!DOCTYPE html>'
+ '<head><title>Dynamic iframe</title>'
+ '<style>body{margin:0;padding:0;border:0;}</style></head>'
+ '<body><script type="text/javascript" src="//smarticon.geotrust.com/si.js">'
+ '<\/script><\/body><\/html>';
div.appendChild(iframe);
iframe.contentWindow.document.open('text/html', 'replace');
iframe.contentWindow.document.write(content);
iframe.contentWindow.document.close();
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
</script>
I originally tried pulling in the content into a hidden IFRAME and then copying the innerHTML from the IFRAME into my div, but GeoTrust's javascript that makes their popup window all pretty needs to be executed in the context its being clicked on. The innerHTML doesn't execute the javascript, and there seemed to be no advantage to not just displaying the IFRAME.
Thanks for the comments and suggestions!