2010-11-24 6 views
3

Je veux faire un popup div qui disparaît quand je clique à l'extérieur. J'ai besoin de js purs, pas de jQuery ou de quelque chose. donc je fais ce qui suit ...javascript élément body.onclick attatch event setTimeout

fonction qui font div 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; 
    } 
} 

peut-être ce code est laid, mais pas un problème principal ...

principal problème est quand j'attache un événement au corps, il s'exécute immédiatement! et div disparaît immédiatement, je ne le vois même pas.

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

Je pense que si je n'utilise pas de parenthèses, il ne s'exécutera pas?

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

enfin j'ai fini avec cette décision

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

mais je pense que c'est de la folie. alors, qu'est-ce que je fais mal?

+0

Pouvez-vous donner un lien vers un exemple en direct, ou mieux, un jsfiddle? 'document.body.onclick = closePopUpsBody' devrait fonctionner comme prévu. –

+0

Lorsque vous avez 'document.body.onclick = closePopUpsBody', que se passe-t-il exactement lorsque vous cliquez? Vous obtenez une erreur? –

+0

merci pour les réponses, vous avez tous eu raison - problème en l'absence de stopPropagation en tr inline onclick code – llamerr

Répondre

3

Vous devez arrêter les bulles d'événements. 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; 
1

Voici un exemple complet de la façon dont vous pourriez accomplir cela.

<html xmlns="http://www.w3.org/1999/xhtml" > 
<head> 
    <title></title> 
    <style> 
     body { font-family: Tahoma; font-size: 1.1em; background: #666666; color: White; } 
     #layer01 { border: 1px solid black; width: 200px; height: 100px; position: absolute; 
        top: 100px; left: 100px; background: white; padding: 10px; color: Black; 
        display: block; } 
    </style> 
</head> 
<body> 
    Click anywhere outside the layer to hide it. 

    <div id="layer01"> Test Layer </div> 

    <script type="text/javascript"> 
     isIE = (window.ActiveXObject) ? true : false; 

     document.onclick = function (e) { 
      var l = document.getElementById("layer01"); 

      if (!isIE && e.originalTarget == l) 
       e.stopPropagation(); 
      else if (isIE && event.srcElement == l) 
       event.cancelBubble = true; 
      else 
       l.style.display = "none"; 
     } 

    </script> 
</body> 
</html> 
2

Habituellement, les événements sont propagés aux parents. Si vous cliquez sur un <div>, puis <body> aura également son onClick appelé.

La première chose à faire est: déboguer l'ordre des fonctions appelées: placez window.dump("I am called!") sortes de choses dans vos gestionnaires.

Je suppose que vous devez appeler event.stopPropagation() quelque part dans votre code. (Voir https://developer.mozilla.org/en/DOM/event)

A propos de la question entre parenthèses:

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

Cette exécute, parce que vous appelez un pour renvoyer une valeur closePopUpsBody de fonction() qui sera affecté à la propriété onclick. En JavaScript, le nom de la fonction représente l'objet de la fonction (comme toute autre variable). Si vous placez des parenthèses après un nom de variable, alors vous dites: "exécutez-le pour moi, en tant que fonction".