简体   繁体   中英

Issue with javascript click event

I am creating a calendar application using javascript. The calendar view is displayed using javascript (dom element) for which I have created a common method and I call the same for displaying the updated calendar view. When I'm clicking on a particular date, I need to update the display of the calendar, but it's getting updated only once when the event of the update is triggered. I have created a similar demo and am providing the same below.

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script>
        $(document).ready(() => {
            this.show();

            for (let i = 0; i < 10; i++) {
                $('#li-' + i).click(() => {
                    alert(i);
                    this.show();
                });
            }
        });

        function show() {
            let elem = document.getElementById('body');
            elem.innerHTML = "";

            let ul = document.createElement('ul');
            for (let i = 0; i < 10; i++) {
                let li = document.createElement('li');
                let text = document.createTextNode(i);
                li.appendChild(text);
                li.setAttribute('id', 'li-' + i);
                li.style.cursor = 'pointer';
                ul.appendChild(li);
                elem.appendChild(ul);
            }
        }
    </script>
</head>
<body>
    <div id="body"></div>
</body>
</html>

On this example, when I click on a 'li' element the click event is triggered and the alert box is shown. Also, the 'show()' method gets invoked for updating the view. However, when the another 'li' element is clicked, the event is not getting triggered.

Side note: I would definitely refactor your code.

The problem: this.show() is actually redrawing the entire div whose id is body .

Redrawing the elements (and removing the previous existing ones) unregisters the click events, which are not automatically registered. In your current scenario, you register the events once , just after rendering them, but you don't register them again after rendering the div again.

The solution is to just register again the events, by moving the for inside the show function.

 $(document).ready(() => { this.show(); }); function show() { let elem = document.getElementById('body'); elem.innerHTML = ""; let ul = document.createElement('ul'); for (let i = 0; i < 10; i++) { let li = document.createElement('li'); let text = document.createTextNode(i); li.appendChild(text); li.setAttribute('id', 'li-' + i); li.style.cursor = 'pointer'; ul.appendChild(li); elem.appendChild(ul); } for (let i = 0; i < 10; i++) { $('#li-' + i).click(() => { alert(i); this.show(); }); } } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="body"> </div> 

When you are clicking on any element you are calling show() again so that DOM is getting created again and binding is getting cancelled So that you can bind to the document that ie if new DOM creates then it will automatically gets binded

    $(document).on("click", 'body #li-' + i, function(event){
         alert(i);
         this.show();
    }.bind(this));

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