2012-01-08 116 views
2

我已經寫了一些javascript,當單擊一個元素時會打開一個元素。不過,我不能讓在JavaScript中e.target不能按我期望的那樣工作

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

這不是工作,我多麼希望這是因爲:

  1. 您可以打開顯示的元素不止一個時,我只想要一次一個開放。
  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); 

這有解決的第一個問題,但我仍然停留在如何使其在一個給定的時間內只有一個盒子是開放的。因此,當用戶登錄框打開並點擊currencyChanger時,我想讓登錄框關閉。

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

+0

請創建一個http://jsfiddle.net/演示。你的意思是說你只想一次顯示'signIn','shoppingBag','currencySelect'之一嗎?請記住,如果框中有元素並單擊它們,則「e.target」不會引用框,而是引用框中的元素。 – 2012-01-08 12:07:50

+0

http://jsfiddle.net/jamcoupe/9CEGw/ – jamcoupe 2012-01-08 12:14:12

+0

@FelixKling是的,如果'shoppingBag'被打開,然後我點擊'signIn'購物袋就會關閉。 – jamcoupe 2012-01-08 12:16:16

回答

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 
} 

您可以打開顯示的元素不止一個時,我只想要一個同時打開。

如果你想使三個對話框相互依賴,你必須保持一些共享狀態。我建議,不要有三個對話框,你可以有一個對話管理器,負責打開和關閉盒子。

例子:

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

我希望這給你一些想法。還有很多可以改進的地方,例如,現在,無論對話是否打開,管理員都會收聽每個事件。

相關問題