As Mattias Buelens explained, document.write
calls the open
method, which clears the DOM, simply because -after loading- the document.close
method is called automatically. There are a number of alternatives you can use, of course.
Use the innerHTML
attribute of the body
element, for example.
Using document.createElement
and document.body.appendChild
is an option, too
But perhaps it's worth taking into consideration that both methods have their downsides: using innerHTML
allows you to inject badly formatted markup into the DOM, and could leave you vulnerable to XSS attacks.
Using document.createElement
is slower (generally) and often requires more code, which in turn makes your script(s) less maintainable.
You could use something like this:
var flip = (function(tempDiv)
{//create a div once
var page = 0,
targetDiv = document.getElementById('contentgoeshere');//closure variables
//page is now no longer an evil global, and the target element into which
//we will inject new data is referenced, so we don't have to scan the DOM
//on each function call
return function(overridePage)//optional argument, just in case
{//actual flip function is returned here
overridePage = overridePage || page++;//new content
tempDiv.innerHTML = overridePage;//render in div that isn't part of the DOM
//any number of checks can go here, like:
if (tempDiv.getElementsByTagName('script').length > 0)
{
alert('Naughty client, trying to inject your own scripts to my site');
return;
}
targetDiv.innerHTML = tempDiv.innerHTML;
//or, depending on your needs:
targetDiv.innerHTML = tempDiv.innerText;//or the other way 'round
};
}(document.createElement('div')));
A couple of side-notes: as it now stands, this function won't work because the DOM has to be fully loaded for the closure to work. A quick fix would be this:
var flip;//undefined
window.onload = function()
{
flip = (function(tempDiv)
{
var page = 0,
targetDiv = document.getElementById('contentgoeshere');
return function(e)
{
tempDiv.innerHTML = e instanceof Event ? page++ : (e || page++);//ternary + logical or
//your [optional] checks here
targetDiv.innerHTML = tempDiv.innerHTML;
if (e instanceof Event)
{//this part is optional, but look it up if you want to: it's good stuff
e.returnValue = false;
e.cancelBubble = true;
if (e.preventDefault)
{
e.preventDefault();
e.stopPropagation();
}
}
return e;
};
}(document.createElement('div')));
//instead of using the HTML onclick attribute:
document.getElementById('buttonID').onclick = flip;//use as event handler
};
Note that window.onload
causes memory leaks on IE<9, check this link for the solution to this issue