Question

Using this code, if I change the dropdown list containing opt1/opt2 I get an alert showing the ID as 'drop'

If I clicking in the 'clickme' test entry box, this changes to a new dropdown, but when I change an option in that, there is no alert issued to tell me the ID.

<script language="javascript">
    $(document).ready(function() {
        $('#test').bind('click', function() {
            $(this).replaceWith('<select id="test" name="test"><option value="volvo">Volvo</option><option value="saab">Saab</option><option value="mercedes">Mercedes</option><option value="audi">Audi</option></select>');
        });

        $("select").change(function(event) {
            alert(this.id);
        });
    });
</script>

<form>
    <input id='test' name='test' type='text' value='ClickMe.'><br>
    <select id='drop' name='drop'>
        <option value='0'></option>
        <option value='1'>Opt1</option>
        <option value='2'>Opt2</option>
    </select><br>

    <input type='submit' value='submit'><br>

    <?php
        if (isset($_REQUEST['test'])) echo $_REQUEST['test'];
    ?>

Why can't I see the id of the new dropdown list ?

Thanks

Était-ce utile?

La solution

event delegation

$(document).ready(function () {

    $('#test').bind('click', function () {
        $(this).replaceWith('<select id="test" name="test"><option value="volvo">Volvo</option><option value="saab">Saab</option><option value="mercedes">Mercedes</option><option value="audi">Audi</option></select>');
    });

    $('form').on('change', 'select[name="test"]', function (event) {
        alert(this.id);
    });

});

Demo: Fiddle

When you use a normal event registration model, it will register the handlers directly to the targeted which are present in the dom at the point of the handler registration execution. So elements which are added later dynamically will not get those handlers.

The solution to this is to use event delegation, in this model the handler is registered to a ancestor element which will be present when the page is loaded with the a selector to filter out the source element. This makes use of event propagation - events happening in an element is propagated to all the ancestor elements(there are few exceptions like focus event). So an event happening in an element gets propagated to the ancestor element in one of them the handler is registered then the events source element(event.target) and its ancestors is matched against the selector passed as the second parameter, if it is satisfied then the handler is executed.

Autres conseils

When elements are inserted dynamically into the DOM (Document Object Model), for example using Ajax, then all event handlers have to be attached to parent elements. So for new items you need to apply .on to a parent element

$('form').on('change', "select", function(event) {
  alert(this.id);// by javascript
  // or
  alert($(this).attr("id");// by jquery
});

when this code is invoked:

$(this).replaceWith('VolvoSaabMercedesAudi');

it unbinds the select change event that is binded on document ready

Please use

$(document).on('change', 'select', function(event) {
    alert(this.id);
});

If you are using jQuery1.6 or under, use .live

$("select").live('change', function(event) {
    alert(this.id);
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top