最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Attach event handlers for click event on all elements in the DOM - Stack Overflow

programmeradmin4浏览0评论

I want to be able to figure out which part of my page has been clicked. There is no guarantee the elements are all on the page from the get go, which means that I need to use something like jQuery delegate.

One way to do this is to iterate through all elements in the DOM and then attach an event handler to each element - but this will be slow and complicated - every time new html is dynamically added, I'd have to either re-attach all the handlers, or figure out the subset of html that was added.

The other way is to use event bubbling - so add an event handler to the document, or body and rely upon the events bubbling up.

Something like this:

$('body').delegate('div', 'click', function(e){
    dummyId++;
    console.log(e);
    console.log(e.currentTarget);
    console.log("=====");

});

However, after using this code, when I click on buttons on my page, I get the div surrounding the button, as opposed to the actual button. In other words, the above is too specific. Furthermore, I feel like the original selector should be the document, rather than the body tag.

To be clear, I want to know when any element is clicked on my page - how do I do that?

So I tried this code with .on:

$(document).on('click', function(e){
    console.log("EVENT DUMMY ID");

    console.log(e.target);
    console.log("=====");

});

However, when I click on buttons in my app, nothing gets triggered - when I click on other elements, the console logs run.

I understand this is probably hard to answer without more context - what else do you need?

I want to be able to figure out which part of my page has been clicked. There is no guarantee the elements are all on the page from the get go, which means that I need to use something like jQuery delegate.

One way to do this is to iterate through all elements in the DOM and then attach an event handler to each element - but this will be slow and complicated - every time new html is dynamically added, I'd have to either re-attach all the handlers, or figure out the subset of html that was added.

The other way is to use event bubbling - so add an event handler to the document, or body and rely upon the events bubbling up.

Something like this:

$('body').delegate('div', 'click', function(e){
    dummyId++;
    console.log(e);
    console.log(e.currentTarget);
    console.log("=====");

});

However, after using this code, when I click on buttons on my page, I get the div surrounding the button, as opposed to the actual button. In other words, the above is too specific. Furthermore, I feel like the original selector should be the document, rather than the body tag.

To be clear, I want to know when any element is clicked on my page - how do I do that?

So I tried this code with .on:

$(document).on('click', function(e){
    console.log("EVENT DUMMY ID");

    console.log(e.target);
    console.log("=====");

});

However, when I click on buttons in my app, nothing gets triggered - when I click on other elements, the console logs run.

I understand this is probably hard to answer without more context - what else do you need?

Share Improve this question edited Aug 22, 2021 at 13:51 Brian Tompsett - 汤莱恩 5,88372 gold badges61 silver badges133 bronze badges asked Mar 27, 2014 at 22:34 praks5432praks5432 7,79232 gold badges93 silver badges158 bronze badges 13
  • 1 Don't use selector-based delegation. Just bind a handler to the document, and check the e.target. That'll be the most deeply clicked element. $(document).on("click", function(e) { console.log(e.target.nodeName); }) – cookie monster Commented Mar 27, 2014 at 22:35
  • on cannot work - I dynamically append html elements – praks5432 Commented Mar 27, 2014 at 22:37
  • 1 Before you say it can't work, try it. There's no reason it won't work for dynamically created elements, assuming I've understood you correctly that you want the most deeply clicked element. – cookie monster Commented Mar 27, 2014 at 22:38
  • 1 I have tried it - api.jquery.com/on - also backs me up - "Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on()." – praks5432 Commented Mar 27, 2014 at 22:39
  • 1 cookie monster's code will work, precisely because he's binding to the document - an element that is present from the start - and only when in the callback interrogating the actual element that invoked the event, be it one that was there from the start or added later. – Mitya Commented Mar 27, 2014 at 22:39
 |  Show 8 more comments

5 Answers 5

Reset to default 16

currentTarget returns the node to which the event has bubbled (if at all). Instead, interrogate target, so:

Vanilla:

document.addEventListener('click', function(evt) {
    alert(evt.target.tagName);
}, false);

jQuery:

$(document).on('click', function(evt) {
    alert(evt.target.tagName);
});

http://jsfiddle.net/qsbdr/

Just Do this:

var listener = function handleClick(event){
    element = event.target
    console.log(element) 
    }

var body = document.body
body.addEventListener('click', listener, true);

This will print the element clicked on the DOM.

I faced the same type of problem to find out which element is clicked on the navbar. I was working in animation slide. So, To solve it, I try to handling all the events of <ul>

TO BE NOTED: This is just for a piece of block. Not entire webpage.

Here is my reactjs code. Concept is same.

jsx

        <ul className="right" onClick={setRainbow}>
            <li><Link to="/">Home</Link></li>
            <li><NavLink to="/about">About</NavLink></li>
            <li><NavLink to="/contact">Contact</NavLink></li>
        </ul>

function

    const setRainbow = (e) => {
            console.log(e.target)
            console.log(e.target.href)
            console.log(e.target.text)
        if (e.target.text === 'About') {
            // to do
        } else {
            // to do
        }
    }

Try this:

$(document).on('click', function(e) {
   // now use e.target here
});

You can also kill the bubbling on the click event by using e.stopPropagation()

I don't see any need to use jQuery for something like this, though my suggestion does rely on MutationEvents, which I understand are to be replaced.

You can get notified upon the insertion of any new node into the DOM. In the callback that fires, you can trivially attach an onclick handler to the new node. I've only handled the case where new nodes are added.

<!DOCTYPE html>
<html>
<head>
<script>
window.addEventListener('load', onDocLoaded, false);

function onDocLoaded()
{
    window.addEventListener('DOMNodeInserted', onNodeInserted, false);
    document.body.appendChild( newEl('div') );
}

function onNodeInserted(evt)
{
    evt.srcElement.addEventListener('click', onNodeClicked, false);
}

function onNodeClicked()
{
    document.body.appendChild( newEl('div') );
}
</script>
<style>
div
{
    border: solid 1px red;
    padding: 8px;
    margin: 4px;
    display: inline-block;
}
</style>
</head>
<body>
</body>
</html>
发布评论

评论列表(0)

  1. 暂无评论