2011-04-11 35 views
1

我有一個很好的創建我需要的事件日曆自定義工具提示的函數。問題是,當用戶點擊去日曆上的下個月時,會創建一組新的鏈接,並且jQuery不再選擇這些鏈接。在jQuery中使用.delegate

這是我原來的功能:

jQuery(function(){ 
     var tip = jQuery("#tip"); 
     var myTitle = ""; 

     jQuery(".eventful-pre a, .eventful a").hover(function(e){ 

     toolTip = "<ul>"; 
      jQuery.each(jQuery(this).attr("title").split(","),function(ind, val){ 
       toolTip = toolTip +"<li>"+val +"</li>"; 
      }); 
      toolTip = toolTip +"</ul>"; 

      tip.html(toolTip); 
      myTitle = jQuery(this).attr("title"); 

      jQuery(this).attr("title", ""); 

      tip.css("top",(e.pageY+5)+"px") 
       .css("left",(e.pageX+5)+"px") 
       .fadeIn("slow"); 

     }, function() { 
       jQuery("#tip").fadeOut("fast"); 

       jQuery(this).attr("title", myTitle); 
     }); 

它的作品我怎麼想的那樣。我認爲.delegate是我想用來抓取新元素的時候,但我可能做錯了,因爲它不起作用。

jQuery("table").delegate("a.em-calnav", function(){ 
     in here I pasted my previous function. 
    } 

日曆可以在http://dev.adabible.org/about-ada/

可以看出我必須在做的.delegate錯誤的,也必須有一個更好的方式去了解的東西比再次粘貼我的功能,並且使其兩次相同的腳本。

先謝謝你哦!

回答

2

jQuery的delegate方法實際上分配一個事件監聽器。你使用了jQuery("table").delegate(...),所以你告訴jQuery爲頁面上的每個表分配一個事件監聽器。

因此,第一步是找出您想要聽的事件。你正在做工具提示,所以目前你正在使用「懸停」。除了「懸停」實際上是兩個事件之一:「mouseenter」和「mouseleave」,沒有什麼不對。您可以使用delegate的「懸停」,但前提是您有一個功能可以處理「輸入」和「離開」事件。它看起來像你使用了兩個不同的功能:一個在工具提示中建立/淡入,一個在摧毀它。

您可以使用delegate兩次,一次用於「輸入」,一次用於「離開」,但(according to this comment on jQuery)實際上並未在所有瀏覽器上支持。 (QuirksMode has a good set of compatibility tables regarding "enter"/"leave", and an explanation of why they're awesome.

所以它看起來像你將不得不使用「鼠標懸停」「鼠標移開」這是因爲如何事件冒泡工作變得更加複雜了一點。但!如果您只在簡單鏈接上使用工具提示(例如,a包含文本而沒有其他內容的元素,或者一個圖像而沒有其他內容),則事情應該可以正常工作。

下一步需要知道event bubbling, another subject that QuirksMode explains really well。將鼠標移到元素上時,會觸發「鼠標懸停」事件。如果該元素具有「鼠標懸停」事件偵聽器,則會執行該偵聽器。 事件然後移動到元素的父級。如果父級具有「鼠標懸停」事件偵聽器,那麼也會被執行。這一直持續到事件經過每一位家長,一直到document

所以當你使用delegate時,你需要告訴jQuery你正在尋找哪些元素。如果你在等待一個「鼠標懸停」事件起源於一類的a元素上「懸停」,那麼你會使用這樣的事情:

jQuery(document).delegate('a.hover', 'mouseover', ...); 

注意,第一部分可以是任何東西,包含您的所有a.hover元素。這些將差不多所有的工作:

jQuery('body').delegate('a.hover', 'mouseover', ...); 
jQuery(document).delegate('a.hover', 'mouseover', ...); 
jQuery('div.some_container').delegate('a.hover', 'mouseover', ...); 

我提出這個問題的原因是因爲在當前的功能,您使用的選擇".eventful-pre a, .eventful a"。但之後,當您嘗試授權時,您使用"a.em-calnav"。你實際上想要瞄準哪個選擇器?如果所有可能有工具提示的鏈接也都有「em-calnav」類,那麼我會去做,只是因爲你不必爲後代選擇器而煩惱。但是任何一個都是有效的。

所以我們最終得到的是這樣的:

jQuery(function() { 
    var tip = jQuery("#tip"); 
    var myTitle = ""; 

    jQuery("table").delegate("YOUR_SELECTOR", "mouseover", function (e) { 
     var toolTip = "<ul>"; 
     jQuery.each(jQuery(this).attr("title").split(","), function (ind, val) { 
      toolTip = toolTip + "<li>" + val + "</li>"; 
     }); 
     toolTip = toolTip + "</ul>"; 

     tip.html(toolTip); 
     myTitle = jQuery(this).attr("title"); 
     jQuery(this).attr("title", ""); 

     tip.css("top", (e.pageY + 5) + "px") 
      .css("left", (e.pageX + 5) + "px") 
      .fadeIn("slow"); 

    }).delegate("YOUR_SELECTOR", "mouseout", function() { 
     jQuery("#tip").fadeOut("fast"); 
     jQuery(this).attr("title", myTitle); 
    }); 
}); 

你的問題是,加載一個新的日曆時,該鏈接不再有「懸停」事件偵聽器。此解決方案在此將活動委託給table。但是,如果在構建新日曆的過程中還要創建一個新表格,那麼這個解決方案並沒有什麼作用。你必須將事件委託給表的父項或其他事物。基本上,你委託給你的JavaScript並沒有真正改變的元素。 (這就是爲什麼document"body"在事件委派中如此常見。)

另外,我並沒有真正改變函數本身;我只是把他們移到適當的地方。但有些事情你可以做得更有效一些。我看到的最大問題就是您構建工具提示的方式。與其說jQuery.each的,你很可能做這樣的事情:

var toolTip = "<ul>"; 
myTitle = jQuery(this).attr("title"); 

toolTip += "<li>" + myTitle.split(",").join("</li><li>") + "</li></ul>"; 

希望我能幫助。祝你好運。

+0

感謝您的詳細解答!這真的幫助我理解這是如何工作的。 a.eventful和a.eventful-pre鏈接是與工具提示(當前月份和上個月)的實際鏈接。 a.em-calnav是在日曆上切換月份的鏈接,它會創建一個新表。我的想法是,工具提示工作正常,所以當a.em-calnav被點擊() - ed時,將腳本刪除到新表。我想我不理解代表如何正確工作。我以爲我基本上是單擊重新應用或重新加載腳本。我會在早上嘗試這個,然後回到這裏。 – Jarrod 2011-04-12 03:57:13

+0

這一切都很完美!再次感謝你。感謝您給我提供更多的信息來學習,這絕對是我更加精通jQuery的目標。同樣感謝您對效率的評論,該代碼片段效果很好,我總是很高興讓我的代碼更高效。 – Jarrod 2011-04-12 14:31:52

1

首先想到的是,您未能爲委託指定事件。

你應該使用這樣的:

jQuery("table").delegate("a.em-calnav", 'click', function(){ 
    in here I pasted my previous function. 
} 

注意添加click(應該是你要委託爲準事件)。