Woes of Safari's Javascript with document.write - javascript

My problem only happens on Safari. IE, FF, Chrome and Opera all work flawlessly. I am adding an object to the DOM (exactly the same way YouTube does it, depending on ActiveX or NPAPI) so after I determine the write object type I add it to the DOM via :
document.write(MyObject)
At the head section of the page, so that js functions called from body can access it. It works on everything except Safari. The only way I can let Safari work is by adding an alert after document.write! I even tried setTimeout, but it works one time and fails 10.

Have you considered using document.body.appendChild(MyObject)?

Document.write doesn't work correctly in the body itself, and document.body.appendChild to add an object tag doesn't work.
So what I did was
var objectContainer = createElement("div");
objectContainer.innerHTML = "<object blah blah> <\/object>"; //<--notice the escaping of /
document.body.appendChild(objectContainer);
And now it works everywhere.

Related

IE9 window object inside an Iframe has no addEventListener

I'm adding an Iframe to a page by using javascripts document.write. The page (from another domain) that is called inside the Iframe does a bit of setup using
window.addEventListener('load', function() {
//do stuff here
}
It works in Chrome. It works in Firefox. It works in Opera.
It doesn't work in IE9. I get the strangest message, that "the Object does not have the property or method 'addEventListener'". It's apparently the window object IE9 is talking about, because when I
console.log(window)
i get
[object Window]
but when I
console.log(window.addEventListener)
I get
undefined
When I call the page directly the script works fine, but in the Iframe I get this magical castrated window object that does not know addEventListener (and probably other stuff too)?! What the hell is happening here?
After much trial and error I found out that the page that was creating my Iframe had broken HTML (no Doctype, no title tag) and thus forced IE9 into Quirks mode, which apparently means reduced abilities. After cleaning up the loading page it works fine.

jQuery misbehaving in Safari

I'm having a problem where certain bit of code is working perfectly across all browsers until I come to Safari where it's giving me issues. I inherited this code, and I'm not a jQuery expert so needless to say I'm a bit baffled:
var xt_begin=$('#begin')[0];
xt_begin.currentTime = 0;
xt_begin.play();
"#begin" is an audio element that was set in the HTML that's using this code and the .play() function is in a jQuery plugin that's being used (Link to plugin).
In all browsers except for Safari, play is being defined as if xt_begin were an object of that timer class. In safari, however, it remains undefined and the code stops working. I have no idea how this happens or how to fix it. I can post more code if need be, any help would be appreciated.
**Update
Upon further investigation it turns out it is a DOM element, and I'm a bit thick. However, Safari seems to have a problem recognizing audio elements for some reason. It's identifying it as an "object HTMLelement" whereas Firefox shows it as "object HTMLAudioElement". I'm still stumped on this one.
**SOLVED
Apparently Safari needs quicktime installed on your desktop for it to use audio elements. That's gonna make this app I'm fixing completely useless, but at least I know now. Thanks for the help folks.
Really just a comment. The statement:
var xt_begin = $('#begin')[0];
is effectively the same as:
var xt_begin = document.getElementById('begin');
so xt_begin is either a DOM element or undefined (jQuery) or null (plain JS). Which is it?
In any case, you should probably follow with:
if (xt_begin) {
/* do stuff with xt_begin */
}
to avoid errors.
Try:
var xt_begin = document.getElementById('begin');
Instead of the jQuery line. That works across all browsers and will at least tell you if you have a jQuery problem or a Safari/web page problem.

document.open / document.write not properly clearing the document in chrome -- is this a bug in chrome?

I am writing to an iframe via document.write then trying to overwrite the document on that same iframe. In FF this works properly. However, in chrome code from the initial document.write persists even after I overwrite it with a second document.write.
See this fiddle: http://jsfiddle.net/meQcC/
If you view it in FF as one would expect, the iframe is blank and you actually get a "function onLoad is not defined error" because in the line
doc.write("<html><head><script>;" +
"<\/script></head><body onload='onLoad()'></body></html>");
There is obviously no onLoad function defined. However, if you view the same fiddle in chrome, the iframe will display a black rectangle, and there will be no error regarding the onLoad call, it will call the previously defined function as though it still exists!!!!
Is there any way to clear the document in chrome so that I can overwrite the contents of the iframe without old code somehow persisting? Is this a bug in chrome?
Yes, this is a bug in Chrome (or more precisely in WebKit). Per spec, it should be creating a new Window object and removing all global event listeners, and it's not doing that.
In particular, see http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-open step 14.
Deleting a <script> does not undefine any functions it defined.
If you want to achieve that you need to keep a list of all globals you create and delete them using delete window.WHATEVER;

In IE, when binding to the 'load' event of an IFRAME, this.contentDocument is undefined

Ok, bear with me folks, the setup on this one is long.
I have a simple page. It loads an iframe. Inside that iframe is a form. I want the form inside the iframe to interact with the parent page via jQuery.
This works correctly in Firefox, Chrome, and Safari. See for yourself here:
http://dl.dropbox.com/u/58785/iframe-example/index.htm
However, in Internet Explorer 6/7/8/9, it does not work. The load event fires, but jQuery cannot get a handle on elements inside the iframe.
I'm using the second 'context' argument of the jQuery function to set the context of the selector, like this: var form = $('#myform'), this.contentDocument)
Here's what is batty. Using the F12 Developer Tools in IE9, I can set a breakpoint in my JavaScript and look at how IE is evaluating the JavaScript. If I hover over this, I can see that it does have a contentDocument property. BUT, if I hover over this.contentDocument, it tells me it's undefined.
Because it's undefined, the jQuery selector returns no elements. Again, this is only in IE. And the IFRAME is on the same domain, so it's not a same-origin issue.
Any pointers?
Not to trample on Roatin's answer, but this issue can also be fixed by specifying a DOCTYPE declaraction. Internet Explorer 8 and over require it for contentDocument. Otherwise, as he said, contentWindow can be used (for earlier versions of IE, too). See the information at W3Schools.

Calling a function in an iframe from a parent in firefox

I'm trying to call a function, test(), of an iframe from the parent document using the code
subframe.test();
subframe refers correctly to the iframe, alert(subframe) returns [object HTMLIFrameElement], and the function runs in both IE7 and opera (9.23), but not firefox (3.0), chrome (3.0) or safari (3.03 beta windows). I assume these browsers support the functionality, so wondering if perhaps I'm using an incorrect call which IE and Opera support anyway, which wouldn't surprise me.
Thought I should answer for posterity - I solved the problem using subframe.contentWindow.test() .
Is the domain of the parent document's source the same as that of the child iframe's? I believe FireFox requires that they are in order to do something like this.

Categories

Resources