繁体   English   中英

当在按钮内单击子元素时,未触发父onClick

[英]Parent onClick is not triggered when the child element is clicked inside button

我有一个带有单击列表器的dropdown-button组件。 该按钮具有一些文本和图标。 如果我们在轮廓上而不是文本或图标上小心地单击按钮,则会触发单击事件。 这是我的组件:

<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>

我觉得这里缺少一些非常基本的东西,有人可以帮我吗? 谢谢。

编辑

这似乎是浏览器的错误,因为此问题的答案是: 按钮元素在单击按钮文本并将其释放时(但仍在按钮内部)不触发点击事件?

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

span {
    pointer-events: none;
}

当您单击跨度时,将其切换两次:)一次通过toggleDropdown方法,第二次通过Windows onclick处理程序。

这是工作示例: jsfiddle

<template id="tmp">
  <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>

<div id="x">
  <tmp name="my name">
     <span>toggle me!</span>
  </tmp>
</div>

Vue.component('tmp', {
template: '#tmp',

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;
}
}
});

new Vue({
el: '#x',
data: function(){
    return {
    name: 'myName'
  }
}
});

编辑:如果您不想使用clickaway,这是一个小指令,用于检测元素外部的点击:

var VueClickOutSide = {

    bind: function(el, binding, vNode) {
        var bubble = binding.modifiers.bubble;
        var handler = function(e) {
            if (bubble || (!el.contains(e.target) && el !== e.target)) {
                binding.value(e);
            }
        }
        el.__vueClickOutside__ = handler;
        document.addEventListener('click', handler);
    },

    unbind: function (el, binding, vNode) {
        document.removeEventListener('click', el.__vueClickOutside__);
        el.__vueClickOutside__ = null;
    }
};

您只需要注册该指令:

Vue.directive('click-outside', VueClickOutSide)

并在模板中使用它:

 v-click-outside:delay="hideDropdownOnClick"

您可以在外部点击时使用vue-clickaway隐藏下拉菜单:

  1. $ npm install vue-clickaway --save
  2. import { mixin as clickaway } from 'vue-clickaway';

  3. export default { mixins: [ clickaway ], ... the rest of your code ...

  4. 您将v-clickaway="visible = false"放在dropdown-button组件的根div中。

在单击时,您显示并立即隐藏列表。 您单击文本或图标(它们是“ span”),

this.visible = !this.visible;

然后代码转到window.onclick

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

而您的跨度没有此类。 所以你设定

 this.visible = false;

将支票更改为

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM