Javascript 将 <li> 元素附加到 <ul> 并为每个元素添加点击事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6111650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Append <li> element to <ul> and add click event for each?
提问by phil123
I'd like to add a series of <li>
elements to a <ul>
, and add a click event to each one, programmatically.
我想以编程方式<li>
向 a添加一系列元素<ul>
,并为每个元素添加一个点击事件。
I'm not sure how to do this, at least not in a neat, jQueryish way.
我不知道如何做到这一点,至少不是以一种简洁的、jQuery 风格的方式。
This is my existing code:
这是我现有的代码:
<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>
Please could someone advise how to add a click event to each list item programmatically?
请有人建议如何以编程方式向每个列表项添加点击事件?
UPDATE: I need to do something slightly different for each list item (let's just say an alert) - apologies for not making this clear.
更新:我需要为每个列表项做一些稍微不同的事情(我们只是说一个警报) - 很抱歉没有说清楚。
回答by Matt Ball
You're better off using .live()
or .delegate()
than worrying about creating a .click()
handler on every element you create. Something like this:
您最好使用.live()
或.delegate()
担心.click()
在您创建的每个元素上创建处理程序。像这样的东西:
$('#saved-list').delegate('li', 'click', function () {
// do stuff on click
});
You only have to bind this click listener once, and it will work for every <li>
that is a descendant of the element with ID saved-list
.
你只需要绑定一次这个点击监听器,它就适用于<li>
ID 元素的所有后代saved-list
。
If you do want to create a separate click handler for every <li>
(I don't recommend this though) here's a nice way to do it:
如果您确实想为每个<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);
});
回答by lonesomeday
Don't.
别。
Rather than binding a new event handler for each element (which could become quite expensive), bind a single event handler to #saved-list
, which is a common ancestor. Event bubbling means that ancestor elements are notified of events on their descendants, so you can handle events there instead of on the originating element.
与其为每个元素绑定一个新的事件处理程序(这可能会变得非常昂贵),不如将单个事件处理程序绑定到#saved-list
,这是一个共同的祖先。事件冒泡意味着祖先元素会在其后代元素上收到事件通知,因此您可以在那里而不是在原始元素上处理事件。
Something like this...
像这样的东西...
$.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
});
See delegate
看 delegate
回答by Mike Axiak
@Matt Ball is pretty close to the answer here, but I will add a little more clearly that you can do different things with the delegate depending on what element was clicked:
@Matt Ball 非常接近这里的答案,但我会更清楚地补充一点,您可以根据单击的元素对委托执行不同的操作:
<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());
});
$('#saved-list').refresh('listview'); // jquery mobile list refresh
$('#saved-list').refresh('listview'); // jquery 手机列表刷新
Note that in the delegate this
is still referring to the li
that was clicked on.
请注意,在委托this
中仍然指的li
是被点击的。
回答by Grant Thomas
You could use the live
function, the downfall is that you might need some mechanism to determine exactly which of the li
items that have been clicked:
您可以使用该live
功能,但缺点是您可能需要某种机制来准确确定哪些li
项目已被单击:
$("#saved-list li").live('click', function() {
//act on click
});
回答by Bas Slagter
Isn't it enough to add this in (or after) your current loop?
将它添加到当前循环中(或之后)还不够吗?
$('#saved-list li').click(function(){ alert('hello'); });
$('#saved-list li').click(function(){ alert('hello'); });
回答by megakorre
hello phil in jquery you can create dom object without adding them as text to the dom. this will give you a chans to manipulate them before they are added (and after to).
hello phil 在 jquery 中,您可以创建 dom 对象,而无需将它们作为文本添加到 dom 中。这会给你一个 chans 在添加之前(和之后)操纵它们。
$("<li />")
.append(
$("<a />")
.attr("href" ,"#saved-route")
.text(this.text))
.click(function() {
// your click event
})
.appendTo("#saved-list");
回答by Erick Petrucelli
This is why bind
exists.
这就是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);
});
});
Also, this way is very easy to create different clicks for each item:
此外,这种方式很容易为每个项目创建不同的点击:
$("#saved-list li#item1").bind(...)
$("#saved-list li#item2").bind(...)
$("#saved-list li#item3").bind(...)
回答by epascarello
$.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);
});
回答by T. Stone
The .click
function will bind a click handler function to any given element. As the comments in your code mention you can use the ID or other means to select the item after it's been DOM-ized but another way to do this is simply to reference the variable that contains the element you want to bind.
该.click
函数将一个点击处理函数绑定到任何给定的元素。正如代码中的注释所提到的,您可以使用 ID 或其他方式在项目被 DOM 化后选择项目,但另一种方法是简单地引用包含要绑定的元素的变量。
Example:
例子:
var li = $('<li />');
li.click(function() { ... });
This is probably somewhat stylistic, but one of the features of jQuery is that it is chainable. This means that jQuery function calls always return a reference to the wrapped set of jQuery itself. Using the chainable aspect, you could re-write the above code like so:
这可能有点风格,但 jQuery 的特性之一是它是可链接的。这意味着 jQuery 函数调用总是返回对 jQuery 本身的包装集的引用。使用 chainable 方面,你可以像这样重写上面的代码:
var list = $('#saved-list'); $.each(all_objects, function(i, item) {{
list.append(
$('<li />')
.append(
$('<a />').text(item.text)
)
.click(function() { ... } );
);
});
回答by Domenic
Although I don't know what this $('#saved-list').refresh('listview')
business is about, the following might be what you're looking for:
虽然我不知道这项$('#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);
Note that we avoid appending to the DOM until the last minute, because appending is expensive.
请注意,我们避免在最后一分钟之前附加到 DOM,因为附加是昂贵的。
As other posters mention, using a delegated click handler is a better approach, generally. That would look something like
正如其他海报所提到的,一般来说,使用委托的点击处理程序是一种更好的方法。那看起来像
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.
});