捕获 Vue 应用程序中的所有点击事件

Posted

技术标签:

【中文标题】捕获 Vue 应用程序中的所有点击事件【英文标题】:Capture all click events inside Vue application 【发布时间】:2019-09-03 16:09:20 【问题描述】:

我需要捕获用户在我的 Vue.js 应用程序中触发的所有点击事件。我的第一步是在#app div 中添加一个 onclick 监听器:

<div id="app" @click="onClickApp"></div>
// ...
<script>
  export default 
    methods: 
      onClickApp() 
        // increment counter in vuex store
      
   
</script>

这会捕获直接在 App 组件内发生的所有点击事件。问题是我正在使用 Bootstrap 模态(通过 BootstrapVue 提供),我还需要捕获其中的点击。这目前不起作用,即使我在 &lt;b-modal&gt;&lt;/b-modal&gt; 组件上设置了另一个 @click 侦听器(vue-cli 的语法)。

这也是我尝试过的(main.js):

new Vue(
  router,
  store,
  render: h => h(App),
  mounted: function() 
    this.$el.addEventListener('click', this.onClickVue)
  ,
  beforeDestroy: function () 
    this.$el.removeEventListener('click', this.onClickVue)
  ,
  methods: 
    onClickVue: function (e) 
      this.$store.commit(mutationTypes.INCREMENT_CLICKS)
    
  );

同样的问题,Bootstrap Modals 内的点击不会触发点击事件。

【问题讨论】:

你的意思是:***.com/questions/46899901/… 嗯,谢谢,但我不这么认为。这似乎是通过事件在组件之间进行通信的解决方案,对吧?我只想在模态中捕获 onclick 事件。 document 上收听怎么样? 在你的应用程序中设置监听器和处理程序mounted钩子是否可行?像document.onclick = (e) =&gt; console.log("x: " + e.clientX + " y: " + e.clientY) 这样的东西应该很容易测试...... 为你想要做的事情创建一个方法doSomething 并在挂载中添加一个监听器并检查它是否有效;-) 【参考方案1】:

我只能通过使用 mouseup 事件来让它工作..

CodePen 镜像:https://codepen.io/oze4/pen/PgKWRW?editors=1010

new Vue(
  el: "#app",
  data: 
    modalShow: false
  ,
  mounted() 
    document.addEventListener("mouseup", e => 
      let m = `x: $e.clientX | y: $e.clientY`;
      console.log(m);
    )
  
);
<script src="https://unpkg.com/vue@2.5.17/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.min.js"></script>
<link href="https://unpkg.com/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.css" rel="stylesheet" />

<div id="app">
  <div style="margin: 5px 0px 0px 40px">
    <b-button @click="modalShow = !modalShow">Open Modal</b-button>
    <b-modal v-model="modalShow">Hello From Modal!</b-modal>
  </div>
</div>

【讨论】:

谢谢,这正在工作!我将它与@marvin-irwin 的方法结合起来,它正是我想要的。 漂亮!很高兴您能找到解决方案。【参考方案2】:

我找不到使用 Bootstrap Vue 进行测试的方法,但这可能会。

TLDR:创建一个插件,该插件将在您的任何组件被实例化时运行。在根元素上放置一个监听器。

https://codesandbox.io/s/kxwz85pl65

const MyPlugin = 
  install(Vue, options) 
    Vue.mixin(
      mounted() 
        setTimeout(() => 
          let cb = this.$root.$el.onclick;
          this.$root.$el.onclick = (e) => 
            alert("element clicked");
            if (cb) 
              cb(e);
            
          ;
        , 10);
      
    );
  
;

编辑:

截至撰写本文时,Vue Bootstrap 似乎不允许模态本身的点击事件,尽管可以点击其中的元素。

https://codesandbox.io/embed/kxwz85pl65

再次编辑,如果你真的想,你可以使用设置超时。不过这有点小技巧。

【讨论】:

我真的很喜欢你的想法,但是在模态中不会触发 onclick,效果与我在问题中描述的功能相同。如果页面内容小于视口,则不会触发内容之外的点击事件(因为#app 不会拉伸到视口度量)。 谢谢,但是使用setTimeout我在单击一个元素时会触发 23 个单击事件。此外,Bootstrap Modal 仍然没有对点击做出反应。我将检查为每个模态元素添加单独的@click。我想我过去已经这样做了,但让我们试一试。【参考方案3】:

更好的答案是将 ev 添加到 onClickApp,在方法中添加 onClickApp(ev)。

现在,您可以访问点击事件了。

【讨论】:

【参考方案4】:

这应该工作;-)

- <div id="app" @click="onClickApp"></div>
+ <div id="app"></div>
// ...
<script>
  export default 
    methods: 
      onClickApp() 
        // increment counter in vuex store
      
   ,
+  mounted() 
+    window.document.addEventListener('click'), this.onClickApp)
+  ,
+  beforeDestroy() 
+    window.document.removeEventListener('click'), this.onClickApp)
+  
</script>

【讨论】:

谢谢,我已经尝试过了(参见我上面的编辑),但仍然没有捕获到对 Modal 的点击。

以上是关于捕获 Vue 应用程序中的所有点击事件的主要内容,如果未能解决你的问题,请参考以下文章

如何在用户点击JS中的移动设备中点击按钮时捕获事件

如何从 vue.js 捕获 Jquery 事件

如何在 vue 中的非输入元素上捕获 Enter 事件?

vue 的点击事件获取当前点击的元素方法

React 应用程序中的 Auth0 Lock v11 未捕获“已验证”事件

在苹果 iphone 上,点击通知会捕获啥事件?