jQuery - How to make .on event work for dynamically created HTML?

旧时模样 提交于 2020-02-02 15:33:06

问题


Reading up on the New specs for the newest jQuery 1.x library, it says to use .on to attach events that work for dynamically created jQuery elements, however, I can't seem to get this work at all. In my $(document).ready function I have the following:

jQuery:

$(".dropdown").on("click", function(event) {
    event.preventDefault();
    var type = $(this).text() == '[ Read more... ]' ? 'expand' : 'collapse';
    var theDiv = type == 'expand' ? $(this).parent().next("div") : $(this).parent().prev("div");
    var theId = $(this).attr("id");
    $(this).parent().remove();
    var vText = theId == 'reqMat' ? 'Every candidate is required to submit a headshot and candidate statement.' : 'To strengthen your candidacy and let people know what you\'re all about, we invite you to create a campaign video.';

    theDiv.animate({height: 'toggle'}, 500, function(){
        if (type == 'expand')
            theDiv.after('<p class="desc"><a href="#" class="dropdown" id="' + theId + '">[ Collapse Information... ]</a></p>');
        else
            theDiv.before('<p class="desc">' + vText + ' <a href="#" class="dropdown" id="' + theId + '">[ Read more... ]</p>');

        if (theId == 'optMat' && type == 'expand')
        {
            var sVidWidth = $("#sampleVideo").width();
            $("#sampleVideo").css({'height': (sVidWidth/1.5) + 'px'});
        }
        else if (theId == 'optMat' && type == 'collapse')
        {
            var iframe = $('#sampleVideo')[0];
            var player = $f(iframe);
            player.api('pause');
        }

        if (theId == 'reqMat' && type == 'expand')
        {
            handleBullets();
        }
    });
});

Ok, so this will drop down the [ Read more... ] text and turn it into a [ Collapse Information... ] string that will go underneath of the actual content that is being expanded. But when I click on the [ Collapse Information... ] text, it doesn't collapse anything, instead it goes to the top of the page, thus having an href="#", but using .on should prevent that from happening when the event.preventDefault(); is applied correct??

Am using the jQuery library found here: <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

My HTML is laid out like so, if this even matters:

<h4>Header 1</h4>
<p class="desc">Brief description. <a href="#" id="reqMat" class="dropdown">[ Read more... ]</a></p>
<div style="display: none;">
    <p>More information is in here...</p>
</div>
<h4>Header 2</h4>
<p class="desc">Brief description. <a href="#" id="optMat" class="dropdown">[ Read more... ]</a></p>
<div style="display: none;">
    <p>More information is in here...</p>
</div>

The first time I click it, it works, but the 2nd time, when [ Collapse Information... ] is shown it doesn't work at all. So it is not attaching itself to the dynamically created <p class="desc"><a href="#" class="dropdown" id="' + theId + '">[ Collapse Information... ]</a></p>.

Why not? Is there something else I should be using instead of .on? I know that .live is no longer used since jQuery 1.7. .click will not work either as I have already tried that as well. What other options are there?


回答1:


To get the on method to register a delegate event handler (just as the delegate method does), you need to specify a selector for the element, and apply it to an element that already exist.

For example:

$("body").on("click", ".dropdown", function(event) {

Preferably, you should apply it to a parent element as close as possible to the dynamically added elements rather than "body", to reduce the scope as much as possible. Otherwise the selector ".dropdown" needs to be evaluated for every click that happens in the page. Typically you would use the containing element that you add the dynamic content to.



来源:https://stackoverflow.com/questions/17777884/jquery-how-to-make-on-event-work-for-dynamically-created-html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!