最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is my jQuery function causing a 'Stack Overflow' error in IE 8?

programmeradmin0浏览0评论

I have a simple function which causes a Stack Overflow error in IE 8. The problem does not appear to occur in any other browser although I have not testing IE 7 or 6.

The exact error is as follow:-

 SCRIPT28: Out of stack space 
 jquery.min.js, line 2 character 7498
 SCRIPT2343: Stack overflow at line: 2 

The function in question:

function switchImage(size, objid, prefix, fullimage){

    if(size !== 'full'){
        var image = prefix + size + '/' + size +'_' + fullimage;
    }
    else {
        var image = prefix + size + '/' + fullimage;
    }

    $('#' + objid).data('type', size)
        .append('<img id="preload" src="' + image + '" style="display:none;" />')
            .find('#preload').load(function(){
                $('#' + objid).find('img').attr('src', image);
                $(this).remove();
            });
}

To give an overview of the use case I will explain the purpose of this function:

When a user resizes an image (using jqueryUI resize) the width/height is pared in another function.

Once the image grows to be of a certain size this function is then called which as you can see, appends a hidden <img> element to the DOM with the 'src' attribute of a higher resolution version of the image (or lower if the image is being downsized by the user.

Once it has been loaded the src attribute of the visible element is updated and the hidden element is removed.

This proved excellent dynamic switching of images as the user resizes them keeping the image quality good throughout the process....

I just can't seem to work out what is causing the problem in IE 8. With this function removed no errors occur, and although the error is present, the function still works as it should (although resize performance is poor anyway in IE 8).

Any help would be greatly appreciated.

UPDATE: I seem to have solved the original issue by rewriting the function to the following:-

function switchImage(size, objid, prefix, fullimage){

    var $el = $('#' + objid);

    if(size !== 'full'){
        var image = prefix + size + '/' + size +'_' + fullimage;
    }
    else {
        var image = prefix + size + '/' + fullimage;
    }

    $el.data('type', size);

    $('<img id="preload" src="' + image + '" style="display:none;" />')
        .appendTo($el)
            .one('load', function(){
                $('#' + objid).find('img').attr('src', image);
                    $(this).remove();
                });
}

As you can see, the only real difference is that I am using .appendTo() rather than .append() as well as using jQuery .one() method to ensure that the load event only occurs once. Though since the element is removed directly afterwards I don't understand why this should make any difference.

I really would be interested to see if anyone can shed any light on this so I can learn how to avoid such issues in the future. Cheers.

I have a simple function which causes a Stack Overflow error in IE 8. The problem does not appear to occur in any other browser although I have not testing IE 7 or 6.

The exact error is as follow:-

 SCRIPT28: Out of stack space 
 jquery.min.js, line 2 character 7498
 SCRIPT2343: Stack overflow at line: 2 

The function in question:

function switchImage(size, objid, prefix, fullimage){

    if(size !== 'full'){
        var image = prefix + size + '/' + size +'_' + fullimage;
    }
    else {
        var image = prefix + size + '/' + fullimage;
    }

    $('#' + objid).data('type', size)
        .append('<img id="preload" src="' + image + '" style="display:none;" />')
            .find('#preload').load(function(){
                $('#' + objid).find('img').attr('src', image);
                $(this).remove();
            });
}

To give an overview of the use case I will explain the purpose of this function:

When a user resizes an image (using jqueryUI resize) the width/height is pared in another function.

Once the image grows to be of a certain size this function is then called which as you can see, appends a hidden <img> element to the DOM with the 'src' attribute of a higher resolution version of the image (or lower if the image is being downsized by the user.

Once it has been loaded the src attribute of the visible element is updated and the hidden element is removed.

This proved excellent dynamic switching of images as the user resizes them keeping the image quality good throughout the process....

I just can't seem to work out what is causing the problem in IE 8. With this function removed no errors occur, and although the error is present, the function still works as it should (although resize performance is poor anyway in IE 8).

Any help would be greatly appreciated.

UPDATE: I seem to have solved the original issue by rewriting the function to the following:-

function switchImage(size, objid, prefix, fullimage){

    var $el = $('#' + objid);

    if(size !== 'full'){
        var image = prefix + size + '/' + size +'_' + fullimage;
    }
    else {
        var image = prefix + size + '/' + fullimage;
    }

    $el.data('type', size);

    $('<img id="preload" src="' + image + '" style="display:none;" />')
        .appendTo($el)
            .one('load', function(){
                $('#' + objid).find('img').attr('src', image);
                    $(this).remove();
                });
}

As you can see, the only real difference is that I am using .appendTo() rather than .append() as well as using jQuery .one() method to ensure that the load event only occurs once. Though since the element is removed directly afterwards I don't understand why this should make any difference.

I really would be interested to see if anyone can shed any light on this so I can learn how to avoid such issues in the future. Cheers.

Share Improve this question edited May 17, 2012 at 2:21 gordyr asked May 17, 2012 at 2:08 gordyrgordyr 6,29614 gold badges67 silver badges123 bronze badges 3
  • What happens when you use a non-minfied version of jQuery? At least that way you'll get a more meaningful reference for the error. – RobG Commented May 17, 2012 at 2:15
  • The same thing happens.... Believe it or not five minutes after posting the question... I have solved it. But I have no idea why... I will update my question, as I would really like to understand why this slight rewrite has made a difference. – gordyr Commented May 17, 2012 at 2:17
  • @gordyr Can you give us the code that calls the function switchImage() to give me some context? – dane fairbanks Commented Apr 12, 2013 at 23:54
Add a ment  | 

1 Answer 1

Reset to default 3

Your initial function would have run straight into an infinite loop if you didn't have $(this).remove(). Essentially what you were doing was setting the src attribute to all img tags, including the preload image itself. (replace $(this).remove() with console.log('loaded') and watch it loop infinitely in Firebug)

I would guess that in IE8, once the attribute is set to the preload image as well, it invoked your 'load' event handler first before executing the next line which is $(this).remove() (explaining the stack overflow), while other browsers might have first finished executing the entire function first, thus removing the preload image, which prevented the infinite loop. (This is just a guess)

A monkey patch to the initial version would be to use .find('img:not(#preload)') instead of just .find('img').

Your patch also prevents the infinite loop because .one() ensures it to only run once.

But ultimately I would refactor the function to the following:

function switchImage(size, objid, prefix, fullimage){

    var $el = $('#' + objid),
        $image = $el.find('img'),
        $preload = $('<img>');

    if(size !== 'full'){
        var image = prefix + size + '/' + size +'_' + fullimage;
    }
    else {
        var image = prefix + size + '/' + fullimage;
    }

    $el.data('type', size);

    $preload
        .on('load', function () {
            $image.attr('src', image);
        })
        .attr('src', image);
}

Also note that the preload image actually does not need to be explicitly appended to the DOM to serve your purpose.

发布评论

评论列表(0)

  1. 暂无评论