2013-04-27 36 views
4

我目前正在開發級聯樹菜單。當一個樹項目被展開時,它會在其下面創建新的<div>,該項目也可能會擴展。我可以得到第一組<div>的綁定並因此展開,但我似乎無法使用「this._on」方法自動綁定新創建的div。我正在尋找類似於live(),delegate()和on()的功能。jQuery UI Widget Factory中的實時綁定事件使用this._on()

我已將我的代碼張貼在jsFiddle上http://jsfiddle.net/vEAhq/

我設置的事件上線60

在審查下_setupEvents方法結合,即在所述刷新方法創建的元素,所述方法_create綁定行期間調用。這是在_expand方法中創建的元素不會像我所期望的那樣被綁定。

提前感謝您的時間。

$.widget("custom.categoryMenu", { 

    options: { 
     links: null 
    }, 

    _create: function() { 
     this.refresh(); 
     this._on('.categoryNavigationExpandIcon', { 
      click: function(event) { 
       var $container = $(event.target).parent(); 
       if(($container).data('expanded') === false) { 
        this._expand($container); 
       } else { 
        this._contract($container); 
       } 
      } 
     }); 
    }, 

    refresh: function() { 
     var $elm = this.element; 
     var $newElem; 
     var $itemTree = this.options.links; 
     var $itemTreeRoot = sortObj($itemTree['1'], 'function', true); 

     this._setupEvents(); 

     $.each($itemTreeRoot, function(key, value) { 
      var ID = $itemTreeRoot[key]; 
      var label = key; 
      $newElem = $('<div style="padding:8px 0;"></div>') 
       .data('expanded', false) 
       .data('id', ID) 
       .data('level', 1) 
       .addClass('categoryNavigationLevel1'); 
      $('<div class="categoryNavigationExpandIcon"></div>').appendTo($newElem); 
      $('<a href="index.cfm?action=products&cat=' + ID + '" rel="?cat=' + ID + '" class="categoryMenuLabel">' + label + '</a>').appendTo($newElem); 
      // Add triangle icons if there are children 
      if ($itemTree[ID]) { 
       $($newElem) 
        .find('.categoryNavigationExpandIcon') 
        .addClass('ui-icon') 
        .addClass('ui-icon-triangle-1-e'); 
      } 
      $elm.append($newElem); 
     }); 
    }, 

    _setupEvents: function() { 
     var events = { 
      click: function(event) { 
       event.preventDefault(); 
      } 
     }; 

     this._on('.categoryNavigationExpandIcon', { 
      click: function(event) { 
       var $container = $(event.target).parent(); 
       if(($container).data('expanded') === false) { 
        this._expand($container); 
       } else { 
        this._contract($container); 
       } 
      } 
     }); 
    }, 

    _expand: function(container) { 
     var $elm = this.element; 
     var $itemTree = this.options.links; 
     var containerLevel = $(container).data('level'); 
     var containerID = $(container).data('id'); 
     var newContainerLevel = containerLevel + 1; 

     var $itemTreeBranch = sortObj($itemTree[containerID], 'function', true); 

     $(container) 
      .data('expanded', true) 
      .find('.ui-icon-triangle-1-e') 
      .removeClass('ui-icon-triangle-1-e') 
      .addClass('ui-icon-triangle-1-se'); 

     $.each($itemTreeBranch, function(key, value) { 
      var ID = $itemTreeBranch[key]; 
      label = key; 
      $newElem = $('<div style="padding:8px 0;"></div>') 
       .data('expanded', false) 
       .data('id', ID) 
       .data('level', newContainerLevel) 
       .addClass('categoryNavigationLevel' + newContainerLevel); 
      $('<div class="categoryNavigationExpandIcon"></div>').appendTo($newElem); 
      $('<a href="index.cfm?action=products&cat=' + ID + '" rel="?cat=' + ID + '" class="categoryMenuLabel">' + label + '</a>').appendTo($newElem); 
      // Add triangle icons if there are children 
      if ($itemTree[ID]) { 
       $($newElem) 
        .find('.categoryNavigationExpandIcon') 
        .addClass('ui-icon') 
        .addClass('ui-icon-triangle-1-e'); 
      } 
      $(container).after($newElem); 
     }); 
    }, 

    _contract: function(container) { 
     var containerLevel = $(container).data('level'); 
     $(container) 
      .data('expanded', false) 
      .find('.ui-icon-triangle-1-se') 
      .removeClass('ui-icon-triangle-1-se') 
      .addClass('ui-icon-triangle-1-e'); 

     $(container) 
      .nextUntil('.categoryNavigationLevel' + containerLevel) 
      .remove(); 
    }, 

    destroy: function() { 
     $.widget.prototype.destroy.call(this); 
    } 

}); 

