首页 > 解决方案 > Vue Js 立即添加事件监听器触发

问题描述

我正在使用 onclick 函数在单击时将事件侦听器添加到父类并立即触发

<button v-on:click="greet">Try it</button>

这是功能

greet: function(e){
 document.getElementById("st-container").addEventListener("click", function() {
        this.bodyClickFn();
      }.bind(this));
}

“st-container”是覆盖按钮的父类

该功能this.bodyClickFn();立即启动

<div class="st-container">
 .
 .
<button v-on:click="greet">Try it</button>
 .
 .
</div>

这是整个vue文件

<template>
    <div>
        <div id="st-container" class="st-container">
            <!--    
                example menus  st-effect-11 st-menu-open
                these menus will be on top of the push wrapper
            -->

            <nav class="st-menu st-effect-11" id="menu-11">
                <h2 class="icon icon-lab">Sidebar</h2>
                <ul>
                    <li>
                        <router-link class="link" :to="{ name: 'home' }">Home</router-link>
                    </li>
                    <li>
                        <router-link class="link" :to="{ name: 'hello' }">Hello World</router-link>
                    </li>

                    <li>
                        <router-link class="link" :to="{ name: 'hello' }">Hello World</router-link>
                    </li>
                    <li>
                        <a href="/main/hello">Hello World</a>
                    </li>
                </ul>
            </nav>

            <!-- content push wrapper -->
            <div class="st-pusher" style="height: 90vh">
                <!--    
                    example menus 
                    these menus will be under the push wrapper
                -->

                <div class="st-content">
                    <!-- this is the wrapper for the content -->
                    <div class="st-content-inner">
                        <!-- extra div for emulating position:fixed of the menu -->
                        <!-- Top Navigation -->

                        <header class="codrops-header">
                            <h1>Sidebar Transitions <span>Transition effects for off-canvas views</span></h1>
                        </header>
                        <div class="main clearfix">
                            <div id="st-trigger-effects" class="column">
                                <button data-effect="st-effect-1">Slide in on top</button>
                                <button data-effect="st-effect-2">Reveal</button>
                                <button data-effect="st-effect-3">Push</button>
                                <button data-effect="st-effect-4">Slide along</button>
                                <button data-effect="st-effect-5">Reverse slide out</button>
                                <button data-effect="st-effect-6">Rotate pusher</button>
                                <button data-effect="st-effect-7">3D rotate in</button>
                                <button data-effect="st-effect-8">3D rotate out</button>
                                <button data-effect="st-effect-9">Scale down pusher</button>
                                <button data-effect="st-effect-10">Scale Up</button>
                                <button data-effect="st-effect-11">Scale &amp; rotate pusher</button>
                                <button data-effect="st-effect-12">Open door</button>
                                <button data-effect="st-effect-13">Fall down</button>
                                <button data-effect="st-effect-14">Delayed 3D Rotate</button>

                            </div>
                            <router-view></router-view>
                            <button v-on:click="greet">Try it</button>
                            <h1>food</h1>
                            <h1>food</h1>
                            <h1>food</h1>
                            <h1>food</h1>
                            <h1>food</h1>
                            <h1>food</h1>
                            <h1>food</h1>
                            <h1>food</h1>
                            <h1>food</h1>
                            <div class="column">
                                <p>Sidebar menus or off-canvas navigations can be revealed in many creative ways.</p>
                                <p>Here is some inspiration for showing them in style using CSS transitions.</p>
                            </div>
                            <div class="info">
                                <p>If you enjoyed this demo you might also like:</p>
                                <p><a href="http://tympanus.net/Development/HeaderEffects/">On Scroll Header Effects</a></p>
                                <p><a href="http://tympanus.net/Development/PageTransitions/">A Collection of Page Transitions</a></p>
                            </div>
                        </div><!-- /main -->
                    </div><!-- /st-content-inner -->
                </div><!-- /st-content -->
            </div><!-- /st-pusher -->
        </div>
    </div>
</template>
<script>
export default {
  methods: {
    greet: function(e) {
      document
        .getElementById("st-container")
        .setAttribute("class", "st-container st-effect-11 st-menu-open");

      document.getElementById("st-container").addEventListener("click", function() {
        this.bodyClickFn();
      }.bind(this));
    },
    resetMenu: function() {
      document.getElementById("st-container");
    },
    bodyClickFn: function() {
      console.log("asdasda");
      this.resetMenu();

      document
        .getElementById("st-container")
        .removeEventListener("click", this.bodyClickFn);
      document
      .getElementById("st-container")
      .addEventListener("click", this.bodyClickFn);
    }
  }
};
</script>





