Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript element body.onclick attatch event setTimeout

I want to make popup div that disappears when i click outside of it. I need pure js, not a jQuery or something. So i do the following...

function that make div to dissapear:

function closePopUps(){
    if(document.getElementById('contact-details-div'))
        document.getElementById('contact-details-div').style.display = 'none';
    //...same code further...
} 
function closePopUpsBody(e){
    //finding current target - http://www.quirksmode.org/js/events_properties.html#target
    var targ;
    if (!e) var e = window.event;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
        targ = targ.parentNode;

    //is we inside div?    
    while (targ.parentNode) {
        //filtering "Close" button inside div
        if (targ.className && targ.className == 'closebtn')
            break;
        if (targ.className && targ.className == 'contact-profile-popup')
            break;
        targ = targ.parentNode;
    }
    //if it not a div, or close button, hide all divs and remove event handler
    if ((targ.className && targ.className == 'closebtn')
        || !(targ.className && targ.className == 'contact-profile-popup')) {
        if(document.getElementById('contact-details-div'))
            document.getElementById('contact-details-div').style.display = 'none';
        //...some more code here...

        document.body.onclick = null;
    }
}

maybe this code is ugly, but this not a main problem...

main problem is when i attach an event to body, it executes immediately! and div dissapears immediately, i even don't see it.

<tr onclick="
closePopUps();
document.getElementById('contact-details-div').style.display='block';
document.body.onclick = closePopUpsBody;
return false;">

i though if i don't use parentheses, it will not executes?

document.body.onclick = closePopUpsBody(); //this executes
document.body.onclick = function(){closePopUpsBody()}; //this is not
document.body.onclick = closePopUpsBody; //this is not

finally i finished with this decision

<tr onclick="
closePopUps();
document.getElementById('contact-details-div').style.display='block';
setTimeout('document.body.onclick = closePopUpsBody;', 500);
return false;">

but i think this is madness. so, what i am doing wrong?

like image 299
llamerr Avatar asked Nov 30 '25 17:11

llamerr


2 Answers

You should stop event bubbling. Simple [demo]

var box = document.getElementById('box');
var close = document.getElementById('close');

// click on a box does nothing
box.onclick = function (e) {
  e = e || window.event;
  e.cancelBubble = true;
  if (e.stopPropagation)
    e.stopPropagation();
}

// click everywhere else closes the box
function close_box() {
  if (box) box.style.display = "none";
}

close.onclick = document.onclick = close_box;
like image 98
25 revs, 4 users 83% Avatar answered Dec 02 '25 06:12

25 revs, 4 users 83%


Usually events are propagated to the parents. If you click on a <div>, then <body> also will have its onClick called.

The first thing is: debug the order of called functions: place window.dump("I am called!") kind of things in your handlers.

I suppose you need to call event.stopPropagation() somewhere in your code. (See https://developer.mozilla.org/en/DOM/event )

About the parentheses question:

document.body.onclick = closePopUpsBody;//this is not
document.body.onclick = closePopUpsBody();//this executes

This executes, because you are calling a function closePopUpsBody() to return a value which will be assigned to the onclick property. In JavaScript the function name represents the function object (as any other variable). If you place parentheses after a variable name, then you say: 'execute it for me, as a function`.

like image 37
Arsen7 Avatar answered Dec 02 '25 05:12

Arsen7



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!