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;
      };
    }
  • 相关阅读:
    简单的StringBuffer实现
    Java-HashMap、HashSet、hashTable
    JavaScript 引用错误
    使用jconsole分析内存情况-JVM
    Thread 与 Runnable 混合使用测试
    裴波那序列-JAVA实现
    多线程之----------线程池
    winform 控件拖拽和缩放
    C# 使用Process调用外部程序中所遇到的参数问题
    winform textbox 的自动实现功能
  • 原文地址:https://www.cnblogs.com/linjiangxian/p/11598316.html
Copyright © 2011-2022 走看看