Добавить элемент <li>к <ul>и добавить событие щелчка для каждого? - PullRequest
6 голосов
/ 24 мая 2011

Я хотел бы добавить серию <li> элементов к <ul> и добавить событие click для каждого из них программным способом.

Я не уверен, как это сделать, по крайней мере, не аккуратно, jQueryish.

Это мой существующий код:

<ul id="saved-list"></ul>
<script type="text/javascript">
$.each(all_objects, function() {{
    var list_route = "<li><a href='#saved-route'>" + this.text + "</a></li>";
    $('#saved-list').append(list_route);      
    // add unique id (this.id) to item and click event here?
    // pseudocode - onclick: alert(this.id);
});
$('#saved-list').refresh('listview'); // jquery mobile list refresh
</script>

Может, кто-нибудь посоветует, как программно добавить событие щелчка к каждому элементу списка?

ОБНОВЛЕНИЕ: мне нужно сделать что-то немного отличающееся для каждого элемента списка (скажем, предупреждение) - извиняюсь за то, что не прояснил это.

Ответы [ 10 ]

14 голосов
/ 24 мая 2011

Вам лучше использовать .live() или .delegate(), чем беспокоиться о создании обработчика .click() для каждого создаваемого вами элемента. Примерно так:

$('#saved-list').delegate('li', 'click', function () {
    // do stuff on click
});

Вам нужно только один раз связать этот прослушиватель щелчков, и он будет работать для каждого <li>, который является потомком элемента с идентификатором saved-list.


Если вы хотите создать отдельный обработчик кликов для каждого <li> (хотя я не рекомендую это), вот хороший способ сделать это:

$.each(all_objects, function() {
    var $a = $('<a/>', {
        href: '#saved-route',
        text: this.text
    });

    var $li = $('<li/>', {
        click: function () {
            // do stuff on click
        }
    }).append($a);

    $('#saved-list').append($li);
});
5 голосов
/ 24 мая 2011

Не.

Вместо того, чтобы связывать новый обработчик событий для каждого элемента (который может стать довольно дорогим), связывайте отдельный обработчик событий с #saved-list, который является общим предком.Пузырьки событий означают, что элементы-предки уведомляются о событиях их потомков, поэтому вы можете обрабатывать события там, а не в исходном элементе.

Что-то вроде этого ...

$.each(all_objects, function() {{
    var list_route = "<li><a href='#saved-route'>" + this.text + "</a></li>";
    $('#saved-list').append(list_route);      
});
$('#saved-list').delegate('li', 'click', function() {
    // do something here each time a descendant li is clicked
});

См. delegate

4 голосов
/ 24 мая 2011

@ Мэтт Болл довольно близок к ответу здесь, но я добавлю немного более ясно, что вы можете делать разные вещи с делегатом в зависимости от того, по какому элементу щелкнули:

<ul id="saved-list"></ul>
<script type="text/javascript">
var $savedList = $("#saved-list");
$.each(all_objects, function() {
    $savedList.append("<li><a href='#saved-route'>" + this.text + "</a></li>");
});
$savedList.delegate("li", "click", function (e) {
    alert($(this).text());
});
.

$ ( '# сохранен-лист') обновить ( 'ListView'); // Обновление списка мобильных телефонов jquery

Обратите внимание, что в делегате this все еще ссылается на li, на который была нажата кнопка.

1 голос
/ 24 мая 2011

Вы можете использовать функцию live, недостатком является то, что вам может понадобиться какой-то механизм, чтобы точно определить, какой из li элементов был нажат:

$("#saved-list li").live('click', function() {
    //act on click
});
1 голос
/ 24 мая 2011

Привет, Фил в jquery Вы можете создать объект DOM, не добавляя их в виде текста в DOM.это даст вам возможность изменять их, прежде чем они будут добавлены (и после).

$("<li />")
  .append(
    $("<a />")
     .attr("href" ,"#saved-route")
     .text(this.text))
  .click(function() {
    // your click event
  })
  .appendTo("#saved-list");
1 голос
/ 24 мая 2011

Разве недостаточно добавить это в (или после) вашего текущего цикла?

$('#saved-list li').click(function(){ alert('hello'); });

0 голосов
/ 24 мая 2011

Хотя я не знаю, о чем этот бизнес $('#saved-list').refresh('listview'), вам может понадобиться следующее:

var listItemEls = all_objects.map(function () {
    return $('<li id="' + this.id + '"><a href="#saved-route">' + this.text + '</a></li>')
           .click(function (e) {
               // do whatever here
           })
           .get();
});

$('#saved-list').append(listItemEls);

Обратите внимание, что мы избегаем добавления в DOM до последней минуты, потому что добавление стоит дорого.

Как отмечают другие авторы, использование делегированного обработчика кликов, как правило, является лучшим подходом. Это выглядело бы как

var listItemEls = all_objects.map(function () {
    return $('<li id="' + this.id + '"><a href="#saved-route">' + this.text + '</a></li>')
           .get();
});

$('#saved-list').append(listItemEls)
                .delegate("li", "click", function (e) {
                    // do stuff here.
                });
0 голосов
/ 24 мая 2011

Функция .click свяжет функцию обработчика щелчка с любым данным элементом. Как отмечают комментарии в вашем коде, вы можете использовать идентификатор или другие средства для выбора элемента после того, как он был DOM-изомирован, но другой способ сделать это - просто обратиться к переменной, содержащей элемент, который вы хотите связать.

Пример:

var li = $('<li />');
li.click(function() { ... });

Это, вероятно, несколько стилистично, но одна из особенностей jQuery - это возможность цепочки. Это означает, что вызовы функций jQuery всегда возвращают ссылку на упакованный набор самого jQuery. Используя цепной аспект, вы можете переписать приведенный выше код следующим образом:

var list = $('#saved-list'); $.each(all_objects, function(i, item) {{
    list.append(
        $('<li />')
            .append(
                $('<a />').text(item.text)
            )
            .click(function() { ... } );
    );
});
0 голосов
/ 24 мая 2011
$.each(all_objects, function() {{
    var list_route = "<li><a href='#saved-route'>" + this.text + "</a></li>";
    var newLi = $(list_route);
    newLi.click( function(){} ).attr("id","foo");
    //if you want the a
    newLi.find("a").click( function(){} ).attr("id","foo");

    $('#saved-list').append(newLi);              
});
0 голосов
/ 24 мая 2011

Вот почему существует bind.

$.each(all_objects, function(index) {{
    $("#saved-list").append("<li id='item" + index + "'><a href='#saved-route'>" + this.text + "</a></li>");
    $("#saved-list li").bind("click", function() {
        alert("Clicked on " + this.id);
    });
});

Кроме того, таким способом очень легко создавать различные клики для каждого элемента:

$("#saved-list li#item1").bind(...)
$("#saved-list li#item2").bind(...)
$("#saved-list li#item3").bind(...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...