Javascript 在按钮内部单击子元素时,不会触发父onClick

Javascript 在按钮内部单击子元素时,不会触发父onClick,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,我有一个下拉按钮组件,它有一个点击列表器。按钮有一些文本和图标。如果我们在大纲上而不是文本或图标上仔细单击按钮,则会触发单击事件。以下是我的组件: <template lang="html"> <div> <button class="button dropbtn" @click="toggleDropdown"> <span>{{ name }}</span> <span class="icon">&l

我有一个下拉按钮组件,它有一个点击列表器。按钮有一些文本和图标。如果我们在大纲上而不是文本或图标上仔细单击按钮,则会触发单击事件。以下是我的组件:

<template lang="html">
<div>
  <button class="button dropbtn" @click="toggleDropdown">
    <span>{{ name }}</span>
    <span class="icon"><i class="fa fa-caret-down"></i></span>
  </button>
  <div v-show="visible" class="dropdown-content is-primary-important">
    <slot>
    </slot>
  </div>
</div>
</template>

<script>
export default {
  props: ['name'],
  data: function() {
    return {
      visible: false
    }
  },
  mounted: function() {
    this.hideDropdownOnClick();
  },
  methods: {
    toggleDropdown: function() {
      // trigged on click of the button
      // make the dropdown visible
      console.log("toggling dropdown");
      this.visible = !this.visible;
    },
    hideDropdownOnClick: function() {
      window.onclick = (event) => {
        console.log(event.target);
        if (!event.target.matches('.dropbtn')) {
          console.log("here", this.visible);
          this.visible = false;
        }
      }
    }
  }
}
</script>

<style lang="css">
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
  position: absolute;
  background-color: #fff;
  min-width: 140px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: 1;
}

/* Links inside the dropdown */
.dropdown-content a {
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}
</style>
我觉得我缺少了一些基本的东西,有人能帮我吗?谢谢

编辑

这看起来像是浏览器的一个bug,因为这个问题的答案是:

添加此CSS规则可以解决我的问题:

span {
    pointer-events: none;
}

添加此CSS规则可以解决我的问题:

span {
    pointer-events: none;
}

单击可显示并立即隐藏列表。 您可以单击文本或图标,它们是span

this.visible = !this.visible;
然后代码转到window.onclick where

你的孩子没有这个班。所以你决定

 this.visible = false;
把支票换成

    if (!event.target.closest('.dropbtn')) 

单击可显示并立即隐藏列表。 您可以单击文本或图标,它们是span

this.visible = !this.visible;
然后代码转到window.onclick where

你的孩子没有这个班。所以你决定

 this.visible = false;
把支票换成

    if (!event.target.closest('.dropbtn')) 

当您在“跨距”中单击时,它会切换两次:一次是通过切换下拉方法切换, 其次是windows onclick处理程序

下面是一个工作示例:

您只需注册该指令:

Vue.directive('click-outside', VueClickOutSide)
并在模板中使用它:

 v-click-outside:delay="hideDropdownOnClick"

当您在“跨距”中单击时,它会切换两次:一次是通过切换下拉方法切换, 其次是windows onclick处理程序

下面是一个工作示例:

您只需注册该指令:

Vue.directive('click-outside', VueClickOutSide)
并在模板中使用它:

 v-click-outside:delay="hideDropdownOnClick"
单击“外部”时,可以使用隐藏下拉列表:

$npm安装vue单击关闭-保存 从“vue clickaway”导入{mixin as clickaway}

导出默认值{ 混合:[单击离开], …剩下的代码

在下拉按钮组件的根div中放置v-clickaway=visible=false

单击“外部”时,可以使用隐藏下拉列表:

$npm安装vue单击关闭-保存 从“vue clickaway”导入{mixin as clickaway}

导出默认值{ 混合:[单击离开], …剩下的代码

在下拉按钮组件的根div中放置v-clickaway=visible=false


很抱歉,我不明白你说的话。子项是否应该返回一个真正的onClick?@aks你的代码对我有效…哦,它的vue,我不知道该行为。对于js,如果你不通过stopPropogation阻止它,它应该是对父项的冒泡。@slyce它不会!请尝试单击文本,在我的浏览器chrome中它是不起作用!很抱歉,我不明白你说的话。子项是否应该返回一个真正的onClick?@aks你的代码对我起作用了…哦,它的vue,我不知道该行为。对于js,如果你不通过stopPropogation阻止它,它应该是对父项的冒泡。@slyce不会!请尝试在我的浏览器c中单击文本hrome它不起作用了!是的,你说的是对的。你能建议一种方法,当我们点击外部时,下拉列表可以隐藏吗?正如Slyce提到的,你可以使用clickaway。是的,你说的是对的。你能建议一种方法,当我们点击外部时,下拉列表可以隐藏吗?正如Slyce提到的,你可以使用clickaway。这是目前为止最简单、最有效的答案。谢谢。另一个经典的例子,其中被接受的答案比简单的解决方案复杂得多。这是迄今为止最简单、最有效的答案。谢谢。另一个经典的例子,其中被接受的答案比简单的解决方案复杂得多。