16

Bootstrap Modal Events fire multiple times, or rather always one more time then before. I wrap the modal events in a click function that returns the modal id for now.

How can I make sure the event always only fires once, and only when the click function invoked it?

jQuery

$('.img-modal').on('click', function () {

// returns #modal-Id
var modalIdClicked = $(this).attr('data-target')
console.log ('modal id clicked from .img-modal = '+ modalIdClicked);

console.log ('.img-modal clicked');

    $(modalIdClicked).on('show.bs.modal', function(event) {

        console.log ( 'show.bs.modal');

    });    

});

Default Bootstrap 3.3.2 Modal HTML

<div class="col-md-7">
    <img class="img-modal img-responsive cursor-pointer" data-toggle="modal" data-target="#modal-1" src="www" alt="image">
</div>

<!--  Modal -->
<div class="modal fade top-space-0" id="modal-1" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-lg">
        <div class="modal-content cursor-pointer" data-toggle="modal" data-target="#modal-1">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="#modal-1">CLOSE &times;</button>
                <h1 class="modal-title">Modal Title</h1>
            </div>

            <div class="modal-body">
                <div class="img-center">
                    <img class="img-modal img-responsive" src="wwww" alt="image">
                </div>
            </div>

            <div class="modal-footer">
                <a href="#" class="btn btn-default" data-dismiss="modal">Close</a>
            </div>
        </div>
    </div>
</div>
<!--  Modal end -->

I did have a look at jQuery click events firing multiple times and Bootstrap 3 - Remotely loaded modal creates duplicate javascript events and it seems this can be achieved with the .off method.

So using $(modalIdClicked).off().on('show.bs.modal', function(event) { did the trick in this case.

Can someone please explain to me why this .off method is needed in this case exactly? I am having trouble understanding how the click is passed around.

Does the click reach the Bootstrap JS one more time with every click? Why does it fire the events multiple times without the .off method?

Thank you.

(I am trying to learn jQuery from a book, if any one out there really has a good book or even the one and only book to read about this, then please do shoot me a note, there is so many out there and all claim to be the best naturally.. thank you.)

lowtechsun
  • 1,915
  • 5
  • 27
  • 55

2 Answers2

12

Why does it fire the events multiple times without the .off method?

Because every time the element .img-modal is clicked, you are attaching a new event listener for the show.bs.modal event. This is why the event show.bs.modal is fired one more time on each click.

Can someone please explain to me why this .off method is needed in this case exactly?

The .off() method simply removes the previously attached event(s).


You don't need to use the .off() method.

Rather than attaching an event listener for the event show.bs.modal on each click event, you should just add a single event listener for all elements with class .modal:

Example Here

$('.modal').on('show.bs.modal', function (event) {
    console.log(this.id);
});

Within the show.bs.modal event listener, this is bound to the .modal element that is shown; therefore you can identify which modal is displayed. In the example above, this.id will be modal-1.

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • Great **explanation** and especially thank you for the **second** part of the answer!! I will have to wrap my mind around a few things in that part. Had the click listener on the `.img-modal` to find the clicked modal, also including traversing the dom with children and so on. This changes a lot if not everything of what I had planned to do with the modal events initially. Thank you, thank you & thank you! Self-taught or by book/school? If by book, **which** one please? A last time, thanks for the solid explanation!! – lowtechsun Mar 14 '15 at 21:07
  • @lowtechsun You're welcome--glad it helped. To answer your question, I'm self-taught. Stack Overflow has practically taught me everything I know. I started answering questions without much knowledge/experience; but after 1338 answer, I've learned a few things ;) For core JavaScript, I'd highly recommend ["JavaScript the Good Parts"](http://amzn.com/0596517742) (it's a heavy/in-depth read). The site [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript) is also excellent.. I haven't read any books on jQuery, I mainly refer to the [jQuery API documentation](http://api.jquery.com/). – Josh Crozier Mar 14 '15 at 21:13
  • You explained pretty well and it helped me to resolve my issues. Learning new stuff from stack overflow everyday. thx – Ajay Kumar Apr 02 '17 at 08:07
4
modal.off().on('show.bs.modal', function(){
    modalBody.load(remote_content);
});

On my case, I was facing multiple remote_loads. '.off()' helped me unbinding previously bound event to the target modal.

dineshsprabu
  • 165
  • 3
  • 4
  • $('.detail_status').on('change', function () { 'content here' }); was running several times. .off did the trick. Thanks. – Sinan Eldem May 19 '18 at 22:29