javascript - Nuxt js自定义光标事件监听器在路由更改后不起作用

标签 javascript vue.js nuxt.js addeventlistener gsap

我目前正在为我们的工作室构建一个新网站,但无法使自定义光标正常工作。这是一个用 gsap 构建的自定义光标,结果很好,除了当我导航到另一条路线并返回主页时,鼠标悬停事件停止工作,我找不到原因。

可能是什么原因造成的,如何解决?

提前致谢!

这是 CustomCursor 组件:

    <template>
      <div class="custom-cursor">
        <div id="cursor-big" class="custom-cursor__ball custom-cursor__ball--big"></div>
        <div id="cursor-small" class="custom-cursor__ball custom-cursor__ball--small"></div>
      </div>
    </template>
    
    <script>
      import gsap from "gsap";
    
      export default {
        props: {
          hoverClass: {
            type: String,
            default: 'cursorHover'
          }
        },
        mounted () {
          const cursorBig = document.getElementById('cursor-big'),
                cursorSmall = document.getElementById('cursor-small'),
                links = document.getElementsByTagName("a"),
                withClassHover = document.getElementsByClassName(this.hoverClass),
                withHover = [...links, ...withClassHover];
    
          // Event Listeners
          document.addEventListener("mousemove", onMouseMove);
          document.addEventListener("mousedown", onMouseHover);
          document.addEventListener("mouseup", onMouseHoverOut);
          document.addEventListener("mouseenter", () => {
            cursorBig.style.opacity = 1;
            cursorSmall.style.opacity = 1;
          });
          document.addEventListener("mouseleave", () => {
            cursorBig.style.opacity = 0;
            cursorSmall.style.opacity = 0;
          });
          withHover.forEach((element) => {
            element.addEventListener("mouseover", onMouseHover);
            element.addEventListener("mouseout", onMouseHoverOut);
          })
    
          // Event Handlers
          function onMouseMove(e) {
            cursorSmall.style.opacity = 1;
            gsap.to(cursorBig, 0.4, {
              x: e.clientX - 18.5,
              y: e.clientY - 18.5
            });
            gsap.to(cursorSmall, 0.1, {
              x: e.clientX - 4,
              y: e.clientY - 4
            });
          }
          function onMouseHover() {
            gsap.to(cursorBig, 0.3, {
              scale: 3,
            });
          }
          function onMouseHoverOut() {
            gsap.to(cursorBig, 0.3, {
              scale: 1,
            });
          }
        }
      };
    </script>
    
    <style>
      @media screen and (min-width:1100px) {
        * {
          cursor: none !important;
        }
    
        .custom-cursor__ball {
          position: fixed;
          top: 0;
          left: 0;
          mix-blend-mode: difference;
          z-index: 99999;
          opacity: 0;
          pointer-events: none;
          transition: opacity 0.5s ease;
        }
    
        .custom-cursor__ball--big {
          content: "";
          width: 35px;
          height: 35px;
          background: white;
          border-radius: 50%;
        }
    
        .custom-cursor__ball--small {
          content: "";
          width: 6px;
          height: 6px;
          background: #fff;
          border-radius: 50%;
        }
      }
    </style>

最佳答案

从评论中移动:

  • 问题:具有 cursorHover 类的元素在您离开其他地方时被删除后不在 DOM 上。 Mounted 只会触发一次。

修复:处理在 dom 元素上重新启动您的事件,并在路由更改时销毁您的自定义事件处理程序。

<template>
  <div class="custom-cursor">
    <div
      id="cursor-big"
      class="custom-cursor__ball custom-cursor__ball--big"
    ></div>
    <div
      id="cursor-small"
      class="custom-cursor__ball custom-cursor__ball--small"
    ></div>
  </div>
</template>

<script>
import gsap from "gsap";

