zoukankan      html  css  js  c++  java
  • vue——利用intersectionOberver实现全局appear/disappear事件

    搬运自:https://juejin.im/post/5cd10959f265da03a00fe5c6

    效果:

    demo地址: https://codepen.io/deepkolos/pen/OYPNNv?editors=1011

    vue:

    <template>
        <div @appear="onAppear" @disappear="onDisappear">box</div>
    </template>
    
    <script>
    export default {
        methods: {
            onAppear() { console.log('onAppear') },
            onDisappear() { console.log('onDisappear') }
        }
    }
    </script>

    js:

    extend(EventTarget.prototype, 'addEventListener', function(eventName) {
      let node = this;
      let ioContext = node.__IO__;
    
      if (eventName === 'appear' || eventName === 'disappear') {
        // 一个节点需要一个 io 即可
        if (node.__IO__) {
          ioContext.listenerNum++;
          return;
        }
    
        let io = new IntersectionObserver(entries => {
          const ioContext = node.__IO__;
          const { visible: lastVisible } = ioContext;
          const entry = entries[entries.length - 1];
          const ratio = entry.intersectionRatio;
          const visible = entry.isIntersecting && ratio >= 0;
    
          if (lastVisible === undefined) {
            ioContext.visible = visible;
          } else if (visible !== lastVisible) {
            ioContext.visible = visible;
    
            node.dispatchEvent(
              new CustomEvent(visible ? 'appear' : 'disappear', {
                bubbles: false // appear/disappear是节点相关的事件不能冒泡
              })
            );
          }
        });
    
        node.__IO__ = {
          instance: io,
          listenerNum: 1
        };
        io.observe(node);
      }
    });
    
    extend(EventTarget.prototype, 'removeEventListener', function(eventName) {
      let node = this;
      let ioContext = node.__IO__;
    
      if (eventName === 'appear' || eventName === 'disappear') {
        // 当事件为没有监听器的时候就可以把 io 注销, 释放内存
        if (--ioContext.listenerNum === 0) {
          ioContext.instance.disconnect();
          ioContext.instance = null;
          node.__IO__ = null;
        }
      }
    });
    
    function extend(obj, fnName, cb) {
      const oldFn = obj[fnName];
      obj[fnName] = function wrap() {
        let ret;
        oldFn && (ret = oldFn.apply(this, arguments));
        cb && cb.apply(this, arguments);
        return ret;
      };
    }
  • 相关阅读:
    斐波那契数列
    斐波那契数列
    .NET (C#)ASP.NET 应用程序与页面生命周期
    .NET (C#) Internals: ASP.NET 应用程序与页面生命周期(意译)
    如何使用:before和:after伪元素?
    学习的网址
    css盒子(box)
    利用Asp.Net来实现“网络硬盘”功能
    Jtemplates ${} or {{html}}的区别
    Jtemplate
  • 原文地址:https://www.cnblogs.com/linjiangxian/p/11598316.html
Copyright © 2011-2022 走看看