Chrome sometimes calls incorrect constructor

前端 未结 2 591
隐瞒了意图╮
隐瞒了意图╮ 2020-12-30 09:26

We have a web site that uses extensively jQuery and it works fine in Firefox and IE. However in Chrome, we are getting frequently (and semi-randomly) Uncaught TypeErro

相关标签:
2条回答
  • 2020-12-30 09:48

    The responses in Chromium bug tracker seem to confirm that this is a bug of Chrome browser.

    The workaround solution is to "fix" pushStack() function in jQuery:

    // Take an array of elements and push it onto the stack
    // (returning the new matched element set)
    pushStack: function( elems, name, selector ) {
       // Build a new jQuery matched element set
       var ret = this.constructor();
    
       // Workaround for Chrome bug
       if ((this instanceof jQuery.fn.init) && !(ret instanceof jQuery.fn.init)) {
           // console.log("applying pushStack fix");
           ret = new jQuery.fn.init();
       }
    
       // etc.
    }
    
    0 讨论(0)
  • 2020-12-30 10:01

    Here is an "unobtrusive" solution (for example, if you're pulling jQuery from a CDN). Save this in a .js file and include it after pulling in jQuery.

    (function ($) {
        var pushStackOrig, pushStackChrome;
    
        pushStackOrig = $.fn.pushStack;
    
        pushStackChrome = function ( elems, name, selector ) {
            // Build a new jQuery matched element set
    
            // Invoke the correct constructor directly when the bug manifests in Chrome.
            //var ret = this.constructor();
            var ret = new jQuery.fn.init(); 
    
            if ( jQuery.isArray( elems ) ) {
                push.apply( ret, elems );
    
            } else {
                jQuery.merge( ret, elems );
            }
    
            // Add the old object onto the stack (as a reference)
            ret.prevObject = this;
    
            ret.context = this.context;
    
            if ( name === "find" ) {
                ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
            } else if ( name ) {
                ret.selector = this.selector + "." + name + "(" + selector + ")";
            }
    
            // Return the newly-formed element set
            return ret;
        };
    
        $.fn.pushStack = function (elems, name, selector) {
            var ret;
    
            try {
                ret = pushStackOrig.call(this, elems, name, selector);
                return ret;
            } 
            catch (e) {
                if (e instanceof TypeError) {
                    if (!(ret instanceof jQuery.fn.init)) {
                        ret = pushStackChrome.call(this, elems, name, selector);
                        return ret;
                    }
                }
    
                throw e;
            }
        };
    
    }).call(this, jQuery);
    
    0 讨论(0)
提交回复
热议问题