Add <li> element to <ul> and add click event for each?

I would like to add a series of <li> elements to <ul> and add a click event to each client.

I'm not sure how to do this, at least not in a neat, jQueryish way.

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 can anyone advise how to add a click event to each list item programmatically?

UPDATE: I need to do something a little different for each item in the list (let it just say a warning) - apologies for not understanding this.

+6
source share
10 answers

You are better off using .live() or .delegate() than worrying about creating .click() for every element you create. Something like that:

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

You only need to bind this listener once, and it will work for every <li> that is a descendant of the element with the id saved-list .


If you want to create a separate click handler for each <li> (I do not recommend this, though), here is a good way to do this:

 $.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); }); 
+14
source

Not.

Instead of binding a new event handler for each item (which can become quite expensive), associate one event handler with #saved-list , which is a common ancestor. The bubbling event means that ancestor elements are notified of events on their descendants, so you can handle events there, and not on the original element.

Something like that...

 $.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

+5
source

@Matt Ball is pretty close to the answer here, but I will add a bit more clearly that you can do different things with a delegate depending on which item was clicked:

 <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') update ('ListView'); // Update the list of mobile jquery

Note that in the delegate, this still refers to the li that was clicked.

+4
source

Is it enough to add this to (or after) the current loop?

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

+1
source

hello phil in jquery you can create a dom object without adding them to the text in dom. this will give you the ability to manipulate them before adding them (and after that).

 $("<li />") .append( $("<a />") .attr("href" ,"#saved-route") .text(this.text)) .click(function() { // your click event }) .appendTo("#saved-list"); 
+1
source

You can use the live function, the downfall is that you may need some kind of mechanism to determine exactly which li element was pressed:

 $("#saved-list li").live('click', function() { //act on click }); 
+1
source

That is why bind exists.

 $.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); }); }); 

In addition, it is thus very easy to create different clicks for each element:

 $("#saved-list li#item1").bind(...) $("#saved-list li#item2").bind(...) $("#saved-list li#item3").bind(...) 
0
source
 $.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
source

The .click function will .click the click handler function to any element. The comments on your code mention that you can use an identifier or other means to select an element after its DOM measurement, but another way to do this is to simply refer to the variable containing the element that you want to bind.

Example:

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

This is probably somewhat stylistic, but one of the features of jQuery is that it is chain-linked. This means that calls to the jQuery function always return a reference to the wrapped set of jQuery itself. Using a related aspect, you can rewrite the above code like this:

 var list = $('#saved-list'); $.each(all_objects, function(i, item) {{ list.append( $('<li />') .append( $('<a />').text(item.text) ) .click(function() { ... } ); ); }); 
0
source

Although I don't know what this $('#saved-list').refresh('listview') business is all about, the following may be required:

 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); 

Please note that we avoid adding to the DOM until the last minute, because adding is expensive.

As other posters note, using a delegated click handler is the best approach. It would look 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. }); 
0
source

Source: https://habr.com/ru/post/888910/


All Articles