0
        $('.catNameVal').on('hover', function() {
            notyId = $(this).attr("catnameid");
            $(this).append(' <a>Delete</a>');
            $(this).unbind('mouseenter mouseleave');
        });

For some reason the .on() method is not working. I have a textbox which adds new values to the DOM and the above code should be discovering those new DOM elements. I've had this problem before but just couldn't figure out the cause of it. Any suggestions? Also keep in mind .live() doesn't work either.

Michael Grigsby
  • 11,467
  • 9
  • 33
  • 52
  • please provide a fiddle. – honk31 Mar 12 '13 at 18:23
  • 2
    You need to use the delegated version of `.on()`. Pass a `selector` argument to `.on()`. – Matt Ball Mar 12 '13 at 18:23
  • Can you put an `alert` or something inside the function and check if it is being called? – Sudipta Chatterjee Mar 12 '13 at 18:23
  • *"the above code should be discovering those new DOM elements"*, no, you'd would have to call `.on` differently: http://api.jquery.com/on/. Also note that `"hover"` as event shorthand for `"mouseenter mouseleave"` is deprecated as of jQuery 1.8. – Felix Kling Mar 12 '13 at 18:23
  • Not a solution to your question but just an observation... instead of using your custom attribute of `catnameid`. I would sugesst using `data-` as outlined for HTML5 in [W3](http://www.w3.org/TR/2011/WD-html5-20110525/elements.html#embedding-custom-non-visible-data-with-the-data-attributes). Then you would call back `$(this).data('catnameid')` – dev Mar 12 '13 at 18:25

4 Answers4

3

If you are adding to the DOM, you need to use the delegated version.

$(document).on('hover', '.catNameVal', function() {
Eric J.
  • 147,927
  • 63
  • 340
  • 553
2

You're close, but the binding isn't dynamic in the way you think. What you're doing here:

$('.catNameVal').on('hover', function() {
    notyId = $(this).attr("catnameid");
    $(this).append(' <a>Delete</a>');
    $(this).unbind('mouseenter mouseleave');
});

Is using .on() to bind to all currently known matches to '.catNameVal', which won't discover new additions to the DOM after the fact. What you want to do is bind this to a universal parent DOM element to all of the additions. document is usually a safe choice, since everything is a child of that. Then you'd include in the binding the filter:

$(document).on('hover', '.catNameVal', function() {
    notyId = $(this).attr("catnameid");
    $(this).append(' <a>Delete</a>');
    $(this).unbind('mouseenter mouseleave');
});

What this does is bind the actual event to document but applies the selector of '.catNameVal' when evaluating the event. So all matching events which bubble up to document will be evaluated, checked against the filter, and executed if they match. This catches late-added DOM elements because they will still bubble up to document.

David
  • 208,112
  • 36
  • 198
  • 279
  • It still doesn't work – Michael Grigsby Mar 12 '13 at 18:29
  • @MichaelGrigsby: Define "doesn't work." Can you provide an example demonstrating this? – David Mar 12 '13 at 18:31
  • @MichaelGrigsby: Wait, is "hover" even an event? RuralJuror may be correct in his answer, so the code may indeed have two issues (the late binding and the event name). According to jQuery, their internal "hover" binding looks for "mouseenter" and "mouseleave": http://api.jquery.com/hover/ – David Mar 12 '13 at 18:34
  • When the new elements are added to the DOM the rewrite you provided still doesn't append Delete to the element. Also now Delete appears every time I hover over the pre-existing elements. I had this fixed before – Michael Grigsby Mar 12 '13 at 18:34
  • I've already changed hover to mousenter in your rewrite. I still get the same result as stated in my comment above – Michael Grigsby Mar 12 '13 at 18:35
  • @MichaelGrigsby: It looks like the `unbind` in your code might not be working as you expect either. It's being called on the matching element, but the event is actually bound to `document` (in order to catch late-added DOM elements), so it's not unbinding anything. There may be a better way overall to accomplish what you're trying to do. If you can provide a jsFiddle or some other working example that would help us see what's going on. – David Mar 12 '13 at 18:39
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/26053/discussion-between-michael-grigsby-and-david) – Michael Grigsby Mar 12 '13 at 18:40
1

Hover is not a standard event. You can't check for hover, it has to be mouseenter.

BBagi
  • 2,035
  • 1
  • 19
  • 23
-3

You need to call .on after the new element is created to re-bind the event handler. It does not discover new elements.

But this would defeat the purpose of .on which is to delegate the event to the handler. So the better solution is to setup the binding on the parent:

$('#catNameValParentNode').on('hover' ...

You get the idea. Then it will delegate the hover event and that handler to all the children of the element with id catNameValParentNode

Tutan Ramen
  • 1,234
  • 1
  • 8
  • 27