Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Very strange corner-case behavior in Internet Explorer 8 on BestBuy's website

I found a bug on bestbuy.com in IE8 and I cannot seem to understand why it occurs. It also occurs in IE8 on sites such as comcast.com and raymourflanigan.com, but not on google.com or godaddy.com.

The following code throws a "Invalid procedure call or argument" error (specifically the last line is what throws the error):

var p = document.createElement("p");
var holder = Element.prototype.appendChild;
holder.apply(document.body, [p]);

This is very strange because I've tried it in other websites in IE8 and it works like a charm. I tried using .call instead of .apply, and even storing a reference to the original appendChild method to another variable on the Element prototype, but both of these attempts threw the same error.

What is causing this?

like image 826
Justin Meltzer Avatar asked May 02 '13 02:05

Justin Meltzer


1 Answers

edit

"What kind of code could possibly cause this error?"

It would seem that the error is related to the document.body not being available as a result of the page being in strict mode. The mode is entered at bestbuy as a result of the directive:

<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">

With regards to internet explorer, the option chrome=1 creates a Google Content Frame (GCF) will force the page to operate in strict mode. comcast.com is in strict mode as a result of its doctype header using XHTML.

There are various ways to enter document modes in IE

The net result of the page being in strict mode is that the rendering surface becomes available at document.documentElement. This code will append text and a paragraph at the bottom of the viewing area:

var p = document.createElement("p");
p.innerHTML = "APPEND";
var holder = Element.prototype.appendChild;
holder.apply(document.documentElement, [p]);

I made this fiddle in order to test this behavior: http://jsfiddle.net/LAkQk/

I first decided to test this behavior in multiple browsers.

Runs without error in chrome, firefox, safari, and IE8.

Note that to test this fiddle (or any really) on ie8 you must use /embedded and then click "result".

So lets just start off with the acknowledgement that there is something on those sites which is causing the conflict.


I was able to repeat the error using IE8 on bestbuy.com, and to confirm that it did work at google.com

However, this is not an issue with apply or appendChild per say. It is specifically an issue with passing the document.body. You may test this yourself with this code at bestbuy.com:

(function(){
 var p = document.createElement("p");
 p.innerHTML = "APPEND";
 var holder = Element.prototype.appendChild;
 var d = document.getElementById("header");
 holder.apply(d, [p]);
})()

Perhaps it is because of something attached to the body as a result of one of their plugins. Amusingly, this works from the ie console at bestbuy.com

$("body").append('<p>Append!</p>');

I looked through a number of the plugins and cannot find the exact line of code which is causing the overload or conflict, but it must be there, more than likely as a result of sniffing the user agent.

like image 199
Travis J Avatar answered Sep 30 '22 23:09

Travis J