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

javascript - Detect click on "empty" area - Stack Overflow

programmeradmin2浏览0评论

Let's say we have next html/css: /

<div id="header">header</div>
<div id="content">
    <div class="actions">
        <div class="actions-row">
            <div class="action ">home</div>
            <div class="action ">search</div>
            <div class="action ">settings</div>
        </div>
        <div class="actions-row">
            <div class="action">...</div>
            <div class="action">...</div>
            <div class="action">...</div>
        </div>
    </div>
</div>
<div id="footer">footer</div>

What I need is to detect any clicks, which were made on an "empty" area. In provided fiddle, empty area would be everything, which has white or orange color.

Is there any technique/approach for doing this?

Let's say we have next html/css: http://jsfiddle/rbDKm/2/

<div id="header">header</div>
<div id="content">
    <div class="actions">
        <div class="actions-row">
            <div class="action ">home</div>
            <div class="action ">search</div>
            <div class="action ">settings</div>
        </div>
        <div class="actions-row">
            <div class="action">...</div>
            <div class="action">...</div>
            <div class="action">...</div>
        </div>
    </div>
</div>
<div id="footer">footer</div>

What I need is to detect any clicks, which were made on an "empty" area. In provided fiddle, empty area would be everything, which has white or orange color.

Is there any technique/approach for doing this?

Share Improve this question asked Nov 17, 2013 at 0:29 anonanon 3091 gold badge5 silver badges13 bronze badges 7
  • 1 Blacklist the unclickable areas or whitelist the clickable ones. – Shomz Commented Nov 17, 2013 at 0:36
  • "In provided fiddle, empty area would be everything, which has white or orange color." What are those areas? People shouldn't have to go to the fiddle to help you. – T.J. Crowder Commented Nov 17, 2013 at 0:37
  • 1 @T.J.Crowder Human brain (or at least mine) has a much worse HTML/CSS parsing/rendering capability than the machine and in some cases, such as this one, an image is indeed worth more than 1000 words. – Shomz Commented Nov 17, 2013 at 0:40
  • explain purpose of needing to target click on empty area – charlietfl Commented Nov 17, 2013 at 0:40
  • @Shomz: Then the image should be in the question. There's a reason we keep this stuff on-site. But it's much more likely to be useful to say what areas the clicks should be ignored for, as in my answer. – T.J. Crowder Commented Nov 17, 2013 at 0:46
 |  Show 2 more ments

2 Answers 2

Reset to default 5

With your markup as you have it now, I think that means you need to detect clicks outside of any div.action, #header or #footer.

To do that, you hook click on body, and then look at the path it took to get to body:

document.body.addEventListener("click", function(e) {
    var elm = e.target;
    while (elm !== document.body) {
        if (elm.id === "header" || elm.id === "footer") {
            return;
        }
        if (elm.tagName.toUpperCase() === "DIV" && /(?:^| )action(?:$| )/.test(elm.className)) {
            return;
        }
        elm = elm.parentNode;
    }
    // If we got here, it's on one of the desired areas
});

There are a couple of variations on that you could do. For instance, instead of className.match you could use classList on modern browsers. And modern browsers also offer Element#closest which you could use instead of the loop.

Alternately, you hook click on body and hook click on the relevant other elements and prevent the click from propagating:

function stopTheEvent(e) {
    e.stopPropagation();
}
document.body.addEventListener("click", function(e) {
    // It's one of the desired areas
});
var list = document.querySelectorAll("#header, #footer, div.action");
var index;
for (index = 0; index < list.length; ++index) {
    list[index].addEventListener("click", stopTheEvent);
}

...but that seems messier.


Note: In the above, I haven't allowed for IE8's lack of addEventListener. If you need to support IE8, look at attachEvent("onclick", ...) and use window.event.returnValue = false; to stop propagation (or use a library that abstracts these things away).

Use the "target" of the event, and check it's class/id

http://jsfiddle/yryQ6/

When you bind the click event, use the event, get the target and ask for it's class:

$('#content').on('click',function(e){
  if ($(e.target).hasClass('action')) {
    // click on an action
  } else {
    // click on smething that's not an action, in this case, action-row o actions, your empty area
  }
}

EDIT: assuming you use jquery, you should be able to use something similar with javascript events

发布评论

评论列表(0)

  1. 暂无评论