重构后JQuery函数无法正常工作

时间:2017-02-24 18:08:52

标签: jquery

我是JQuery的新手(更多C#)并且无法在这里看到我做错了什么。

我有以下JQuery切换汉堡菜单,并且还会产生调光效果并阻止滚动到Body。汉堡包也从3条水平线到X形动画。在第一个JQuery(下面)中,这很好用。但是我一直在努力改进这个并将我的代码清理到下面的第二个JQuery,这对我来说看起来更清晰(考虑到未来的功能)。然而,当我这样做时,除了汉堡包之外,一切仍然按照预期运行,不再为X设置动画。我真的不明白为什么因为没有真正可辨别的区别,无论如何我的新手JQuery眼睛。

另外作为一个新手,我也很想知道在这样的函数中是否需要以下两行代码:

e.preventDefault();

event.stopPropagation();

JQuery(Works):

jQuery(document).ready(function () {
    jQuery('#toggle-nav').click(function (e) {
            event.stopPropagation();
            jQuery(this).toggleClass('active');
            jQuery('.menu ul').toggleClass('active');
            jQuery('.hamburger ul').toggleClass('active');
            jQuery('.dimmer').toggleClass('active');
            jQuery('body').toggleClass('no-scrolling');

            e.preventDefault();            
    });
});

JQuery(没有工作):

jQuery(document).ready(function() {
  jQuery('#toggle-nav').click(function(e) {
    toggleNav();

    function toggleNav() {
      event.stopPropagation();
      jQuery(this).toggleClass('active');
      jQuery('.menu ul').toggleClass('active');
      jQuery('.hamburger ul').toggleClass('active');
      jQuery('.dimmer').toggleClass('active');
      jQuery('body').toggleClass('no-scrolling');

      e.preventDefault();
    }
  });
});

3 个答案:

答案 0 :(得分:2)

你有几个问题。您正在定义click事件内部的函数并直接调用它。因此,您的this变量的范围不正确,无法满足您的需求。这也意味着每次单击#toggle-nav时,都会创建,调用,然后销毁该函数。如果您在click事件之外声明它,则只创建一次,而不是每次单击都会重复使用它。当您使用的参数名称为event.stopPropagation()时,您还使用了e。最后,您不需要将匿名函数传递给.click函数。您可以按名称传递命名函数,它将直接调用。

以下是您的代码清理了一点以解决这些问题。

jQuery(document).ready(function () {
    jQuery('#toggle-nav').click(toggleNav);

    function toggleNav(e) {
        e.stopPropagation();
        jQuery(this).toggleClass('active');
        jQuery('.menu ul').toggleClass('active');
        jQuery('.hamburger ul').toggleClass('active');
        jQuery('.dimmer').toggleClass('active');
        jQuery('body').toggleClass('no-scrolling');

        e.preventDefault();
    }
});

或者,您可以使用匿名函数。

jQuery(document).ready(function () {
    jQuery('#toggle-nav').click(function (e) {
        jQuery(this).toggleClass('active');
        jQuery('.menu ul').toggleClass('active');
        jQuery('.hamburger ul').toggleClass('active');
        jQuery('.dimmer').toggleClass('active');
        jQuery('body').toggleClass('no-scrolling'); //Alternatively : jQuery(document.body)

        return false;
    });
});

关于evente的使用,请参阅this link。基本上,event属性存在于某些浏览器的全局上下文中。这意味着您的代码可能在这些浏览器中运行,但在其他浏览器中会破坏。 Click事件会自动将事件作为提供函数的第一个参数传递给您,这样您就可以直接访问它了。

最后一点,当使用jQuery事件return false;同时触发e.stopPropagation();e.preventDefault();时,如果您返回false,则不需要自己调用它们。

jQuery source for reference

答案 1 :(得分:0)

在原始代码中,this的值是指#toggle-nav元素。在修订版中,this引用其父函数。

答案 2 :(得分:0)

您需要将您的功能移出事件监听器。

jQuery(document).ready(function() {
  jQuery('#toggle-nav').click(function(e) {
    e.stopPropagation();
    toggleNav();
    e.preventDefault();
  });
});

function toggleNav() {
  jQuery('#toggle-nav').toggleClass('active');
  jQuery('.menu ul').toggleClass('active');
  jQuery('.hamburger ul').toggleClass('active');
  jQuery('.dimmer').toggleClass('active');
  jQuery('body').toggleClass('no-scrolling');
}

我还在函数中添加了正确的选择器,因为this发生了变化。如果你愿意,你可以传递事件目标(e.target也许,我无法回想起我的头脑。为了回答你的上一个问题,我怀疑你没有问题,但是如果不查看你的所有代码,我无法肯定地说。