export default {
  name: "CustomCursor",
  props: {
    hoverClass: {
      type: String,
      default: "cursorHover",
    },
  },
  data() {
    return {
      cursorBig: null,
      cursorSmall: null,
      withHover: [],
    };
  },
  watch: {
    "$route.path"() {
      console.log("route change");
      this.destroy();
      this.$nextTick(this.init);
    },
  },
  mounted() {
    console.log("mounted");
    this.$nextTick(this.init);
  },
  beforeDestroy() {
    console.log("beforeDestroy");
    this.destroy();
  },
  methods: {
    init() {
      console.log("init");
      setTimeout(() => {
        this.cursorBig = document.getElementById("cursor-big");
        this.cursorSmall = document.getElementById("cursor-small");

        this.withHover = [
          ...document.getElementsByTagName("a"),
          ...document.getElementsByClassName(this.hoverClass),
        ];

        this.withHover.forEach((element) => {
          element.addEventListener("mouseover", this.onMouseHover);
          element.addEventListener("mouseout", this.onMouseHoverOut);
        });
        document.addEventListener("mousemove", this.onMouseMove);
        document.addEventListener("mousedown", this.onMouseHover);
        document.addEventListener("mouseup", this.onMouseHoverOut);
        document.addEventListener("mouseenter", this.onMouseEnter);
        document.addEventListener("mouseleave", this.onMouseLeave);
      }, 100);
    },
    destroy() {
      console.log("destroy");
      this.withHover.forEach((element) => {
        element.removeEventListener("mouseover", this.onMouseHover);
        element.removeEventListener("mouseout", this.onMouseHoverOut);
      });
      document.removeEventListener("mousemove", this.onMouseMove);
      document.removeEventListener("mousedown", this.onMouseHover);
      document.removeEventListener("mouseup", this.onMouseHoverOut);
      document.removeEventListener("mouseenter", this.onMouseEnter);
      document.removeEventListener("mouseleave", this.onMouseLeave);
    },
    onMouseEnter() {
      this.cursorBig.style.opacity = 1;
      this.cursorSmall.style.opacity = 1;
    },
    onMouseLeave() {
      this.cursorBig.style.opacity = 0;
      this.cursorSmall.style.opacity = 0;
    },
    onMouseMove(e) {
      this.cursorSmall.style.opacity = 1;
      gsap.to(this.cursorBig, 0.4, {
        x: e.clientX - 18.5,
        y: e.clientY - 18.5,
      });
      gsap.to(this.cursorSmall, 0.1, {
        x: e.clientX - 4,
        y: e.clientY - 4,
      });
    },
    onMouseHover() {
      gsap.to(this.cursorBig, 0.3, {
        scale: 3,
      });
    },
    onMouseHoverOut() {
      gsap.to(this.cursorBig, 0.3, {
        scale: 1,
      });
    },
  },
};
</script>

<style>
@media screen and (min-width: 1100px) {
  * {
    cursor: none !important;
  }

  .custom-cursor__ball {
    position: fixed;
    top: 0;
    left: 0;
    mix-blend-mode: difference;
    z-index: 99999;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.5s ease;
  }

  .custom-cursor__ball--big {
    content: "";
    width: 35px;
    height: 35px;
    background: black;
    border-radius: 50%;
  }

  .custom-cursor__ball--small {
    content: "";
    width: 6px;
    height: 6px;
    background: #000;
    border-radius: 50%;
  }
}
</style>

关于javascript - Nuxt js自定义光标事件监听器在路由更改后不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70481561/

相关文章:

javascript - 检测 chrome.extension.sendRequest 失败

vue.js - Nuxt.js npm run generate 后找不到文件

layout - Nuxt.js - 如何在布局中使用布局

vue.js - 更改变量时 Vuejs 组件不会更新

vue.js - Nuxt 命令行传递参数

javascript - 替换字符串中最后一次出现的单词

javascript - 如何在 RxJS 中按功能组合函数( f(g(h)))?

javascript - 使用对象的属性作为 TextInput 的来源

javascript - 在 Vue.js 中迭代 JSON 和打印值

spring 5 webflux功能端点请求中不存在访问控制原始 header