2013-04-28 76 views
2

我創建了一個響應模板,並且當屏幕正在調整大小或小於指定的寬度時,我想要移除元素上的偵聽器。
設想一個菜單,當您將鼠標懸停在項目上時,它會顯示正常顯示中的子菜單,但移動設備中的相同菜單僅通過點擊或點擊項目來顯示子菜單。jQuery Undelegate不起作用

我不能讓undelegate工作。在調整大小的屏幕上,我仍然有mouseovermouseout事件偵聽器。我沒有得到在控制檯的任何錯誤,我都試過:

  • .off('mouseover', 'li')
  • .off('mouseover')
  • .undelegate('li', 'mouseover')
  • .undelegate('li')


和他們沒有工作。

var $window = $(window); 
    function handleSidenav() { 
    $(".nav-list").delegate('li', 'mouseover', function(e) { 
     $(this).find("a").addClass('active'); 
     $(this).find("div.sub-items").toggle(); 
    }).delegate('li', 'mouseout', function(e) { 
     $(this).find('a').removeClass('active'); 
     $(this).find("div.sub-items").toggle(); 
    }); 
} 

function checkWidth() { 
    var windowsize = $window.width(); 
    if (windowsize < 767) { 
     smallScreenDelegation(); 
    } else { 
     SmallScreenUndelegation(); 
    } 
} 
checkWidth(); 
handleSidenav(); 
$window.resize(checkWidth()); 

function smallScreenDelegation() { 
    $(".nav-list").undelegate('li'); //It's not working 
    $(".nav-list").undelegate('li'); //It's not working 
    $(".nav-list").delegate('li a:first', 'click', function(event) { 
     if ($(this).next().is(':hidden')) { 
      $(this).addClass('active'); 
      $(this).next().slideDown('slow'); 
     } else { 
      $(this).removeClass('active').next().slideUp('slow'); 
     }    
     event.preventDefault(); 
    }); 
} 
+1

你當然意識到你剛剛做出了一個主要的噓聲,因爲你重新調整每個瀏覽器調整大小的事件處理程序,可能在某些時候導致類似堆棧溢出的事情? – adeneo 2013-04-28 19:08:45

+0

我以前遇到過這種情況,我認爲它與你在該類存在之前向代理鼠標懸停添加一個類有關。 – nick 2013-04-28 19:13:11

+0

@MarcelGwerder'mouseover'和'mouseout'通常在觸摸時發生在觸摸設備上。 – 2013-04-28 19:14:23

回答

0

我仍然不知道什麼是錯的undelegate,我不能使它的工作,但我設法修復我的代碼通過使用onoff

作爲adeneo said我在每個窗口上委託和取消調整大小,這是一個安靜的錯誤,我想我解決了這個問題,但保留了device變量的最後一個狀態。

var $window = $(window); 
var device; 

function desktopSidenav() { 
    $(".nav-list > li").off('click'); 
    $(".nav-list > li").on('mouseover', function(e) { 
     $(this).find("a").addClass('active'); 
     $(this).find("div.sub-items").toggle(); 
    }).on('mouseout', function(e) { 
     $(this).find('a').removeClass('active'); 
     $(this).find("div.sub-items").toggle(); 
    }); 
} 

function handheldSidenav() { 
    $(".nav-list > li").off('mouseover').off('mouseout'); 
    $(".nav-list > li").on('click', function(e) { 
     if ($(this).find("div.sub-items").is(':hidden')) { 
      $(this).find("a:first").addClass('active').next().slideDown('slow'); 
     } else { 
      $(this).find("a:first").removeClass('active').next().slideUp('slow'); 
     }    
     e.preventDefault(); 
    }); 
} 

現在我做別的事情了,我會在device變量保存設備類型之前檢查窗口大小。如果調整窗口大小,我將檢查設備狀態並根據設備類型進行操作。

if ($window.width() > 767) { 
    device = 'desktop'; 
    desktopSidenav(); 
} else { 
    device = 'handheld'; 
    handheldSidenav(); 
} 
$window.resize(function() { 
    if ($window.width() > 767) { 
     if (device == 'handheld') { 
      device = 'desktop'; 
      desktopSidenav(); 
     } 
    } else { 
     if (device == 'desktop') { 
      device = 'handheld'; 
      handheldSidenav(); 
     } 
    } 
}); 

如果我使用delegateundelegate代替onoff,代碼將無法正常工作,我仍然不知道爲什麼,所以這不能算是真正的答案,但我想告訴大家誰有類似的問題使用jQuery的onoff而不是delegate

+0

這聽起來像你不確定哪些代碼路徑真的在不同的情況下運行。添加大量'console.log'語句來了解真正發生的事情。這會比猜測更快。失敗;再猜;再次失敗;無限廣告。 – 2013-05-03 22:53:55

1

您需要將窗口包裝到jQuery對象中。我不知道你是否設置了$ window = $(window),但是在這裏似乎$ window.width()和$ window.resize(checkWidth)缺少括號。一旦我將它們更改爲$(窗口),我就可以正常工作。你必須定義你想要取消打開哪個事件。我用:

$('.nav-list').undelegate('li', 'mouseover'); 

打開控制檯,你可以看到,它的工作原理:http://jsbin.com/efonut/6/edit

而且,它是真正最好用。對()和關閉()VS .delegate()和.undelegate( ),但至少這個工程...

+0

對不起,我是一個稍晚點兒,但我已經聲明'var $ window = $(window);'早些時候,並感謝提到'$ window.resize(checkWidth())缺少的括號;'但我仍然無法使其工作。 – 2013-05-01 11:26:57