【问题标题】:jQuery event won't work after ajax callajax调用后jQuery事件将不起作用
【发布时间】:2015-12-16 18:06:41
【问题描述】:

我有一个展开/折叠块,我为此编写了一个函数:

function expandCollapse() {
    var $btnShowHide = $('.btn-show-hide');
    var $contentShowHide = $('.content-show-hide');

    contentToggle();

    $btnShowHide.each(function() {
        $(this).on('click', function() {
            var i = $btnShowHide.index(this);
            $contentShowHide.eq(i).slideToggle('fast');
            $contentShowHide.eq(i).toggleClass('collapsed');

            if ($contentShowHide.eq(i).hasClass('collapsed')) {
                $('.icon-show-hide', this).text('+');
            } else {
                $('.icon-show-hide', this).text('-');
            }
        });
    });

    function contentToggle() {
        $contentShowHide.each(function() {
            var i = $contentShowHide.index(this);
            if ($(this).hasClass('collapsed')) {
                $(this).hide();
                $('.icon-show-hide', $btnShowHide.eq(i)).text('+');
            } else {
                $('.icon-show-hide', $btnShowHide.eq(i)).text('-');
            }
        });
    }
}

我在$(document).ready 上调用此函数。这可以正常工作,但是当页面中执行 ajax 调用时会失败。所以,我查看了这个answer 并在ajax 成功时再次调用了该函数,但这使得行为很奇怪(例如,单击btn 一次将折叠并多次展开内容以单击一次)。关于如何解决这个问题的任何想法?

示例 HTML(一页上可能有多个):

<h3 class="btn-show-hide">
 <span class="icon-show-hide"></span>
 <span>Title</span>
</h3>
<div class="content-show-hide collapsed">
//Stuff
</div>

【问题讨论】:

  • 您何时以及如何调用 expandCollapse()?你也可以发布 HTML 吗?)
  • @AdamJeffers on document.ready 和 ajax 成功。
  • 查看我的回答,每次调用 expandCollapse 时,您都会一遍又一遍地将同一个事件处理程序重新绑定到所有按钮。如果你真的不想改变你的代码结构,你可以事先打电话给off()....
  • 是否有理由将事件处理程序绑定在一个循环中?这被认为是不好的形式。考虑使用@Jasen 的使用委托的建议。
  • 是的,您可以绑定到正文,但最好找到最近的静态父项。

标签: jquery ajax


【解决方案1】:

显然解决方案是在收听事件之前设置off。 所以,它只是

 $btnShowHide.each(function() {
        $(this).off('click').on('click', function() {
            var i = $btnShowHide.index(this);
            $contentShowHide.eq(i).slideToggle('fast');
            $contentShowHide.eq(i).toggleClass('collapsed');

            if ($contentShowHide.eq(i).hasClass('collapsed')) {
                $('.icon-show-hide', this).text('+');
            } else {
                $('.icon-show-hide', this).text('-');
            }
        });
    });

这解决了我的问题,但我不知道为什么会这样。

【讨论】:

    【解决方案2】:

    除非您在每次调用 expandCollapse() 之前删除/替换 $('.btn-show-hide');$('.content-show-hide'); 的所有实例,否则您将一遍又一遍地重新添加相同的事件处理程序,我怀疑这是多次崩溃的原因/展开。

    $btnShowHide.each(function() {
            $(this).on('click', function() {
                var i = $btnShowHide.index(this);
                $contentShowHide.eq(i).slideToggle('fast');
                $contentShowHide.eq(i).toggleClass('collapsed');
    
                if ($contentShowHide.eq(i).hasClass('collapsed')) {
                    $('.icon-show-hide', this).text('+');
                } else {
                    $('.icon-show-hide', this).text('-');
                }
            });
        });
    

    上面的代码每次调用expandCollapse()都会增加一个新的事件处理函数,或许应该放在这个函数之外,只执行一次……

    【讨论】:

    • 我刚试过这个。我将您突出显示的代码移至 document.ready 并调用 contentToggle();在 ajaxSuccess() 和 document.ready 中。点击事件不再起作用。
    • @A.O.您的答案/示例代码与 OP 已有的完全相同?
    • 您是否也将您的引用移至$btnShowHide$contentShowHide? @AdamJeffers 代码 sn-p 是相同的,我是说它应该移到 expandCollapse() 函数之外,这样他就不会在每次调用 expandCollapse() 时重新绑定他的点击事件处理程序。
    • @A.O.我相信 AdamJeffers 对代码的以下重组就是您所指的。我试了一下,点击事件又失败了。
    猜你喜欢
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 2011-03-13
    • 2012-12-14
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多