0
votes

we're using jQuery 1.7.1 and we're going to upgrade after removing deprecated live() functions. I've been reading many questions here and at other places about the differences between live() and on(). However, I do not understand why in my particular case on() cannot take a certain (static) element for the event listener binding. According to the docs and other places, it's ideal to bind as close to your event target as reasonably possible, even though "document" works in all cases.

First, I am not changing the DOM. I am not adding or removing elements, which was a common problem in most questions. Everyone involved is there onload.

Second, this is a basic (psuedo-code!) version of our HTML:

<div.container>
    ...
    <ul>
        <li>
            <div.a_static_parent>
                <form method="post" action="call_a_python_func">...
                    <input.a_static_child>
                    <submit /> ...</form>
                 ...non-form stuff...
            </div>
        </li>
        ...x however many items...
    </ul>
</div>

What our code was actually doing was checking if two values were the same or different, and depending on that, setting the submit button to disabled or not (it could have been changing colour or alerting 'FOO!' though, same issue). This is a POST-only form, not POST-REDIRECT-GET; there is no page refresh. We're merely updating a value in the back.

Our old, working jQuery code using live():

$('.a_static_child').live('change blur',  function() {
    //alert('FOO!'); and other non-DOM-changing things      
});

Our new, works-once-per-page-load jQuery code using on():

$('.a_static_parent').on('change blur', '.a_static_child', function() {
    //alert('FOO!'); and other non-DOM-changing things      
});

Works all the time, regardless:

$(document).on('change blur', '.a_static_child', function() {
    //alert('FOO!'); and other non-DOM-changing things      
});

In the middle case, the events fire until I hit the submit button. After that, with on() but not with live(), no further events will fire in that form (and this is true for each individual form on the page) until I refresh the page. Moving the handler out to .container or document fixes this, but since the form submit isn't changing the DOM in any way, I don't understand why I need to go that far away.

I wanted to move the event closer to the actual target. .a_static_child is always in .a_static_parent but not always in .container, as this form also shows up in dialogs and frames and whatnot.

Can someone explain how hitting submit is turning off events when I use on(), if that's indeed the case? Or what is happening? I can post more code if needed but I was hoping to stick to the basics.

1
Most likely you replace/reload the .a_static_parent elements so you lose all events attached to them. - JJJ
We don't replace any elements. Nothing is removed. - stommepoes
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live(). Please refer to the jQuery API Documentation for more info. - Wim Ombelets
I read the API. If you know where it explains why hitting a submit button changes it, that's exactly what I am looking for. - stommepoes
FYI, .live binds the event handler to document, so the equivalent .on version would also bind the event handler to document. There is no situation where .live works but .on doesn't. So, the actual question is, I guess: What messes with .a_static_parent? - Felix Kling

1 Answers

1
votes

I've just replicated your code and actually got it working, so it must be an outside issue. Here's your working code: http://jsfiddle.net/MGrwb/1/

<div>   
    <ul>
        <li>
            <div id="a_static_parent">
                <form method="post">
                    <input id="a_static_child" />
                    <button id="testButton">Test</button>
                 </form>
            </div>
        </li>
    </ul>
</div>

$(document).on('change, blur', '#a_static_child', function() {
    alert('FOO!');// and other non-DOM-changing things      
});

$('#testButton').click(function(e) {
   $('form').submit();
});

$('form').submit(function (evt) {
    evt.preventDefault();  
});