Monkey patching document.write()
This is one of the crazier workarounds that I have implemented. I was working on a web page that embeds third-party widgets. The widgets are drawn in the page document - they do not get their own frames. And sometimes the widgets are redrawn after page load.
We had a problem with one widget invoking
document.write(). In case
you are not familiar with it, if that method is called while the page is
rendering it inserts content into the DOM immediately after the script
tag in which the call is made. But if
document.write() is called
after page rendering is complete it erases the entire DOM. When this
widget was redrawn after page load it would kill the whole page.
The workaround we went with was to disable
document.write() after page
load by replacing it with a wrapper that checks whether the jQuery ready
event has fired.
The new implementation checks the value of
delegates to the original
document.write() implementation if the page
is not finished rendering yet. Otherwise it does nothing other than to
output a warning message.
document.write() means that the problematic widget will not
be fully functional if it is redrawn after page load. It happens that
in the case of this app that is ok. The redrawn widget is only used as
a preview when editing widget layouts.
A particular problem came up with IE compatibility. I wanted to use the
invoke the original
document.write() implementation, like this:
But in older versions of Internet Explorer,
document.write() is not
really a function. There are a lot of examples in IE of native API
values. For example if you pass too many arguments to a DOM API method
silently ignore extra arguments. If you look at the value of
document.write the result is not
"function". What is particularly
problematic in this case is that
document.write does not implement
Fortunately I found that the Function prototype does implement both
apply and furthermore you can borrow those methods to use
on function-like values like
themselves real function values - so
apply both implement
In the workaround above I applied
document.write by taking
Function.prototype.apply value and using its
call method. So
is equivalent to this one,
Except that the first version works in IE7.
If you find this difficult to follow, you are not alone.
We have had this workaround in our code for a couple of years now. So far it is working nicely.