As a result of our client needing a responsive (CSS) website and the requirement of working within their extremely basic CMS platform, we have written a script to go along with a page’s worth of custom HTML that:
- saves our HTML to a variable,
- clears out the entire
headanddocument, - and then adds our custom HTML back into the
document.bodyas the only HTML content.
This ensures that there isn’t any garbage HTML, <style> or <link> items leftover from the CMS that interferes with the responsive layout. Our custom CSS requires that we reach all the way to the body element.
Test page w/problem: https://www.eiseverywhere.com/ehome/index.php?eventid=31648&tabid=53961
However, the script is running from within a nested table in the document, as that is where the CMS is placing our content (within its preset page template).
This seems to work smoothly (albeit in noticable “passes”) in all modern browsers, including FF, Chrome, Safari, iOS, and IE9.
And with IE8, several different things are happening each time the page is reloaded:
-
Page loads with no errors, but only HTML element is visible (black background). All other elements are completely invisible, but there (eg. links can be clicked on if found).
-
Page loads black and invisible as described above, but status bar indicates error 927917.
-
Page begins to load content visibly (background images, etc), but is interrupted by Operation Aborted 927917 error pop-up, followed by a redirect to blank white “Could not load page” page.
-
Page loads everything normally, without any errors.
Any four of these things happen in IE8 when attempting to load the page, and we’re not sure what is causing this inconsistency. It is making it very hard to troubleshoot.
With IE7, we are getting similarly inconsistent results, and the known bug 927917
The overarching question here would be, given the requirements, code, and content, what is the best way to perform this content swap/injection? We’re only interested in supporting IE7+, and willing to ditch IE7 all together if it is too troublesome.
We’ve tried some of the following suggestions, but have gotten mixed results between IE7 and IE8, none of which completely solve the problems listed above:
http://www.timvasil.com/blog14/post/2008/05/28/Fix-for-IEs-Operation-Aborted-error.aspx
http://blogs.msdn.com/b/ie/archive/2008/04/23/what-happened-to-operation-aborted.aspx
CMS output before our script kicks in:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Title</title>
<!-- CMS included meta tags -->
<meta name="description" content="event title" />
<meta name="keywords" content="meta-tags" />
<!-- CMS included scripts -->
<script language="javascript" type="text/javascript" src="/include/scripts/scripts.js"></script>
<script language="javascript" type="text/javascript" src="/ehome/include/scripts.js"></script>
<style type="text/css"> /* CMS styles */ </style>
<!-- CMS JS Library inclusion - could possible use this to wait for DOM ready -->
<script type="text/javascript" src="/include/scripts/prototype.js">
</script>
</head>
<body>
<form>
<input type="hidden" id="module" value="ehome" /><input type="hidden" id="eventid" value="31648" />
</form>
<table id="shadow_table">
<tr>
<td></td>
<td>
<table id="outer_table">
<!-- Lots of CMS table HTML -->
<tr>
<td id="inner_content">
<div class="eh_outer_div">
<div id="main_section">
<div>
<div>
<!-- BEGIN OUR CUSTOM CODE - intended to replace body contents -->
<div id="wrap">
<!--[if (gte IE 6)&(lte IE 8)]>
<script src="https://www.eiseverywhere.com/docs/562/selectivizr.js"></script>
<![endif]-->
<!--[if lt IE 9]>
<script src="https://www.eiseverywhere.com/docs/562/html5.js"></script>
<script src="https://www.eiseverywhere.com/docs/562/iemq.js"></script>
<![endif]-->
<header>
<!-- header content... -->
</header>
<div id="main">
<ul>
<li data-id="home"><a href="https://www.eiseverywhere.com/ehome/index.php?eventid=31648&tabid=50283">Home</a></li>
<!-- Other nav items... -->
</ul>
<h1>speakers</h1>
<section id="content">
<!-- Begin Main Content Section -->
<article>
<h2>CITE <strong>2012 speakers</strong></h2>
<p><strong>Our speaker list is growing continuously, so check back often for updates. Our esteemed roster so far includes:</strong></p>
<!-- Misc main content - etc.. -->
</article>
</section>
</div><!-- End Main -->
</div><!-- End #wrap Wrapper -->
<footer>
<div>
<ul>
<li data-id="home"><a href="https://www.eiseverywhere.com/ehome/index.php?eventid=31648&tabid=50283">Home</a></li>
<!-- Other nav items... -->
</ul>
<!-- Misc footer content... -->
</div>
</footer> <!-- End Footer -->
<!-- Cleaning Code -->
<!-- THIS IS WHERE THE REPLACEMENT SCRIPTING IS (<SCRIPT>) -->
<!-- END CUSTOM CONTENT -->
</div>
</div>
</div>
</div>
</td>
</tr>
<!-- LOTS OF OTHER UNNECESSARY CMS TABLE MARKUP... -->
</table>
<!-- Garbage DIVs from CMS scripts -->
<div id="overlay"></div>
<div id="home_od"></div>
</body>
</html>
UPDATED: Our custom replacement/injection script with DOM ready():
<script type="text/javascript">
/* Clean.js /// Switches out host HTML and replaces with clean custom HTML */
document.observe('dom:loaded', function() { // Prototype.js listener: http://www.prototypejs.org/api/document/observe
/* PAGE VARIABLES */
var pre = '<!--[if lt IE 7 ]><div id="wrap" class="ie pre9 ie6"><![endif]--><!--[if IE 7 ]><div id="wrap" class="ie pre9 ie7"><![endif]--><!--[if IE 8 ]><div id="wrap" class="ie pre9 ie8"> <![endif]--><!--[if IE 9 ]><div id="wrap" class="ie ie9"> <![endif]--><!--[if (gt IE 9)|!(IE)]><!--><div id="wrap"><!--<![endif]-->';
var wrap = document.getElementById('wrap');
var title = wrap.getElementsByTagName('h1')[0].innerHTML;
var pgid = title.replace(/[^a-zA-Z 0-9]+/g,'-').toLowerCase().replace(/[ ]/g, '-'); // clean H1 text and use as page id
var footer = "<footer>" + document.getElementsByTagName('footer')[0].innerHTML + "</footer>";
var content = pre + wrap.innerHTML + footer;
var post = '</div>';
/* HOUSE CLEANING */
// Clean out <HEAD>
emptyHead(); //remove all style blocks from head
removeLinks("js"); //remove all occurences of "somescript.js" on page
removeLinks("css"); //remove all occurences "somestyle.css" on page
// Stage <BODY>
document.body.setAttribute("id", pgid);
document.body.setAttribute("onload", "finished('"+pgid+"')");
document.title = "CITE Expo + Conference: March 4-6, 2012 | " + title;
document.body.innerHTML = content + post;
// document.body.insertAdjacentElement('afterBegin', document.getElementsByTagName('footer')[0]);
// document.body.insertAdjacentElement('afterBegin', wrap);
// document.body.removeChild(document.getElementById('shadow_table'));
// Add meta tags
addMetatag('viewport', 'head');
// Add stylesheets
addStylesheet('https://www.eiseverywhere.com/file_uploads/d1d7aeedb561585d601535bb14aa6910_cite.css', 'head');
addStylesheet('https://www.eiseverywhere.com/file_uploads/cead2f725f0acc8b4ada117d22b2e872_type.css', 'head');
addStylesheet('https://www.eiseverywhere.com/file_uploads/41062e7af46018760d01e8d9f7a7b9a9_flex.css', 'head');
addStylesheet('https://www.eiseverywhere.com/file_uploads/fff3d12e98686a02eb8e8f2ac45f7bf8_anm8.css', 'head');
addStylesheet('https://www.eiseverywhere.com/file_uploads/64388fdb8762f9232b2330f9e196f996_benton-gothic-cite.css', 'head');
addStylesheet('https://www.eiseverywhere.com/file_uploads/f92ea468d4be1013b77010d2c42fdc6f_stag-cite.css', 'head');
// Add javascript
/* addJavascript('https://www.eiseverywhere.com/file_uploads/3df3d4e3b7e57d447396fe2608c96664_jump.js', 'body'); // Not working well - need to inject a new element */
addJavascript('https://www.eiseverywhere.com/file_uploads/b8601cc668024431aae05a886084fc37_android21.js', 'body');
/* FUNCTIONS */
function emptyHead()
{
var head = document.getElementsByTagName('head')[0];
var s = head.getElementsByTagName('style');
if(s)
while(s.length >= 1)
head.removeChild(s[0]);
}
function emptyBody()
{
// document.body.removeChild(document.getElementById("overlay"));
// document.body.removeChild(document.getElementById("home_od"));
}
function addJavascript(jsname, pos)
{
var th = document.getElementsByTagName(pos)[0];
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('src', jsname);
th.appendChild(s);
}
function addStylesheet(cssname, pos2)
{
var th2 = document.getElementsByTagName(pos2)[0];
var s2 = document.createElement('link');
s2.setAttribute('type', 'text/css');
s2.setAttribute('href', cssname);
s2.setAttribute('media', 'screen');
s2.setAttribute('rel', 'stylesheet');
th2.appendChild(s2);
}
function addMetatag(meta, pos3)
{
var th3 = document.getElementsByTagName(pos3)[0];
var s3 = document.createElement('meta');
s3.setAttribute('name', meta);
s3.setAttribute('content', 'width=device-width, minimum-scale=1.0, maximum-scale=1.0');
th3.appendChild(s3);
}
function removeLinks(filetype)
{
var targetelement = (filetype == "js") ? "script" : (filetype == "css") ? "link" : "none" //determine element type to create nodelist from
var targetattr = (filetype == "js") ? "src" : (filetype == "css") ? "href" : "none" //determine corresponding attribute to test for
var allsuspects = document.getElementsByTagName(targetelement)
for (var i = allsuspects.length; i >= 0; i--) //search backwards within nodelist for matching elements to remove
if (allsuspects[i] && allsuspects[i].getAttribute(targetattr) != null)
allsuspects[i].parentNode.removeChild(allsuspects[i]) //remove element by calling parentNode.removeChild()
}
document.stopObserving("dom:loaded")
});
function finished(pid) // DOM is [natively] ready
{
setMenu(pid); // set the active class on li elements that contain a link to the current page
// emptyBody(); // remove junk divs from bottom of page
setLayout(); // if <aside> is missing, set #main to .single-column class
if(pid == "home") {
var anm8 = '<object type="application/x-shockwave-flash" data="http://client.clevelanddesign.com/CD/IDG/CITE/content/intro.swf"><!-- By default, play flash video --><param name="movie" value="http://client.clevelanddesign.com/CD/IDG/CITE/content/intro.swf" /><param name="wmode" value="transparent" /><param name="scale" value="default" /><!-- Show iPad/iPhone/iPod visitors the HTML5 video --><video autoplay poster="https://www.eiseverywhere.com/file_uploads/e82b83f31bb069e818fe691ebc824cf1_mtng-locked.png"><source src="https://www.eiseverywhere.com/docs/562/intro-compressed.mp4" type="video/mp4"></source></video><!-- Backup image if all else fails --><img src="https://www.eiseverywhere.com/file_uploads/e82b83f31bb069e818fe691ebc824cf1_mtng-locked.png" alt="Meet the next generation of business" /></object>';
document.getElementById('hero').innerHTML = anm8; // if home page, add animation after page is loaded
}
window.scrollTo(0, 1); // scroll mobile address bars out of sight (iPhone, Android) - gives us more screen space
}
function setMenu(p) // compare cleaned H1 text to link IDs // requires consistent naming between H1 and li.data-id // update topnav + footer HTML snippets in eTouches to match
{
var mitems = document.getElementsByTagName('li');
for(i = 0; i < mitems.length; i++) {
if(mitems[i].getAttribute('data-id'))
if(mitems[i].getAttribute('data-id') == p)
mitems[i].setAttribute("class", "active");
}
}
function setLayout()
{
if(!document.getElementsByTagName('aside').length)
document.getElementById("main").setAttribute("class", "single-column");
}
</script>
<!--[if IE 7 ]>
<script type="text/javascript">
// alert('Please upgrade to a modern browser to enjoy this website properly.');
</script>
<![endif]-->
Both removing the “defer” attribute and enclosing the manipulation code inside of a document ready event (a la Prototype.js) have solved the problems described in the original question. IE 7/8 no longer fail to load or load inconsistently.
Thanks to both @jfriend00 and @Alfabravo for their tips.
I am still having issues with (all browsers) the native onLoad body event and its function not firing, and the fact that IE 7/8 are randomly dropping stylesheets, but I believe that is a separate problem.