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;
      };
    }
  • 相关阅读:
    面试笔试题
    类型转换
    c++11之智能指针
    c++预处理命令
    java的javac不能正常运行
    状态模式
    观察者模式Observer
    带图形界面的虚拟机安装+Hadoop
    测试工具的使用:JUnit、PICT、AllPairs
    Test_1 一元二次方程用例测试以及测试用例
  • 原文地址:https://www.cnblogs.com/linjiangxian/p/11598316.html
Copyright © 2011-2022 走看看