<style lang="css" scoped>
*,
*:after,
*::before {
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

html,
body,
.st-container,
.st-pusher,
.st-content {
  height: 100%;
}

.st-content {
  overflow-y: scroll;
  background: #f3efe0;
}

.st-content,
.st-content-inner {
  position: relative;
}

.st-container {
  position: relative;
  overflow: hidden;
}

.st-pusher {
  position: relative;
  left: 0;
  z-index: 99;
  height: 100%;
  perspective: 1000px;
  -webkit-transition: -webkit-transform 0.5s;
  transition: transform 0.5s;
}

.st-pusher::after {
  position: absolute;
  top: 0;
  right: 0;
  width: 0;
  height: 0;
  background: rgba(0, 0, 0, 0.2);
  content: "";
  opacity: 0;
  -webkit-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
  transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
}

.st-menu-open .st-pusher::after {
  width: 100%;
  height: 100%;
  opacity: 1;
  -webkit-transition: opacity 0.5s;
  transition: opacity 0.5s;
}

.st-menu {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  visibility: visible;
  width: 300px;
  height: 100%;
  background: #48a770;
  -webkit-transition: all 0.5s;
  transition: all 0.5s;
}

.st-menu::after {
  position: absolute;
  top: 0;
  right: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.2);
  content: "";
  opacity: 1;
  -webkit-transition: opacity 0.5s;
  transition: opacity 0.5s;
}

.st-menu-open .st-menu::after {
  width: 0;
  height: 0;
  opacity: 0;
  -webkit-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
  transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
}

/* content style */

.st-menu ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.st-menu h2 {
  margin: 0;
  padding: 1em;
  color: rgba(0, 0, 0, 0.4);
  text-shadow: 0 0 1px rgba(0, 0, 0, 0.1);
  font-weight: 300;
  font-size: 2em;
}

.st-menu ul li a {
  display: block;
  padding: 1em 1em 1em 1.2em;
  outline: none;
  box-shadow: inset 0 -1px rgba(0, 0, 0, 0.2);
  color: #f3efe0;
  text-transform: uppercase;
  text-shadow: 0 0 1px rgba(255, 255, 255, 0.1);
  letter-spacing: 1px;
  font-weight: 400;
  -webkit-transition: background 0.3s, box-shadow 0.3s;
  transition: background 0.3s, box-shadow 0.3s;
}

.st-menu ul li:first-child a {
  box-shadow: inset 0 -1px rgba(0, 0, 0, 0.2), inset 0 1px rgba(0, 0, 0, 0.2);
}

.st-menu ul li a:hover {
  background: rgba(0, 0, 0, 0.2);
  box-shadow: inset 0 -1px rgba(0, 0, 0, 0);
  color: #fff;
}

.st-effect-11.st-container {
  -webkit-perspective: 1500px;
  perspective: 1500px;
}

.st-effect-11 .st-pusher {
  -webkit-transform-style: preserve-3d;
  transform-style: preserve-3d;
}

.st-effect-11.st-menu-open .st-pusher {
  -webkit-transform: translate3d(100px, 0, -600px) rotateY(-20deg);
  transform: translate3d(100px, 0, -600px) rotateY(-20deg);
}

.st-effect-11.st-menu {
  opacity: 1;
  -webkit-transform: translate3d(-100%, 0, 0);
  transform: translate3d(-100%, 0, 0);
}

.st-effect-11.st-menu-open .st-effect-11.st-menu {
  visibility: visible;
  -webkit-transition: -webkit-transform 0.5s;
  transition: transform 0.5s;
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
}

.st-effect-11.st-menu::after {
  display: none;
}
</style>

标签: vue.js

解决方案


你在极大地滥用 vue。首先,您通常不需要使用document.get,因为您应该使用this.$refs. 其次,您可以使用动态类切换类:class

因此,您可以将行简化为:

<div @click="bodyClickFn" id="st-container" class="st-container" :class="{'st-effect-11': clickable, 'st-menu-open': clickable}" ref="container">


<button v-on:click.stop="greet">Try it</button>

注意.stop之后click,这基本上是在调用stopPropagation


  data()
  {
    return {
      clickable: false
    }
  },
  methods: {
    greet: function(e) {
      this.clickable = true
    },
    resetMenu: function() {
      this.clickable = false
    },
    bodyClickFn: function() {
      if (!this.clickable)
      {
        return
      }
      this.resetMenu();
    }
  }

密码沙盒: https ://codesandbox.io/s/6vwmvxm193

我建议您在进一步使用它之前实际观看一些 youtube 教程。因为如果您不打算实际使用 Vue 的功能,那么使用 Vue 是没有意义的。


推荐阅读