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;
      };
    }
  • 相关阅读:
    web10 动态action的应用
    web09 struts2配置 struts2入门
    web 08 struts2入门 struts2配置 struts包
    web07-jdbcBookStore
    web06-PanduanLogin
    web05-CounterServlet
    web04-LoginServlet
    web03-OutputInfo
    web02-welcomeyou
    web01-helloworld
  • 原文地址:https://www.cnblogs.com/linjiangxian/p/11598316.html
Copyright © 2011-2022 走看看