点击除某些元素以外的任何内容;e.目标不起作用..有时



我试图重新创建jQuery的本机event处理程序.click("body", "element, element", function( ... ));。如果用户单击这两个元素以外的任何内容,它将执行某些操作。

我已经成功地做到了这一点,但是,有时脚本不起作用。一段时间后,如果用户单击body,则实际的下拉按钮触发,它不会切换下拉列表的class。我不确定为什么会发生这种情况,因为它时不时地工作......

<小时 />

这是我的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
        }
    }
}

以及相应的 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 !-->
<小时 />我

包含一个 JsFiddle,以便您可以尝试重现我的问题。

非常感谢所有的帮助,
谢谢。

我尽可能

少地修改了你的代码。我希望这就是你要找的。

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>

由于您的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";
    }
}

这里似乎有几个问题。 我将类名重命名为更简单的单词并测试代码。 我发现,根据您的 CSS 以及您设置为 position:relative 和 position:absolute 的内容,下拉菜单div 必须在 user_...-outerdiv 内!

我将代码修改如下并对其进行测试。 它可以毫无问题地工作:

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>

编辑:使用"if (e.target == uButton || e.target.parentNode == uButton)单击事件"以包含按钮中的所有元素以显示下拉列表。

相关内容

最新更新