- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 Vue 应用程序中有一个相当简单的组件。当用户打开菜单时,我将事件监听器添加到 #app
元素以检测“外部”点击。
当用户在外部单击时,它会关闭菜单并移除事件监听器。这按预期工作。问题是,当用户单击按钮打开菜单,然后再次单击它关闭它时,我也想要removeEventListener
因为菜单现在已关闭.
然而,这是行不通的。当我通过按钮打开菜单然后通过按钮关闭它时,事件监听器保留在 #app
元素上,即使我正在删除它也是如此。
如果您多次单击按钮,然后在值显示 true
时单击按钮外部,您将多次看到控制台日志 outside click
。
new Vue({
el: "#app",
data: {
menuVisible: false
},
methods: {
click(e) {
var clickSource = e.target;
var app = document.getElementById("app");
var that = this;
function clickOutside(e) {
if (e.target != clickSource) {
console.log("outside click");
that.menuVisible = false;
app.removeEventListener("click", clickOutside);
}
}
if (this.menuVisible === false) {
this.menuVisible = true;
app.addEventListener("click", clickOutside);
} else if (this.menuVisible === true) {
this.menuVisible = false;
app.removeEventListener("click", clickOutside);
}
}
}
});
body {
margin: 0;
}
#app {
min-height: 100vh;
}
<script src="https://unpkg.com/vue"></script>
<div id="app">
{{menuVisible}}
<button @click="click">
click
</button>
</div>
最佳答案
问题是在每次点击
时,您都会创建一个新 clickOutside
函数;如果您将该函数与 removeEventListener
一起使用,因为没有向该确切 函数对象注册事件,所以不会删除任何内容。
相反,请记住处理程序对象,以便您可以使用它进行删除,请参阅注释:
new Vue({
el: "#app",
data: {
menuVisible: false,
clickOutside: null
},
methods: {
click(e) {
var clickSource = e.target;
var app = document.getElementById("app");
var that = this;
// Only create it if we don't already have it
if (!this.clickOutside) {
// Create it
this.clickOutside = function clickOutside(e) {
console.log("clickOutside triggered");
if (e.target != clickSource) {
console.log("It's an outside click");
that.menuVisible = false;
// Remove it
app.removeEventListener("click", that.clickOutside);
}
};
}
if (this.menuVisible === false) {
this.menuVisible = true;
app.addEventListener("click", this.clickOutside);
} else if (this.menuVisible === true) {
this.menuVisible = false;
app.removeEventListener("click", this.clickOutside);
}
}
}
});
body {
margin: 0;
}
#app {
min-height: 100vh;
background-color: #ddd;
}
<script src="https://unpkg.com/vue"></script>
<div id="app">
{{menuVisible}}
<button @click="click">
click
</button>
</div>
旁注:使用起来更加地道
if (this.menuVisible) {
this.menuVisible = false;
app.removeEventListener("click", this.clickOutside);
} else {
this.menuVisible = true;
app.addEventListener("click", this.clickOutside);
}
甚至
this.menuVisible = !this.menuVisible;
if (this.menuVisible) {
app.addEventListener("click", this.clickOutside);
} else {
app.removeEventListener("click", this.clickOutside);
}
...而不是将 bool 值与 true
或 false
与 ===
进行比较。您已经了一个 bool 值,所以...我的意思是,您在哪里停止? if ((this.menuVisible) === true === true)
? :-)
关于javascript - removeEventListener 没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46546472/
我有以下代码,我在其中向文档添加了一个事件监听器,然后将其删除。 document.addEventListener("keypress", gameStart); function gameStar
我想知道是否可以在不引用应删除的事件处理函数的情况下删除事件监听器。 jquery的$().unbind('touchmove')将无法工作,因为事件监听器是使用 Javascript 的 addEv
下面的代码应该在轮到玩家手中的每张扑克牌时添加一个事件监听器,然后在轮到其他玩家时删除事件。 它不起作用。一旦事件在第一回合初始设置,该玩家的牌就保持可点击状态。 takeTurn ( playerI
这个问题已经有答案了: How to removeEventListener that is addEventListener with anonymous function? (5 个回答) 已关闭
由于某种原因,我需要在滚动页面结束时延迟点击并阻止Default一段时间。所以我写了这样的内容: // const disableClickDuringScrollHandler=(e)=> { //
我不明白为什么单击 div2 元素后 div1 元素仍然分配了事件监听器。似乎 specialFunction() 的 div 参数在初始执行后和单击 div2 后是 div1 元素,其中应该从 di
这个问题已经有答案了: Removing event listener which was added with bind (10 个回答) 已关闭 5 个月前。 我一直在研究 es6 类,并尝试设置
我知道有类似问题的问题,但我不知道如何解决该问题。 我需要解决这个问题:我在 html 文档中添加了一个 onClick 监听器,然后,在 js 中我尝试删除它,但我不能。 这是我的代码:
我正在尝试制作一款纸牌游戏。在我的游戏中,用户有义务选择一张卡(我向每张卡添加 EventListeners ,在我的 HTML 中为 ),选择后他不应该允许点击任何其他卡(我必须删除所有 Even
我添加了一个事件监听器以在用户操作后捕获 SVG 的加载。 HTML JS mySVG = document.getElementById('mySVG'); mySVG.addEventListe
这个问题在这里已经有了答案: The value of "this" within the handler using addEventListener (10 个答案) 关闭 3 年前。 我一定是
我的元素上有一个事件监听器,由于某种原因我不知道为什么没有删除。 我是这样设置的: for (i = 0; i < data[0].length; i++) { (function(i){
我想弄清楚为什么我的 removeEventListener 不起作用,我尝试了多种方法来修复它但仍然不起作用任何见解都会有所帮助。 addEventListener 按预期工作,但当我尝试删除监听器
我的 Vue 应用程序中有一个相当简单的组件。当用户打开菜单时,我将事件监听器添加到 #app 元素以检测“外部”点击。 当用户在外部单击时,它会关闭菜单并移除事件监听器。这按预期工作。问题是,当用户
我按照教程创建了 slider 效果。问题是效果在较小的屏幕上看起来不太好。我可以很容易地使用媒体查询处理样式,问题是 javascript 不是这种情况。这是我的代码: HTML:
考虑以下示例。我们有一个简单的 html 文件 Create button 和两个版本的js文件。版本一个: function create_button() { var new_
有没有办法根据变量而不是事件来删除偶数监听器?我想删除我设置的两个事件监听器,但不想删除第三方网站可能已启用的其他事件监听器。 var scrollVar = window.addEventListe
我有一些简单的代码,但目前它不会在第一次调用后删除监听器。我怎样才能做到这一点?还是我真的需要在收到通知后对 var 集添加冗余 if/else 检查? document.addEventLi
我有一个生成 HTML 元素的对象,这些元素也与该对象的数组相关联,假设我们有一个它的实例。因此,当它创建元素时,它还会将以下事件监听器分配给元素的嵌套部分(类是 uploadDelete)。 现在这
我已经尝试使用 console.log 对我的代码进行故障排除并查看它是否会运行,但它似乎只是绕过了 removeEventListeners。我让同行检查了我的代码,但不明白问题出在哪里。Javas
我是一名优秀的程序员,十分优秀!