/** 
* Name: Sort Javascript Object 
* Credit: Arne Martin Aurlien 
* URL: http://am.aurlien.net/post/1221493460/sorting-javascript-objects 
*/ 
sortObj = function(obj, type, caseSensitive) { 
    var temp_array = []; 
    for (var key in obj) { 
     if (obj.hasOwnProperty(key)) { 
      if (!caseSensitive) { 
       key = (key['toLowerCase'] ? key.toLowerCase() : key); 
      } 
      temp_array.push(key); 
     } 
    } 
    if (typeof type === 'function') { 
     temp_array.sort(type); 
    } else if (type === 'value') { 
     temp_array.sort(function(a,b) { 
      var x = obj[a]; 
      var y = obj[b]; 
      if (!caseSensitive) { 
       x = (x['toLowerCase'] ? x.toLowerCase() : x); 
       y = (y['toLowerCase'] ? y.toLowerCase() : y); 
      } 
      return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 
     }); 
    } else { 
     temp_array.sort(); 
    } 

    var temp_obj = {}; 
    for (var i=0; i<temp_array.length; i++) { 
     temp_obj[temp_array[i]] = obj[temp_array[i]]; 
    } 

    return temp_obj; 
}; 
+0

你能用HTML結構編輯你的小提琴嗎? (順便說一句,你必須在左側包含jQuery和jQuery-UI) – 2013-04-27 23:18:07

+0

我已經更新了小提琴,以包含一個可用的HTML示例。 (注意:json對象非常大)。對小部件的調用是最後一個。 – 2013-04-27 23:51:00

+0

好吧謝謝,但當你更新小提琴,鏈接改變:) 我想這是更新的? http://jsfiddle.net/vEAhq/5/ – 2013-04-28 00:07:12

回答

11

這是更好的,當你有追加一些新創建的內容,結合文檔上的事件,對指定選擇或自定義事件。

舉例來說,如果你正在試圖綁定在一個給定的類」。你的級點擊:

$('.your-class').on('click', function (e) { 
    // ... 
}) 

您希望通過更換:

$(document).on('click', '.your-class', function (e) { 
    // ... 
}) 

它恰好爲jQuery用戶界面相同:

你只希望更換:

// Here you just bind a click on the existing elements of your class 
this._on('.categoryNavigationExpandIcon', { 
    click: function(event) { 
     var $container = $(event.target).parent(); 
     if(($container).data('expanded') === false) { 
      this._expand($container); 
     } else { 
      this._contract($container); 
     } 
    } 
}); 

通過:

// Bind a custom event on the document in order to delegate this event event to the new created classes 
this._on(this.document, { 
    'click.categoryNavigationExpandIcon': function(event) { 
     var $container = $(event.target).parent(); 
     if(($container).data('expanded') === false) { 
      this._expand($container); 
     } else { 
      this._contract($container); 
     } 
    } 
}); 

你可以在這裏找到更新的jsfiddle: http://jsfiddle.net/vEAhq/7/

順便說一句,你可以在創建使用jQuery一個元素跳過關閉標籤!

$('<div>'); // instead of $('<div></div>'); 
+0

非常感謝你@ Flo-Schield-Bobby爲你提供的幫助這個。基本上我的語法錯了。對於將該事件委託給該文件,我有點不同意。 'live()'總是這樣做的,他們用'delegate()'和'on()'代替它,這樣整個文檔就不會一直在觀察變化。相反,我將代理從this.document移動到this.element,以便它只委託給UI Widget的容器​​。更新後的代碼位於http://jsfiddle.net/vEAhq/8/。再次感謝您的幫助。 – 2013-04-28 18:59:23

+0

好吧,你是對的,只要記住它只會在你將新的HTML元素追加到初始綁定元素內時才起作用! – 2013-04-28 20:24:58

相關問題