Name is required.
Email address is required.
Invalid email address
Answer is required.
Exceeding max length of 5KB

Firefox throws javascript error when setting listeners after Ajax replacement


If you use Ajax to replace the 5.3.1356 player.swf in a webpage, Firefox will not reattach the listeners (onPlay, onPause, onComplete, etc). It works fine if you don't use Ajax. Chrome, Safari, and IE8 all work fine in both cases.

When you do an ajax replacement of the player and then call jwplayer().setup, Firefox throws the following javascript error in Firebug:

Error: o.jwAddEventListener is not a function
Source File: http://buladean.com/jw53/eventtest/jwplayer.js
Line: 1

I've created a test page at
http://buladean.com/jw53/eventtest/

When the test page starts, it is non-ajax, and works fine in all browsers. If you click either of the buttons above, it will ajax replace the player. All browsers handle this fine except Firefox, which throws the error above.

Bob

8 Community Answers

JW Player

User  
0 rated :

Any ideas on this? This exact problem is preventing me from purchasing right now. I have to know that the listeners will reattach in all major browsers.

JW Player

User  
0 rated :

Yo I just found a 'solution':

If you put the 'autostart' at the END of your setup call, the "o.jwAddEventListener" Firefox error goes away.

Like so:
jwplayer("vid_plyr").setup({
flashplayer: "player.swf",
file: "video1.mp4",
height: 240,
width: 320,
events: {
onComplete: function(event) { olayHide(); }
},
autostart: true
});

If the autostart: comes before the events:, Firefox throws the error.

Enjoy!

JW Player

User  
0 rated :

OK, I just lied. I didn't get the error on the first time after the page loaded, but each subsequent call to setup threw the error.

However, a workaround is to call the player when the page first loads, then hide/show the player's container.

Good luck.

JW Player

User  
0 rated :

@danbob Thanks for looking at the problem. Unfortunately, keeping the container available (even if invisible) isn't an option for us. The video container is only one part of a larger context that needs to be updated.

I suspect this is a timing issue in the swf itself.

Any other ideas?

Pablo

JW Player Support Agent  
0 rated :

@Bob -

There does appear to be a bug, where the remove() function doesn’t properly work in Firefox. This is due to the lack of the “outerHTML” getter/setter in Firefox. I’ve created a ticket to resolve the issue:

http://developer.longtailvideo.com/trac/ticket/1094

In the meantime, you may be able to create a quick workaround by generating an outerHTML getter and setter. There’s an article here which describes how this might work:

http://snipplr.com/view/5460/outerhtml-in-firefox/

JW Player

User  
0 rated :

@PabloS

Brilliant! You were 100% on target there. Doing some DOM manipulation with Javascript to create a get/setOuterHTML for Firefox fixed the problem.

For anyone else having this problem, I also found the scripts on this page:

http://webfx.eae.net/dhtml/ieemu/htmlmodel.html

to be helpful in creating an outerHTML for Firefox. Just add the outerHTML getter/setter prototype functions to your jquery $(document).ready function, and it should work.

Basically, I have this (just to help anyone else that is having this problem):
$(document).ready(function() {
makeOuterHtml();
}

function makeOuterHtml() {
if(typeof(HTMLElement) != 'undefined') { // prevents IE from seeing the rest
HTMLElement.prototype.__defineGetter__("outerHTML", function () {
var attrs = this.attributes;
var str = "<" + this.tagName;
for (var i = 0; i < attrs.length; i++)
str += " " + attrs[i].name + "=\"" + attrs[i].value + "\"";

if (_emptyTags[this.tagName])
return str + ">";

return str + ">" + this.innerHTML + "</" + this.tagName + ">";
});
HTMLElement.prototype.__defineSetter__("outerHTML", function (sHTML) {
var r = this.ownerDocument.createRange();
r.setStartBefore(this);
var df = r.createContextualFragment(sHTML);
this.parentNode.replaceChild(df, this);
});
}
}

This also fixed the remove() issue.

Bob

JW Player

User  
-1 rated :

Forgot a piece of the solution. You'll also need :

var _emptyTags = {
"IMG": true,
"BR": true,
"INPUT": true,
"META": true,
"LINK": true,
"PARAM": true,
"HR": true
};

somewhere in a <script> tag.

Bob

JW Player

User  
-1 rated :

Genius solution Bob! my thanks for it!

thought:
jwplayer("container").onReady(function() {
makeOuterHtml();
});

can be used too, and if u use Bob's function, close it with a ");"

$(document).ready(function() {
makeOuterHtml();
}); <------

Cheers!
Jeffrey

This question has received the maximum number of answers.