简体   繁体   中英

Using jQuery .on() method doesn't work on dynamically created element

I am currently working on a website that has a logout button which gets dynamically inserted into a sidebar whenever the window reaches a certain size. When I click on the log out button I want to call the method logOut();

The ID of the anchor tag is "btnLogOut" everywhere(even checked it by searching in my IDE in case there are any invisible characters or something).

There is always only one log out anchor tag on every page. To be sure, I replaced "btnLogOut" with "btnLogOut_zq" everywhere and the error persisted.

I used setInterval(function(){ console.log($("#btnLogOut").length); },1); and this returns 1 constantly while resizing the window and making it bigger and then smaller and so on so the element is always present on the page.

Using .on() method to detect a click and then call logOut(); method

$(document).ready(function()
{
    $(document).on("click", "#btnLogOut", function()
    {
        logOut();
    });
});

This is what I use to take the original anchor tag and put it in the sidebar(Only the part that's relevant to the logout button):

$.fn.navList = function() {

    var $this = $(this);
        $a = $this.find('a'),
        b = [];

    $a.each(function() {

        var $this = $(this),
            indent = Math.max(0, $this.parents('li').length - 1),
            href = $this.attr('href'),
            target = $this.attr('target');
        if($a.attr("id") === "btnLogOut") {
            console.log($a);
            b.push(
                '<a ' +
                    'id="btnLogOut" ' + 
                    'class="link depth-' + indent + '"' +
                    ( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
                    ( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
                '>' +
                    $this.text() +
                '</a>'
            );
        }

    });

    return b.join('');

};
$(
    '<div id="navPanel">' +
        '<nav>' +
            $('#btns').navList() +
        '</nav>' +
    '</div>'
)

Creating elements by string does not "instantiate" them inside of the DOM . To get around this you would have to create the elements by means of the DOM's Javascript API (or serverside rendering of elements before the DOM loads, EG: an HTML file).

Although there are a few ways to do it, this is a good example with jQuery:

b.push(
    $('<a />', {id:"btnLogout", class: "link depth-1", target:"_BLANK", "href":"HTTP://", "text":$this.text()})
);

Assuming b is an existing array that'll be appended to another element or iterated over.

Learn more about creating elements the "correct" way on the Mozilla docs: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement

EDIT:

For your nesting further down:

$('<div />', {id: 'navPanel'}).append(
    $('<nav />', html: $("#btns").navList())
);

If you have access to ES6 then you can use Template Literals for this:

$(
    `<div id="navPanel">
        <nav>
            $($('#btns').navList())
        </nav>'
    </div>`
)

I'm not sure if the syntax will conflict with the jQuery shorthand dollar sign.

Just put:

$(document).on("click", "#btnLogOut", function()
{
   logOut();
});

Outside the $(document).ready

Careful, because by looking at your HTML page code, you have two times the ID #btnLogOut .

EDIT 1:

Take a look at this JSFiddle that I created in order to show you that even elements created on the fly have the onclick event attached.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM