2012-01-08 16 views
2

要素をクリックすると要素を開くJavaScriptが書かれています。私は一度に一つのオープンをしたいときは、示された要素を複数開くことができJavaScriptでeTargetが期待通りに機能しない

  1. :しかし、私は

    var menu = document.getElementById(show); 
    if (menuOpen && e.target !== menu){...} 
    

    は、これは私がそれをしたいどのように動作しないことができません。

  2. 要素の内部をクリックすると閉じます。ボックスの外側をクリックした場合にのみ閉じます。

    function openBox(button, show){ 
        var menuOpen = false; //to toggle when the button is clicked. 
    
        // checks the whole document for clicks and then if the element is open it will > 
        // check to see if you have clicked away from it or not. 
        document.addEventListener("click", function(e){ 
         var menu = document.getElementById(show); 
         if (menuOpen && e.target !== menu){  // if elements open and the click event target does not match > 
          menu.style.display = "none";   // we will close it 
          menuOpen = false; 
         } 
        },false); 
    
        // add an event listner to the button element and then if its clicked stop any > 
        // links an stop bubbling and then change the display style. 
        document.getElementById(button).addEventListener("click", function(e){ 
         var menu = document.getElementById(show); 
         e.preventDefault(); 
         e.stopPropagation(); 
         if (menuOpen){ 
          menu.style.display = "none"; 
          menuOpen = false; 
         } else { 
          menu.style.display = "block"; 
          menuOpen = true; 
         } 
        },false); 
    } 
    openBox("signInButton", "signIn"); 
    openBox("bagButton", "shoppingBag"); 
    openBox("currencyButton", "currencySelect"); 
    

http://jsfiddle.net/jamcoupe/9CEGw/

編集:私はにコードを変更し @Felixクリングポスト後:

document.addEventListener("click", function(e){ 
    var menu = document.getElementById(show); 
    if (menuOpen && (e.target.parentNode !== menu) && (e.target !== menu)){  
     menu.className = "closedBoxes";  
     pointer = document.getElementById(arrow).className = "arrowE"; 
     menuOpen = false; 
    } 
    },false); 

これは、最初の問題を解決しているが、私はまだどのように貼り付けられています1つの時間に1つのボックスだけが開いているようにします。だから、ユーザーがサインインボックスを開いて、currencyChangerをクリックすると、サインインボックスがオフになります。私はそれが閉じ要素内をクリックする

http://jsfiddle.net/jamcoupe/kcF9Z/7/

+0

http://jsfiddle.net/デモを作成してください。一度に 'signIn'、' shoppingBag'、 'currencySelect'のどれかだけを表示したいと思っていますか?ボックスの中に要素があり、クリックされた場合、 'e.target'はボックスを参照するのではなく、その内部の要素を参照することに注意してください。 –

+0

http://jsfiddle.net/jamcoupe/9CEGw/ – jamcoupe

+0

@FelixKling「shoppingBag」が開いていて、その後、「signIn」ショッピングバッグをクリックしたときに閉じます。 – jamcoupe

答えて

1

、私は、彼らがボックスの外側をクリックした場合、それはクローズします。

私はすでにボックスが他の要素が含まれている場合は、その後、e.targetはボックス内のボックス自体ではなく要素を参照していない、私のコメントで言ったように。

クリックが外れているかどうかをテストするには、e.targetがボックス内の要素であるかボックス自体であるかをテストする必要があります。そのためには、DOMツリーをトラバースする必要があります。

例:私は一度に開いているものを欲しいとき

var target = e.target; 
while(target && target !== menu) { 
    target = target.parentNode; 
} 

if(!target) { 
    // click was outside of the box 
} 

あなたが示した要素を複数開くことができます。

3つのダイアログを互いに依存させたい場合は、いくつかの共有状態を維持する必要があります。私は、3つのダイアログを持つ代わりに、ボックスの開閉を担当する1つのダイアログマネージャを用意することをお勧めします。

例:

function DialogManager() { 
    this.dialogs_ = {}; 
    this.openedDialog_ = null; 

    this.init_(); 
} 

DialogManager.prototype.init_ = function(e) { 
    var self = this; 
    document.addEventListener('click', function(e) { 
     var id = e.target.id; 
     if(id && id in self.dialogs_) { // if one of the buttons was clicked. 
      self.openDialog(id);  // the dialog is opened (or closed) 
      return; 
     } 

     if(self.openedDialog_) { // if a dialog is currently open, we have to 
      var target = e.target; // close it if the click was outside 
      while(target && target.id !== self.openedDialog_) { 
       target = target.parentNode; 
      } 
      if(!target) { 
       self.closeDialog(self.openedDialog_); 
      } 
     } 
    }, false); 
}; 

DialogManager.prototype.registerDialog = function(button_id, dialog_id) { 
    this.dialogs_[button_id] = dialog_id; 
}; 

DialogManager.prototype.openDialog = function(id) { 
    var open_id = this.openedDialog_; 
    if(open_id) { 
     this.closeDialog(open_id); 
    } 
    if(id !== open_id) { 
     var dialog = document.getElementById(this.dialogs_[id]); 
     dialog.style.display = "block"; 
     this.openedDialog_ = id; 
    } 
}; 

DialogManager.prototype.closeDialog = function(id) { 
     var dialog = document.getElementById(this.dialogs_[id]); 
     dialog.style.display = "none"; 
     this.openedDialog_ = null; 
}; 

DEMO

私は、これはあなたにいくつかのアイデアを提供したいと考えています。ダイアログが開いているかどうかにかかわらず、マネージャはすべてclickイベントをリッスンするなど、改善できる項目はまだまだあります。

関連する問題