简体   繁体   English

javascript-除某些元素外的onclick; e.target无法正常运作...有时

[英]javascript - onclick of anything but certain elements; e.target not working… sometimes

I have tried to recreate jQuery 's native event handler, .click("body", "element, element", function( ... )); 我试图重新创建jQuery的本机event处理程序.click("body", "element, element", function( ... )); . Where if the user clicks on anything but those two elements, it will do something. 如果用户单击除这两个元素以外的任何内容,它将执行某些操作。

I've successfully done this, however, sometimes the script will not work . 我已经成功完成了此操作,但是有时脚本无法正常工作 After a while, if the user clicks on the body , then the actual dropdown button trigger, it will not toggle the class for the dropdown. 稍后,如果用户单击body ,则实际的下拉按钮触发,它将不会切换下拉菜单的class I'm unsure why this is happening, because it is working every now and then... 我不确定为什么会这样,因为它不时在起作用...


This is my JavaScript : 这是我的JavaScript

var uButton = document.getElementById("user_content"), // the trigger
    uDropdown = document.getElementById("user__dropdown-menu"); // the menu

document.onclick = function(e){
    if(e.target == uButton){ // if button has been clicked
        toggleClass(uDropdown, "active"); // (custom function) toggle the class "active"
    } else if(e.target != uButton && e.target != uDropdown){ // if anything BUT the dropdown and button are clicked
        if(hasClass(uDropdown, "active")){ // (custom function) if the dropdown is active
            uDropdown.className = "user__procedural-outer-dropdown"; // reset the classes to default
        }
    }
}

And the corresponding HTML : 和相应的HTML

<div class="navigation__user-content" id="user_content"> <!-- the button !-->
    <span id="nav_username">Sign In</span>
    <div class="user__procedural-outer"></div>
</div>
<div class="user__procedural-outer-dropdown" id="user__dropdown-menu"></div> <!-- dropdown !-->

I've included a JsFiddle to so you can try and recreate my problem. 我附带了一个JsFiddle ,因此您可以尝试重新创建我的问题。

All help is greatly appreciated, 非常感谢所有帮助,
Thanks. 谢谢。

It seems there are several problems here. 看来这里有几个问题。 i renamed the class names to more simple words and test the code. 我将类名重命名为更简单的单词并测试了代码。 i found, based on your css and what you set as position:relative and position:absolute, the dropdown-menu div must be inside the user_...-outer div! 我发现,基于您的CSS以及您设置为position:relative和position:absolute的内容,下拉菜单div必须位于user _...- outer div内!

i revise the code as following and test it. 我将代码修改如下并对其进行测试。 it works without problem: 它可以正常工作:

 var uButton = document.getElementById("user_content"), uDropdown = document.getElementById("user-dropdown"); document.onclick = function (e) { if (e.target == uButton || e.target.parentNode == uButton) { toggleClass(uDropdown, "active"); } else if (e.target != uButton && e.target != uDropdown) { if (hasClass(uDropdown, "active")) { uDropdown.className = "user-dropdown"; } } } function hasClass(element, cls) { return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1; } function toggleClass(element, cls) { element.classList.toggle(cls); } 
 .user-content{ width: 70px; height: 15px; margin-top: 6px; padding: 8px; float: right; background: #730aa2; border-radius: 2px; cursor: pointer; } .user-content:hover{ box-shadow: inset 2px 2px 0 #200050; } .user-content > #signin{ display: inline-block; position: relative; top: -2px; left: 3px; font-size: 13px; font-weight: bold; color: #e6e6e6; } .user-content:hover > #signin{ text-shadow: 1px 1px 3px #caca30; } .user-outer{ float: right; position: relative; top: -2px; width: 17px; height: 17px; border-radius: 16px; background: yellow no-repeat center; background-size: cover; } .user-dropdown{ position: absolute; top: 43px; right: 0; width: 320px; height: 200px; /*background:#f8f8f8;*/ /* to see its position*/ visibility: hidden; /* hide when not active */ overflow: hidden; } .user-dropdown.active{ background: red; visibility:visible; } 
 <p>This is a test page!</p> <div id="user_content" class="user-content"> <span id="signin">Sign In</span> <div id="user-outer" class="user-outer"> <div id="user-dropdown" class="user-dropdown"></div> </div> </div> 

Edit: use if (e.target == uButton || e.target.parentNode == uButton) in click event to include all elements inside button to show the dropdown. 编辑:在点击事件中使用if (e.target == uButton || e.target.parentNode == uButton)将按钮内的所有元素都包括在内以显示下拉菜单。

since your nav_username is not in the user__procedural-outer , you need to target it also when document.onclick = function(e) happens 由于您的nav_username不在user__procedural-outer ,因此在document.onclick = function(e)发生时,也需要将其定位

function hasClass(element, cls) {
    return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
function toggleClass(element, cls){
    element.classList.toggle(cls);
}

var uButton = document.getElementById("user_content"),
    uButtonSpan = document.getElementById("nav_username"),
    /*since your "nav_username" is not in the "user__procedural-outer", you need to target it also when "document.onclick = function(e)" happens */
    uDropdown = document.getElementById("user__dropdown-menu");

document.onclick = function(e){
    if((e.target == uButton) || (e.target == uButtonSpan)){
        toggleClass(uDropdown, "active");
    } else if((e.target != uDropdown) && (e.target != uButtonSpan) && (hasClass(uDropdown, "active"))){
            uDropdown.className = "user__procedural-outer-dropdown";
    }
}

I modified your code as minimally as possible. 我尽可能少地修改了您的代码。 I hope this is what you're looking for. 我希望这是您要寻找的。

 function hasClass(element, cls) { return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1; } function toggleClass(element, cls){ element.classList.toggle(cls); } var uButton = document.getElementById("user_content"), // the trigger uDropdown = document.getElementById("user__dropdown-menu"); // the menu document.onclick = function(e){ var elem = e.target; do { switch(elem) { case uButton: return toggleClass(uDropdown, "active"); case uDropdown: return void(0); } } while(elem = elem.parentNode); if(hasClass(uDropdown, "active")) uDropdown.className = "user__procedural-outer-dropdown"; } 
 .navigation__user-content{ width: 70px; height: 15px; margin-top: 6px; padding: 8px; float: right; background: #730aa2; border-radius: 2px; cursor: pointer; } .navigation__user-content:hover{ box-shadow: inset 2px 2px 0px #5a0d91; } .navigation__user-content:hover #nav_username{ text-shadow: 2px 2px 0px #5a0d91; } .navigation__user-content > #nav_username{ display: inline-block; position: relative; top: -2px; left: 3px; font-size: 13px; font-weight: bold; color: #e6e6e6; } .user__procedural-outer{ float: right; position: relative; top: -2px; width: 17px; height: 17px; border-radius: 16px; background: url("noimagefound.png") no-repeat center; background-size: cover; } .user__procedural-outer-dropdown{ position: absolute; top: 43px; right: 0; width: 320px; height: 200px; overflow: hidden; } .user__procedural-outer-dropdown.active{ background: red; } 
 <div class="navigation__user-content" id="user_content"> <span id="nav_username">Sign In</span> <div class="user__procedural-outer"></div> </div> <div class="user__procedural-outer-dropdown" id="user__dropdown-menu"></div> 

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

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