2017-02-24 55 views
1

我是JQuery(更多C#)的新手,无法看到我在这里做错了什么。重构后JQuery函数无法正常工作

我有下面的JQuery,它可以切换汉堡包菜单,并且还可以调节调光效果并防止滚动到正文。汉堡包也从3条水平线移动到X.在第一个JQuery(如下)中,这工作正常。不过,我一直在试图改进这一点,并清理我的代码到下面的第二个JQuery,这对我来说看起来更清晰(铭记未来的功能)。然而,当我这样做时,除了汉堡包之外,所有东西仍然按照预期工作,不再为X创作动画。无论如何,我真的不明白为什么没有真正明显的区别。

另外,作为一个新手,我也很想知道,即使是需要这样的功能的代码如下两行:

e.preventDefault(); 

event.stopPropagation(); 

JQuery的(作品):

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

你不应该使用'event.stopPropagation()'它应该是'e.stopPropagation()'。另外,将你的代码移动到一个新的函数中,这个函数是在事件处理程序本身中定义的,看起来很傻,因为每次单击时,函数都会被重新定义... –

+0

感谢您的回答,我没有意识到这是我在做什么。 – Damo

回答

2

你有几个问题。您正在定义click事件中的函数并直接调用它。因此,您的this变量的作用域不正确,无法满足您的需求。这也意味着,每次单击#toggle-nav时,函数都会被创建,调用并销毁。如果您在单击事件之外声明它,则只会创建一次,而不是每次点击重复使用。您还使用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属性存在于某些浏览器的全局上下文中。这意味着你的代码可能在这些浏览器中运行,但它会在其他浏览器中破解。点击事件会自动将事件作为第一个参数传递给所提供的函数,以便您可以直接在其中跨浏览器访问它。

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

jQuery source for reference

+0

这绝对是太棒了,并且帮助我了解发生了什么。它也让我意识到我对JQuery知道得有多少,以及它对c#有多不同(这是我的日常工作,但仍有很长的路要走)!做你所做的事情,以及我试图做的事情,都是正确的,即更好地分别创建一个函数并调用它,而不是在click事件内部定义函数? – Damo

+0

很高兴我可以帮助:)一般情况下,如果你只使用该功能,我不认为它会伤害到只使用匿名函数。我编辑了我的答案,包括一个例子。 – Marie

+1

玛丽,再次感谢你,非常感谢。 – Damo

0

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

+0

感谢您的回答,并再次指出了我没有意识到的事情。 – Damo

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变化。如果你想要的话,你可以通过事件目标(也许,我无法回想起我的头顶)。为了回答你最后一个问题,我怀疑你没有考虑到这两条问题,但是没有查看所有的代码,我不能肯定地说。

+0

感谢您的回答。我会接受玛丽亚的回答,但只是想表示感谢,因为迄今为止所有的答案都让我意识到了一些新的东西。 – Damo