firefox 20.0 jquery find() error
Hi, I update last day ff19 -> 20.
This jquery code
$('#id').find('.image');
in 19 works well, now this get errot
TypeError: can't convert undefined to object array = Array.prototype.slice.call( array, 0 );
I try to update my jquery from 1.7.2 to 1.9.1, but same error.
I try chrome and ie9 all works good.
Then i try to use $('#id').find('div.image'); //div added
and it's come back to works. :)
Do you think it's a bug or what else?
Chosen solution
So after filing a bug report with Mozilla, they discovered that it was due to a specific incompatability with the prototype-deprecation script. There's a block of code which essentially unsets the element.getElementsByClassName reference in firefox specifically. Fixing the bug in firefox is unfortunately not possible, they'd have to unset a major fix to getElementsByClassName or change their UA string.
So.
If you are using the prototype-deprecation library, remove the following lines to solve the problem until you can cut the file out completely:
{ methodName: 'getElementsByClassName', namespace: Element.Methods, message: 'Element#getElementsByClassName has been deprecated, please use Element#select instead.' },Read this answer in context 👍 6
All Replies (17)
A good place to ask advice about web development is at the MozillaZine "Web Development/Standards Evangelism" forum.
The helpers at that forum are more knowledgeable about web development issues.
You need to register at the MozillaZine forum site in order to post at that forum.
Thx, i write there! :)
I'm running into the same problem with 3 computers once the 20.0 update happened I can't access different web sites because of java errors..
Mozilla you need to fix this..
Hi there! I have faced this problem yesterday too, and here is me solution: on jquery-1.9.1.js, you should replace the line 3947
push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
with
push.apply( results, slice.call(context.querySelectorAll( m ), 0) );
After this, the bug disappeared. Please note, i'm not sure about this solution, it can probably affect some other functions, or selector speed. Use it on your own risk. Good luck :)
Modified
Hi pivodirtjumper, are you sure that m is in the correct format for that change? In getElementsByClassName you simply have the class name, while in querySelectorAll you preface the class name with a dot. I would think you would need to account for that somewhere.
Yes, sorry, i forgot to paste the line where m is re-defined. So the correct version should be:
push.apply( results, slice.call(context.querySelectorAll( '.' + m ), 0) );
Thanks.
Our E-Commerce site has just stopped working in Firefox due to this bug. This is a pretty major issue. We applied the fix that pivodirtjumper suggested on our test server and it patched the issue, however our production server is using googles CDN which we can't make the change to.
This is a pretty SERIOUS issue mozilla... very surprising and incredibly disappointing that 'getElementsByClassName' is broken in firefox 20
Hi schenn, is there any way to provide a minimal test case demonstrating how the library fails? It would be helpful to understand where the failure is occurring.
If I open the web console on this page and test the two methods against each other with a sample class name, there isn't a problem, so we need a better model.
document.getElementsByClassName("main-content").length == document.querySelectorAll(".main-content").length;
Not anymore, we implemented that fix for our live site and it solved the problem, however, I'll dump the old code into this box and you can try and figure it out??
This fails at "this.table.find('.clear_selected_product')" AND qty.parents('tr').find('.line_total').text('$0.00');. According to firebug, this.table and qty.parents('tr') are returning the correct elements.
Typing those lines into the console at the appropriate breakpoint also throws the above error. This error does not fire in FF19, Chrome, Safari, IE or Opera.
After making the change stipulated by pivodirtjumper, changing push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); to push.apply( results, slice.call(context.querySelectorAll( '.' + m ), 0) ); in the jQuery 1.8.3 file (Sizzle function - line 3930) , the errors stop and functionality is restored in FF 20.0.1.
Should point out that selecting elements by ID or tag or attribute do still work, it's only selecting by classes which is throwing the error.
this.table = jQuery("#selected_products").find('#_selected_products').children('table');
this.table.find('.clear_selected_product').on({click:function(){ var that = jQuery(this); var qty_selector = '.qty_'+that.parents('tr').data('product'); jQuery(qty_selector).each(function(){ var qty = jQuery(this); qty.val(); qty.parents('tr').find('.line_total').text('$0.00'); }); jQuery("#selected_products").find("#_selected_products").children('table').data('form').removeItem(that.parents('tr').data('product')); }});
Modified
Note: Just typing
this.table.find('.clear_product_info') or qty.parents('tr').find('.line_total') by themselves in the console at the appropriate breakpoint also fires the error.
More notes in case it helps:
table is an html table element
'this' is a js object
What kinds of elements are .clear_product_info and .line_total?
<a class="clear_selected_product">X</a>
line_total is a span
Modified
If I try to use .find() in a similar way on a few elements in a very basic document, I can't replicate the errors: http://www.jeffersonscher.com/forumshots/jQuery/jquery-find-3.html
Someone more sophisticated than me will need to develop the test case.
I'll convert the problem page to a test case later today.
Further investigation reveals that the issue is a conflict between jquery and prototype version 1.6.0.3 and the deprecation library 1.6.0.2. These last two libraries are embedded in our CMS.
By stepping through the Sizzle function, when it gets to the context.getElementsByClassName(m), the result is undefined instead of a populated html object.
This issue is only present on FF 20.0.1, it does not appear in FF < 20. It does not fire in the latest version of Chrome or Opera or IE 7,8,9 or 10.
This throws the error.
<html lang="en"> <head> <title><!-- Insert your title here --></title> <script src ="jquery-1.8.3.js" type="text/javascript"></script> <script>$.noConflict();</script> <script type="text/javascript" src="prototype-1.6.0.3.js"></script> <script type="text/javascript" src="prototype-deprecation-1.6.0.2.js"></script> <script> jQuery(document).ready(function(){ jQuery("#test").find(".test").text("success"); }); </script> </head> <body> <div id="test"> <div class="test"></div> </div> </body> </html>
Modified
Chosen Solution
So after filing a bug report with Mozilla, they discovered that it was due to a specific incompatability with the prototype-deprecation script. There's a block of code which essentially unsets the element.getElementsByClassName reference in firefox specifically. Fixing the bug in firefox is unfortunately not possible, they'd have to unset a major fix to getElementsByClassName or change their UA string.
So.
If you are using the prototype-deprecation library, remove the following lines to solve the problem until you can cut the file out completely:
{ methodName: 'getElementsByClassName', namespace: Element.Methods, message: 'Element#getElementsByClassName has been deprecated, please use Element#select instead.' },