我试图重新创建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)
单击事件"以包含按钮中的所有元素以显示下拉列表。