Javascript js行导致上面的代码不执行
这是一支笔,上面有完整的html: 我正在编写两个函数——一个用于显示隐藏内容,另一个用于隐藏内容。我希望show()函数在父div上执行,hide()函数在div上使用选择器Javascript js行导致上面的代码不执行,javascript,html,css,Javascript,Html,Css,这是一支笔,上面有完整的html: 我正在编写两个函数——一个用于显示隐藏内容,另一个用于隐藏内容。我希望show()函数在父div上执行,hide()函数在div上使用选择器执行。单击text 但是,我正在打开。请从“显示”中单击“文本”“隐藏”,这样我就不希望“隐藏”功能始终保留在文本上。我还希望它的交互文本在更改为隐藏函数时明显可见,因此我将其设置为链接 这很好,但是当尝试将父对象的onclickAttr设置回show()函数时,隐藏块中的任何内容都不会执行 如果删除父级的onclickA
执行。单击text
但是,我正在打开。请从“显示”中单击“文本”
“隐藏”,这样我就不希望“隐藏”功能始终保留在文本上。我还希望它的交互文本在更改为隐藏函数时明显可见,因此我将其设置为链接
这很好,但是当尝试将父对象的onclick
Attr设置回show()
函数时,隐藏块中的任何内容都不会执行
如果删除父级的onclick
Attr的行设置,脚本将按预期执行。如果我设置另一个元素的onclick Attr,脚本将按预期执行
但是,如果有这一行,就不会发生任何事情,控制台中也没有指示错误的输出。我甚至用元素类型和类名设置了一个警报,以确保我的目标是正确的元素
获取元素匹配选择器的最近父级:
var getClosest = function (element, selector) {
for ( ; element && element !== document; element = element.parentNode ) {
if ( element.matches(selector) ) return element;
}
return null;
}
显示隐藏元素ul.服务类别菜单
function show(elem) {
var menu = elem.querySelector("ul.service-category-menu"),
click = elem.querySelector(".click-text"),
parent = getClosest(elem, '.service-category');
;
if (menu.style.display === "none" || menu.style.display === "") {
menu.style.display = "block";
click.innerHTML = "<a href=\"#\">Click to Hide<\/a>";
click.setAttribute('onclick','hide(this);');
elem.setAttribute('onclick', 'null');
}
}
它被执行,就在您单击
单击以隐藏
之后,事件继续到父级,并且父级的事件处理程序被执行。因此,在调用hide()
在javascript中,它通常称为气泡(当您单击子对象时,父对象的单击处理程序也将在子对象的单击处理程序完成后执行)
因此,对于解决方案,您可以在hide()
函数的末尾添加这一行
event.stopPropagation();
要阻止事件继续发生在父级设置事件。其他答案中提到的stopPropagation
可能会解决您的问题。或者,您可以将hide
函数的最后一行更改为window.setTimeout(e=>parent.setAttribute('onclick','show(this)),0)
现在发生的是:
你点击
它执行hide
函数,并在该函数期间将单击事件绑定到父级
单击会传播到父级并执行新绑定的函数,重新显示内容
通过使用setTimeout(fn,0)
,您可以确保在函数绑定到父函数之前完成单击事件。首先,我必须承认我反对使用onclick
属性。如果您没有使用VueJS或React之类的框架,我认为HTML和JS应该保持分离,以便更好地控制和维护
您可以使用addEventListener
、removeEventListener
和e.stopPropagation()
来避免触发多个事件处理程序
活动分为两个阶段:
- 事件捕获:事件从
文档
一直传播到目标元素
- 要在此阶段捕获事件,请执行以下操作:
elm.addEventListener('click', myFunc, true);
elm.addEventListener('click', myFunc, false); /* or just omit the 3rd param */
- 事件冒泡:事件从目标反弹到
文档
- 要在此阶段捕获事件,请执行以下操作:
elm.addEventListener('click', myFunc, true);
elm.addEventListener('click', myFunc, false); /* or just omit the 3rd param */
使用e.stopPropagation()
可以断开该链条
//当DOM就绪时
addEventListener(“DOMContentLoaded”,init);
函数init(){
//获取所有类别
var$categories=document.queryselectoral(“服务类别”);
//对他们每个人来说
数组.from($categories).forEach(函数($categority){
//为单击添加事件侦听器
$category.addEventListener(“单击”,显示);
});
}
函数getClosest(元素、选择器){
for(;element&&element!==document;element=element.parentNode){
if(element.matches(selector))返回元素;
}
返回null;
}
功能表演(e){
var$menu=此.querySelector(“ul.服务类别菜单”),
$click=this.querySelector(“.click text”);
如果([“无”,包括($menu.style.display)){
$menu.style.display=“块”;
$click.innerHTML='';
$click.addEventListener(“单击”,隐藏);
//删除'show'事件侦听器
此.removeEventListener(“单击”,显示);
}
e、 停止传播();
}
函数隐藏(e){
var$parent=getClosest(此“.service类别”),
$menu=$parent.querySelector(“ul.服务类别菜单”),
$click=$parent.querySelector(“.click text”);
如果(![“无”,“包括($menu.style.display)){
$menu.style.display=“无”;
$click.innerHTML=“单击以显示”;
$click.removeEventListener(“单击”,隐藏);
$parent.addEventListener(“单击”,显示);
}
e、 停止传播();
}
。服务类别{显示:内联块;边框:3px实心#ccc;边距:1%;字体重量:700;字体大小:3.5vw;光标:指针;背景颜色:fff;z索引:3;背景位置:中心;背景大小:封面;颜色:#000}。单击文本{文本对齐:右;字体大小:1.25vw;字体样式:斜体;字体重量:700;右填充:1%}。服务类别:悬停。单击文本{颜色:#b22222}。服务类别菜单{显示:无;左边距:8%;右边距:8%;边距顶部:1%;背景色:#fff;字体重量:700;字体大小:1.6vw;边框半径:10px}
网络开发
点击显示
-
一些文字。。。
网页设计
点击显示
-
一些文字。。。
看看addEventListener
/removeEventListener
——如果DOM能够在设置Programmaticali时重新解析onclick
属性,我会感到惊讶。谢谢,我在1998年之前就学会了js