javascript - 是否有类似 Jquery 内存或缓存的东西?

标签 javascript jquery caching memory

我用 jQuery 编写了一个用于 360 度产品预览的脚本。它工作得很好。但如果我长时间“玩”它(拖动、放大、缩小等),它就会变得越来越慢。如果我缓慢地拖动鼠标,它工作正常,但它在快速鼠标移动时卡住。页面重新加载后,它再次正常工作几分钟,然后变慢。

什么会导致这种行为?是否有类似 jQuery 内存变满的东西?

根据请求,部分代码:

加载图片:

$.getJSON("load.php", {dir: 'images/'}, function(output) {
var imagelist = jQuery.makeArray(output.imagelist);
var zoomlist = jQuery.makeArray(output.zoomlist);
var cache = [];

function preload(arrayOfImages) {
    $(arrayOfImages).each(function(){
        var im = $("<img>").attr("src",this);
        cache.push(im);
        image.attr('src', this);
    });
}
preload(imagelist);

旋转部分

holder.mousedown(function(e){
    var enterPosition = e.pageX - this.offsetLeft;
    isDown = true;
    $(document).mousemove(function(e){
        if(isDown && !isZoom){
            var cursorPosition = e.pageX - contOffset.left;
            var xOffset = cursorPosition - enterPosition;
            var step = Math.round(contWidth/countFrames);
            var frameOffset = Math.round(xOffset/step);
            var cycles = Math.abs(Math.floor((frameOffset+startFrame)/countFrames));

            currentFrame = startFrame + frameOffset;
            if(currentFrame >= countFrames){
                currentFrame = currentFrame - countFrames*cycles;
            }       
            if(currentFrame < 0){
                currentFrame = countFrames*cycles + currentFrame;
            }

            image.attr('src', imagelist[currentFrame]);
            $('#info').html(currentFrame);      
            var corner = Math.floor(360/countFrames);                       
            var degrees = corner*currentFrame;                              
            var radians=degrees*Math.PI/180;
            var sine=Math.sin(radians);
            var cose=Math.cos(radians);
            var poinx = rotCenter+rotRadius*sine*-1;
            var poiny = rotCenter+rotRadius*cose
            $('#pointer').css('left',poinx);
            $('#pointer').css('top',poiny);
        };
    });
    $(document).mouseup(function(){
        isDown = false;
        startFrame = currentFrame;
    });
});

缩放部分

$('#zoom').click(function(e){
    var isZoom = true;

    var offset = holder.offset();
    var startXpos = e.pageX - offset.left;
    var startYpos = e.pageY - offset.top;
    var zoomImg = new Image();

    zoomImg.onload = function() {
        zoomHeight = zoomImg.height;
        zoomWidth = zoomImg.width;

        var leftOverflow = (zoomWidth - contWidth)/-2;
        var topOverflow = (zoomHeight - contHeight)/-2;

        image.attr('src', zoomlist[currentFrame]);
        image.css('left', leftOverflow);
        image.css('top', topOverflow);
        $('#round').fadeOut();
        $('#zoom').fadeOut();           
        holder.addClass('zoomout');
        holder.mousemove(function(e){
            if(isZoom){
                var currentXpos = e.pageX - offset.left;
                var currentYpos = e.pageY - offset.top;

                var xlimit = (zoomWidth-contWidth)*-1;
                var ylimit = (zoomHeight-contHeight)*-1;



                var xSpeedCoeff = Math.floor(zoomWidth/contWidth);
                var ySpeedCoeff = Math.floor(zoomHeight/contHeight);
                var moveLeft = startXpos - currentXpos;
                var moveTop = startYpos - currentYpos;
                var leftOffset = leftOverflow + moveLeft*xSpeedCoeff;
                var topOffset = topOverflow + moveTop*ySpeedCoeff;
                var hMoveLock = false;
                var vMoveLock = false;


                if(leftOffset >= 0){
                    hMoveLock = true;
                    startXpos = startXpos - leftOffset;
                } 
                if(leftOffset <= xlimit){
                    hMoveLock = true;
                    startXpos = startXpos - leftOffset + xlimit;    
                }

                if(topOffset >= 0){
                    vMoveLock = true;
                    startYpos = startYpos - topOffset;
                } 
                if(topOffset <= ylimit){
                    vMoveLock = true;
                    startYpos = startYpos - topOffset + ylimit; 
                }

                if(!hMoveLock) {
                    image.css('left', leftOffset);
                }
                if(!vMoveLock) {
                    image.css('top', topOffset);
                }

                holder.mousedown(function(){

                    image.attr('src', imagelist[currentFrame]);
                    image.css('left', 0);
                    image.css('top', 0);
                    $('#round').fadeIn();
                    $('#zoom').fadeIn();            
                    holder.removeClass('zoomout');
                    pan = false;
                    isZoom = false;
                });
            }
        });
    }
    zoomImg.src = zoomlist[currentFrame];
}); 

我知道,代码不清楚,现在就在这里,如果有任何建议,我将不胜感激。

最佳答案

发生这种情况的原因有很多,如果没有看到代码就不可能说 既然您已经发布了代码,请参阅下面的更新:

我想到了几种可能性:

  1. 是的,您可能分配了很多对象,然后要么不释放它们,要么垃圾收集器运行缓慢。

  2. 您可能会不经意地一遍又一遍地重新附加事件处理程序,因此事件(最终触发所有附加的处理程序)会因为附加的(冗余)处理程序的数量而变慢。


发布代码后

更新:

它是#2,这是有问题的代码(它可能不是唯一有问题的代码):

holder.mousedown(function(e){
    var enterPosition = e.pageX - this.offsetLeft;
    isDown = true;
    $(document).mousemove(function(e){
        // ...
    });
    $(document).mouseup(function(){
        // ...
    });
});

mousedown 事件在 holder 元素上触发时,您正在做的是添加一个新的mousemovemouseup 到文档的处理程序,在已经存在的任何处理程序之上。所以每次 mousedown 都会向链中引入一个新的处理程序。由于 mousemove 发生了很多,因此不断增加的处理程序链被称为很多

您应该只附加 mousemovemouseup 处理程序一次,而不是在每个 mousedown 上,或者您应该确保在 mouseup删除它们。 (后者将要求您不像目前那样使用匿名函数,因为您需要将相同函数引用传递给您[间接]传递给的unbind bind编辑:或者您可以使用 jQuery 的“命名空间”事件内容。)


FWIW,这应该让您开始使用一次附加版本:

(function() {   // Scoping function so isDown and enterPosition aren't globals
    var isDown = false,
        enterPosition;

    // I don't know where `holder` or `startFrame` come from, but presumably you do

    // Hook up mousedown on holder
    holder.mousedown(function(e){
        enterPosition = e.pageX - this.offsetLeft;
        isDown = true;
    });

    // Hook up mousemove on document (just once)
    $(document).mousemove(function(e){
        // Flag controls whether we do anything
        if(isDown && !isZoom){
            var cursorPosition = e.pageX - contOffset.left;
            var xOffset = cursorPosition - enterPosition;
            var step = Math.round(contWidth/countFrames);
            var frameOffset = Math.round(xOffset/step);
            var cycles = Math.abs(Math.floor((frameOffset+startFrame)/countFrames));

            currentFrame = startFrame + frameOffset;
            if(currentFrame >= countFrames){
                currentFrame = currentFrame - countFrames*cycles;
            }       
            if(currentFrame < 0){
                currentFrame = countFrames*cycles + currentFrame;
            }

            image.attr('src', imagelist[currentFrame]);
            $('#info').html(currentFrame);      
            var corner = Math.floor(360/countFrames);                       
            var degrees = corner*currentFrame;                              
            var radians=degrees*Math.PI/180;
            var sine=Math.sin(radians);
            var cose=Math.cos(radians);
            var poinx = rotCenter+rotRadius*sine*-1;
            var poiny = rotCenter+rotRadius*cose
            $('#pointer').css('left',poinx);
            $('#pointer').css('top',poiny);
        };
    });

    // Hook mouseup on document (just once)
    $(document).mouseup(function(){
        isDown = false;
        startFrame = currentFrame;
    });
})();

如果您的代码已经在作用域函数中,则不需要我介绍的新代码。

关于javascript - 是否有类似 Jquery 内存或缓存的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9377088/

相关文章:

c# - 缓存在特定时间过期

javascript - jQuery preventDefault 函数不适用于 jsfiddle

javascript - Puppeteer(评估失败 : syntaxerror: invalid or unexpcted token)

javascript - 突出显示文本后打开下拉菜单

jquery - CSS中的旋转动画

java - 如何在黑莓浏览器字段中缓存

javascript - 'typing' 变量(与接口(interface))和 'modelling'(对于 Typescript Angular 2 项目)中类的使用

javascript - 真正基本的 javascript 函数概念

javascript - 在 JSLint 中,为什么这个 block 是空的?

caching - 为什么 skiplist 内存局部性差但平衡树好?