【问题标题】:Sort li and event handlers with jQuery使用 jQuery 对 li 和事件处理程序进行排序
【发布时间】:2014-01-25 15:09:26
【问题描述】:

所以,我在对列表进行排序时遇到问题,我丢失了附加到列表项的任何事件处理程序。我知道如何使用我想要的 w/e 过滤器对列表进行很好的排序,只是我不知道如何保留附加到每个列表元素的事件处理程序。那么,代码...

HTML

<ul id="classes">
    <li class="class_2" date-created="Sat Jan 04 2014 20:46:55 GMT-0500 (EST)">Calc 152<di class="class_list_arrow"></di></li>
    <li class="class_3" date-created="Mon Jan 06 2014 21:26:59 GMT-0500 (EST)">Phys 133<di class="class_list_arrow"></di></li>
</ul>

排序 JS

function ascending (){
    var rows = $('#classes li').get();

    rows.sort(function(a, b) {

      var A = new Date($(a).attr('date-created')).getTime();
      var B = new Date($(b).attr('date-created')).getTime();

      //var events = $._data($(a).get(0), "events");
      //alert(JSON.stringify(events));

      if(A < B) {
        return -1;
      }

      if(A > B) {
        return 1;
      }

      return 0;     
   });

    $('#classes').html('');
    $.each(rows, function(index, row) {
             $('#classes').append(row);
    });
}

所以...这就是我卡住的地方。我可以得到attr。 date-created 很好,可以按照我的需要进行排序,但是在每个 li 元素上我都有一个 'tap' 事件处理程序和一个 'swiperight swipeleft' 处理程序,这些在排序后会丢失并附加回 dom。

我很确定我需要使用存储在 var 事件中的 $._data 方法......但不知道如何去做。感谢您的帮助!

【问题讨论】:

  • 删除此行并查看:$('#classes').html(''); 附加一个已经存在的元素只需移动它,保留附加的处理程序
  • @A. Wolff:我认为,这会重复列表项。
  • @AshishKumar 不,不会因为它们没有被克隆。
  • @A.沃尔夫:哇,答案总是比我想象的要容易啊啊。谢谢!

标签: jquery sorting


【解决方案1】:

鉴于此 html

<ul id="classes">
  <li class="l_3" data-doc="Mon Jan 06 2014 22:26:59 GMT-0500 (EST)">a</li>
  <li class="l_1" data-doc="Sat Jan 04 2014 20:46:55 GMT-0500 (EST)">b</li>
  <li class="l_2" data-doc="Mon Jan 06 2014 21:00:09 GMT-0500 (EST)">c</li>         
</ul>
<button onclick="SortAscending()">sort</button>

function SortAscending() 是这样的:

function SortAscending ()
{    
    var rows = $('#classes li').get();
    rows.sort(function(a, b) {
          var A = new Date($(a).attr('data-doc')).getTime();
          var B = new Date($(b).attr('data-doc')).getTime();
          if(A < B) { return -1; }
          if(A > B) { return 1; }
          return 0;     
    });

    $.each(rows, function(index, row) {
             $('#classes').append(row);
    });    
}

每个事件处理程序都保持连接状态。

原因来自 jQuery 源码

正如A. Wolff 指出的部分$('#classes').html('') 是罪魁祸首。在 html() 函数的 jQuery-Source 中有这样的内容:

 if ( typeof value === "string" .... )
 {
    ...
    for (; i < l; i++ )
    {
       // Remove element nodes and prevent memory leaks
       elem = this[i] || {};
       if ( elem.nodeType === 1 )
       {
          jQuery.cleanData( getAll( elem, false ) );
          elem.innerHTML = value;
       }
    }
 }

所以调用$('#classes').html('') 被评估为传递一个字符串并清除所有附加的处理程序。

如果处理程序仍然附加,我使用此代码对其进行了测试。

$( document ).ready(function() {
    $(".l_1").on("click", function(){ alert("item 1")});
    $(".l_2").on("click", function(){ alert("item 2")});
    $(".l_3").on("click", function(){ alert("item 3")});

});

【讨论】:

  • 感谢您很好地解释了幕后发生的事情!
猜你喜欢
  • 2012-04-23
  • 1970-01-01
  • 2011-03-28
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
相关资源
最近更新 更多