Question

I'm trying to replace one element with another. It works only once, then when I try to click the element .two again, it doesn't call the function.

This is the code, its wrapped around a django for loop. That's why I need to use $(this):

<div class = "galery">

{% for image in images %}

<img class = 'one' src = "http://www.fmscout.com/datas/avatars/48327-chelsea-logo.jpg">
<span class='glyphicon glyphicon-certificate two'></span>

{% endfor %}

</div>

<script>
$('.two').on('click', change_content);

function change_content(){
    var one = $('.galery').find('.one')
    $(this).replaceWith("<img class = 'one' src ='http://www.fmscout.com/datas/avatars/48327-chelsea-logo.jpg'>")
    one.replaceWith("<span class='glyphicon glyphicon-certificate two'></span>")
}

</script>
Was it helpful?

Solution

It's because the new .two is added dynamically, but the click handler has already been attached to existing .two divs, before the new one exists. You need to attach the handler to an element that will always exist, and then use that to handle clicks to child elements. This is called event delegation. In jQuery it would be done like this:

$('.galery').on('click', '.two', change_content);

So, .galery responds to all click to it and its children, and if the click target matches the selector in the on() call (.two), it will call the handler function.

OTHER TIPS

Since you've used .replaceWith(), the span with class two has been added dynamically to the DOM so all the events will not be available until you attach them to this span.

In this case, You can make use of event delegation:

Event delegation allows us to attach a single event listener, to a parent element, that will fire for all children matching a selector, whether those children exist now or are added in the future.

$('.galery').on('click', '.two', change_content);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top