2017-02-24 53 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