1

I have run into a small issue when trying to attach event handlers to elements on a page.

The elements I am attaching the handlers too are dynamical created at runtime and some work with the events and some do not.

For example the following work well:

// Setup full screen button
fullscreenButton = document.createElement("img");
fullscreenButton.src = "/media/site-images/fullscreen.svg";
fullscreenButton.setAttribute("class", "fullscreenButton");

$(fullscreenButton).on("click", (function (video) {
    return function () {
        if (video.requestFullScreen) {
            video.requestFullScreen();
        } else if (video.webkitRequestFullScreen) {
            video.webkitRequestFullScreen();
        } else if (video.mozRequestFullScreen) {
            video.mozRequestFullScreen();
        }
    };
}(this)));

The video goes to fullscreen fine. However when I do something like this:

// Setup the div container for the video
videoContainer = document.createElement("div");
videoContainer.setAttribute("class", "videoContainer");
$(this).wrap(videoContainer);

// When the hover leaves, hide the controls
$(videoContainer).on("mouseleave", (function (controlsBox) {
    return function () {
        $(controlsBox).fadeTo(400, 0);
        $(controlsBox).clearQueue();
    };
}(controlsBox)));

// If the video itself is clicked, play/pause the video
$(videoContainer).on("click", (function (vid, playPauseButton) {
    return function () {
        playPause(vid, playPauseButton);
    };
}(this, playPauseButton)));

No event is fired.

I have read through and used links like .on() jquery not working to get around it with some success but I am confused as to the difference on why one dynamic element works with event handlers and other dont.

A JSfiddle to the whole shebang is here: http://jsfiddle.net/m4twG/1/ (obviously a work in progress)

Community
  • 1
  • 1
Doug Miller
  • 1,316
  • 4
  • 24
  • 46

2 Answers2

2

You need to use a delegated event handler to attach events to elements which are dynamically created after the DOM has loaded. Try this:

$(document)
    .on("mouseleave", '.videoContainer', (function (controlsBox) {
        return function () {
            $(controlsBox).fadeTo(400, 0);
            $(controlsBox).clearQueue();
        };
    }(controlsBox)))
    .on("click", '.videoContainer', (function (vid, playPauseButton) {
        return function () {
            playPause(vid, playPauseButton);
        };
    }(this, playPauseButton)));

Note, for best performance document should be changed to the closest static element which is available on DOM load.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • Why are the $(videoContainer).on... events considered dynamic and need a delegated handler and $(fullscreenButton).on... etc are not? The $(fullscreenButton).on and others are generated dynamically just like the $(videoContainer).on... but work. – Doug Miller Nov 09 '13 at 20:59
  • You've not shown the code where both of those elements are appended to the page so I can't give you a definite answer. My guess would be that `fullscreenButton` is appended before `document.ready` fires. – Rory McCrossan Nov 10 '13 at 10:20
0

Try like this

$('body').on("mouseleave", '.videoContainer',  (function (controlsBox) {
    return function () {
        $(controlsBox).fadeTo(400, 0);
        $(controlsBox).clearQueue();
    };
}(controlsBox)));
$('body').on("click", '.videoContainer', (function (vid, playPauseButton) {
    return function () {
        playPause(vid, playPauseButton);
    };
}(this, playPauseButton)));
Anil kumar
  • 4,107
  • 1
  • 21
  • 36