【问题标题】:JQuery animate slower every call每次调用 JQuery 动画都会变慢
【发布时间】:2023-03-24 04:31:01
【问题描述】:

我有一个用 Jquery 打开的模态框。当关闭按钮被调用时,模态框被关闭。一切正常,但是我打开和关闭模态框的次数越多,模态框关闭所需的时间就越长:

window.closeModal = function () {
    modal = $("div.modal-overlay");
    windowHeight = $(window).height();
    // Until here performance is good
    modal.animate({top: windowHeight, }, 800, function () {
        // This is the problem 
        modal.hide();
        $("body").css("overflow-y", "scroll");
    });
}

我在每一行都放置了控制台日志,一切都会立即执行,直到我点击 modal.animate 函数。每次我打开一个模态框并按下关闭按钮时,modal.animate 开始执行需要更多时间。

谁能给点启示。

@编辑: 我创建了一个显示问题的 jsfiddle。

只需按下打开模式,然后关闭模式。这样做 4-5 次可以看到延迟变大

http://jsfiddle.net/CZ54C/

@@EDIT:发生了一些非常奇怪的事情。

虽然 openModal 执行了一次,但 iframe.load 执行了 # 次模态打开和关闭...

window.openModal = function (url) {
    console.log("open start");
    modal = $("div.modal-overlay");
    modalIframe = $("div.modal-overlay iframe");
    windowHeight = $(window).height();
    modal.css("bottom", "0");
    modalIframe.attr("src", url + "?frame=true");
    modalIframe.load(function () {
        console.log("open load")
        modalIframe.css('height', windowHeight);
        modal.show().animate({
            top: 0,
        }, 800, function () {
            $("body").css("overflow-y", "hidden");
        });
    });
}

【问题讨论】:

  • 尝试减少持续时间(800到400)以更快地完成动画..
  • 大声笑@web2008 - 每次他这样做都需要更长的时间。这不仅太慢了!!
  • @Archer,没错。并不是动画被堆叠,因为动画在新的触发后很久就完成了。
  • 能否在 jsfiddle 或 jsbin 中重现该问题?
  • 你在开始另一个动画之前尝试过停止动画吗? api.jquery.com/stop

标签: jquery performance jquery-animate


【解决方案1】:

我想我解决了这个问题,

似乎通过更改 iframe url,“加载处理程序再次附加”。所以每次“加载执行”时,它都会被附加。我用这个代码解决了它:

 modalIframe.one('load',function () {});

//Instad of
 modalIframe.load(function () {});

这是好的做法吗?

【讨论】:

  • 这对您不起作用,因为one 函数将在调用一次后删除处理程序。这意味着在您第一次单击“打开模式”链接后将不会调用处理程序。请参阅我的答案以获得更好的解决方案。
  • 似乎对我不起作用;尝试在此示例中使用one 打开、关闭然后再次打开模式:jsfiddle.net/CZ54C/3
【解决方案2】:

问题是您每次打开模式对话框时都将一个新的load 处理程序附加到modalIframe。因此,如果您第二次单击“打开模式”,则加载回调将执行两次。下次点击会执行3次,以此类推。

解决此问题的最佳方法是将 openModal 函数之外的加载事件处理程序移动到附加点击处理程序的同一块中:

Working Demo

$(function () {
    var modal = $("div.modal-overlay"),
        modalIframe = modal.find('iframe');

    $("a.open").click(function (e) {
        e.preventDefault();
        var href = $(this).attr("href");
        openModal(href);
    });

    $("a.close").click(function (e) {
        e.preventDefault();
        closeModal();
    });

    //put load handler here
    modalIframe.load(function () {
        var windowHeight = $(window).height();

        modalIframe.css('height', windowHeight);
        modal.show().animate({
            top: 0,
        }, 800, function () {
            $("body").css("overflow-y", "hidden");
        });
    });
});

window.openModal = function (url) {
    $("div.modal-overlay iframe").attr("src", url + "?frame=true");
}

window.closeModal = function () {
    modal = $("div.modal-overlay");
    windowHeight = $(window).height();
    modal.animate({
        top: windowHeight,
    }, 800, function () {
        modal.hide();
        $("body").css("overflow-y", "scroll");
    });
}

【讨论】:

  • 问题是在我的代码中,加载处理程序已经在页面加载时执行。因此,无需单击链接,即可打开模式。
  • 你是通过打电话给openModal来做的吗?如果是这样,只要您在附加 load 处理程序之后调用它(即,在您的 jQuery 就绪回调中),它就不会产生影响
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多