views:

4966

answers:

6

I know very little about JavaScript but despite this I'm trying to cobble something together on my wordpress blog. It's not working, and I don't know how to resolve it, and hey, that's what StackOverflow is for, right?

Firstly, the error message is:

Error: element.dispatchEvent is not a function
Source File: http://.../wp-includes/js/prototype.js?ver=1.6
Line: 3936

It happens on page load. My page load handler is registered thusly:

Event.observe(window, 'load', show_dates_as_local_time);

The error goes away if I disable some other plugins, and this (plus googling) led me to conclude that it was a conflict between prototype and jQuery (which is used by some of the other plugins).

Secondly I'm following the wordpress recommended practice of using wp_enqeue_script to add a dependency from my JavaScript to the Prototype library, as follows:

add_action( 'wp_print_scripts', 'depo_theme_add_javascript' );

function depo_theme_add_javascript() {
    wp_enqueue_script('friendly_dates', 'javascript/friendly_dates.js', array('prototype'));
}

Now I'm also aware that there are some potential conflicts between jQuery and Prototype which are resolved using the jQuery noConflicts method. I've tried calling that from various places but no good. I don't think this is the problem because a) the noConflict function relates solely to the $ variable, which doesn't seem to be the problem here, and b) I would expect wordpress to sort it out for me because it can...

Lastly, using the Venkman debugger I've determined that the element referenced in the error message is indeed an HTMLDocument but also does lack a dispatchEvent. Not sure how this could happen, given it's a standard DOM method?

+6  A: 

There is a nasty trick many libraries do that I've taken a distinct liking to, and it looks like prototype is one of these.

Mootools does this, If I am right, and it involves overloading many of the prototypes on the basic classes, monkey patching them.

And likewise, I similarly encountered strange behaviour when mootools and jQuery were present, usually jQuery dying because it was calling some object method which had been somehow overloaded/monkey patched by Mootools.

Also, mysteriously, taking mootools out of the script usage list, resulted in everything running much faster, which I concluded was due to less object pollution.

Now I could be wrong, but I concluded from my experience such libraries just simply don't like to co-exist with each other, and seeing how mootools code seemed to me to degrade speed at which normal things were done, I sucked up and ported all mootools based code to jQuery ( A time consuming deal I assure you ), and the result, was code that was fast and didn't have weird errors that were unexplainable.

I recommend you consider migration as at least One of your options.

One More thing, when writing:

I tend to use this syntax with all my jQuery driven code, for a bit of safe encapsulation in the event somebody breaks '$' somehow.

Runtime Code This waits for document.ready before executing:

 jQuery(function($){ 
      code_with_$_here; 
 });

jQuery Plugins

(function($){ 
    code_with_$_here; 
})(jQuery);

Using these will make it easier for people using any jQuery you happen to write to be able to use it without much of a conflict issue.

This will basically leave them to make sure their code isn't doing anything really magical.

Kent Fredric
Thanks, yes that's looking more and more likely. Of course jQuery is somewhat intimidating for someone like me who knows nothing about JavaScript... But it's probably easier than resolving this particular problem!
Alastair
+5  A: 

Its worth reading this article on the JQuery site about Using JQuery With Other Libraries. It deals with more than just the noConflict option.

Soviut
+2  A: 

I think you should search well because all jQuery plugins has a prototype version and all prototype plugins has a jQuery version. If you really don't find what you look and you can't use only one library, take a look here at

jQuery.noConflict();

But again, i think it make no sense to load over 15-20kb for each library :)

Ionut Staicu
A: 

Thanks for the suggestions all. In the end I think Kent's explanation was the closest, which basically amounted to "Prototype is broken". (Sorry if I'm summarizing you incorrectly :)

As for the jQuery.noConflict option - I already mentioned this in the question. It makes a difference when you run this method, and I have very little control over that. As I said, I have tried running it in a couple of different places (specifically the page header and also from my script file), to no effect. So, much as we'd all like it to be, "just use noConflict" is not an answer to this question, at least not without additional information.

Besides, jQuery.noConflict seems to be about the $ variable, and the code around the error point does not deal with that variable at all. Of course they could be related indirectly, I haven't tracked it down.

So basically I ended up rewriting the script using jQuery instead of Prototype, which actually had its own problems. Anyway I've published the whole war story on my blog, should you be interested.

Alastair
+1  A: 

Hi, i had the same problem, but noConflict was the solution in my case. I simply put the line

jQery.noConflict();

at the end of the jquery.js file, and changed all code that used jQuery with the $ function to the jQuery function. The part based on the prototype framework was left untouched. Then i loaded the jquery.js as the first JS-File in my base-template (this is a bit ugly, but since the file will be in the browser-cache after the first time, i think it is ok) and it worked.

Janosch
A: 

I had the exact issue as Alastair and Janosch's suggestion worked for me

Malachi