简体   繁体   English

在JavaScript中e.target无法正常工作

[英]In JavaScript e.target is not working as I expected

I have written some javascript that opens an element when an element is clicked. 我已经编写了一些JavaScript,可在单击某个元素时打开一个元素。 However I can't get the 但是我不能

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

This is not working to how I want it because: 这不适用于我想要的方式,因为:

  1. You can open more than one of the showed elements when I only want one open at a time. 当我一次只想打开一个时,可以打开多个显示的元素。
  2. When I click inside the element it closes, I only want it to close if they have clicked outside the box. 当我在元素内部单击时,它关闭了,我只希望它们在框外单击时关闭。

     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/ http://jsfiddle.net/jamcoupe/9CEGw/

Edit: After @Felix Kling post I changed the code to: 编辑:@Felix Kling发布后,我将代码更改为:

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);

this has solve the first problem but I am still stuck on how to make it so that only one box is ever open at one giving time. 这已经解决了第一个问题,但是我仍然坚持如何制作它,以便一次给定的时间只能打开一个盒子。 So when a user has signIn box open and clicks on currencyChanger I want the signIn box to be off. 因此,当用户打开登录框并单击currencyChanger时,我希望关闭登录框。

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

When I click inside the element it closes, I only want it to close if they have clicked outside the box. 当我在元素内部单击时,它关闭了,我只希望它们在框外单击时关闭。

As I already said in my comment, if the box contains other elements, then e.target does not refer to the box itself but to the element within the box. 正如我在评论中已经说过的,如果该框包含其他元素,则e.target并不引用该框本身,而是引用该框内的元素。

So in order to test whether the click was outside or not, you have to test whether e.target is an element within the box or the box itself. 因此,为了测试单击是否在外部,必须测试e.target是框内的元素还是框本身。 For that, you have to traverse the DOM tree. 为此,您必须遍历DOM树。

Example: 例:

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

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

You can open more than one of the showed elements when I only want one open at a time. 当我一次只想打开一个时,可以打开多个显示的元素。

If you want to make the three dialogs dependent on each other, you have to maintain some shared state. 如果要使三个对话框相互依赖,则必须维护一些共享状态。 I'd suggest, instead of having three dialogs, you can have one dialog manager which takes care of opening and closing the boxes. 我建议您不要使用三个对话框,而可以使用一个对话框管理器来负责打开和关闭框。

Example: 例:

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 DEMO

I hope this gives you some idea. 我希望这能给您一些想法。 There is still a lot which can be improved, for example, now the manager listens to every click event, no matter whether a dialog is open or not. 还有很多可以改进的地方,例如,不管对话框是否打开,现在经理都监听每个click事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM