JQuery - attach an event to a dynamic element

I read the .on documentation, but there is an error in it.

Here is the HTML:

<a href="#" class="add-new">make new row</a> <ul> <li class="opts" > <select class="change" href="#" data-row="1"> <option>a</option> <option>b</option> <option>c</option> </select> </li> </ul> 

Here is the javascript:

  var index = 2; $('.add-new').on('click',function(e) { e.preventDefault(); $('.opts:first').clone(true).insertAfter('.opts:last'); $('.opts:last select').attr("data-row", index); index++; }); $(document).on('click', '.change', function(e) { e.preventDefault(); console.log($(this).data('row')); }); 

If I dynamically generate strings, the new elements work with the .on event.
But if the first element is changed and more new elements are added, new new ones will trigger an event.
Now they act as if they are the first element.

Here is an example: http://jsfiddle.net/BgAsY/2/
Add one or two lines, and then change any but the first. The console displays the correct number if they are changed.
Now add a few more lines and change these new ones. Everything is still fine, but now change the first selection, add more rows and then change these newest ones. Now the console always shows 1, as if it thinks that these newest lines are the first line.

What am I missing here?

+4
source share
2 answers

Change

 $(this).data('row') 

to

 $(this).attr('data-row') 

and seems to solve the problem.

Fiddle

+2
source

Replace console.log($(this).data('row')); to console.log($(this).attr('data-row'));

The cause of the problem:

  • When you execute $('.opts:first').clone(true) , the new cloned object transfers the data set to the original object using the data() method
  • Then you change the "data-row" attribute of the cloned element instead of changing its data via data() , so the data ("row") remains unchanged.
  • And when you click .change, you retrieve the data using the data () method, which returns the data (which has not been changed), and not the value of the attribute of the data row that you changed in the last step.

$ (elm) .data ('row') is not the same as $ (elm) .attr ('data-row')

Here is a working fiddle: http://jsfiddle.net/BgAsY/12/

0
source

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


All Articles