0

I was running some test popups by putting them into the HTML file manually and the JS function that I had to close them worked fine. However, when I add the popups dynamically, the closing function breaks and they are unable to be removed.

Here is the JS function that tells all popups in the .popup class to close when the .close button is clicked. The code also contains a hover function to switch the images out for the close button when the user hovers over it, that is also broken.

$('.popup').on('click', '.close', function() {
    $(this).closest('.popup').remove(); //or .hide() if you just want to hide the popup
});

$('img.close').hover(function () {
    this.src = '/engine/themes/img/popup.close.hover.png';
}, function () {
    this.src = '/engine/themes/img/popup.close.idle.png';
});

And here is my method of adding it to the DOM

var popupID = 'popup1';
// Create popup div
var popupHTML = '<div id="'+popupID+'" class="popup">'+
    '<div class="toolbar"><div id="title">Please Wait</div>'+
    '<img class="close" src="/engine/themes/img/popup.close.idle.png" alt="Close" title="Close" />'+
    '</div><p class="text">Loading...<p></div>';

$('body').append(popupHTML);

$.ajax({
    url: pageURL,
    cache: false,
    success: function(data) {
        var matches, pageTitle;

        matches = data.match(/<title>(.*?)<\/title>/);
        pageTitle = 'MERKD.COM';
        if ( typeof matches !== 'undefined' && matches != null ) {
            pageTitle = matches[1];
        }

        $('#'+popupID).html(strReplace('Loading...', data, $('#'+popupID).html()));
        $('#'+popupID).html(strReplace('Please Wait', pageTitle, $('#'+popupID).html()));
    } // end success call
}); // end ajax function

Note at the bottom I use a manually-written replacing method instead of just using $('#popup1 p').html('some text'); because when I do it that, it shows the text retrieved in data twice, anyone know why that is?

I'm lost as to why this stopped working when I added the popups dynamically, but surely I'm just overlooking something, because I also can't figure out why the text retrieved in data is displayed twice when I do a regular .html() or .text() jQuery call.

SISYN
  • 2,209
  • 5
  • 24
  • 45
  • Look up event delegation. It is the answer to your problem. – Jonny Sooter Sep 12 '13 at 21:25
  • 1
    possible duplicate of [Event binding on dynamically created elements?](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Jason P Sep 12 '13 at 21:26

1 Answers1

1

Try this:

var hovered;
$(document).on('mouseenter','img.close',function () {
    hovered = this;
    this.src = '/engine/themes/img/popup.close.hover.png';
});
$(document).on('mouseleave','img.close',function () {
    hovered.src = '/engine/themes/img/popup.close.idle.png';
});

Event handlers are bound only to the selected elements and they must exist already on the page at the time the code loads. Otherwise, to correct that, you can use event delegation and add the event handler to "something" that was already there, document is always a safe card.

Read more about .on()

EDIT:

I corrected my code, I actually realized that .on() and hover don't work together, so I adapted to a mouseenter & mouseleave instead. You can not use .hover() here anyway since you need to use delegation.

From jQuery's documentation:

Deprecated in jQuery 1.8, removed in 1.9: The name "hover" used as a shorthand for the string "mouseenter mouseleave". It attaches a single event handler for those two events, and the handler must examine event.type to determine whether the event is mouseenter or mouseleave. Do not confuse the "hover" pseudo-event-name with the .hover() method, which accepts one or two functions.

Sergio
  • 28,539
  • 11
  • 85
  • 132