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;
  };
}
vue 利用intersectionOberver实现全局appear/disappear事件的更多相关文章
- vue学习笔记(一)关于事件冒泡和键盘事件 以及与Angular的区别
		
一.事件冒泡 方法一.使用event.cancelBubble = true来组织冒泡 <div @click="show2()"> <input type=&q ...
 - Vue父组件与子组件传递事件/调用事件
		
1.Vue父组件向子组件传递事件/调用事件 <div id="app"> <hello list="list" ref="child ...
 - 深入理解Vue父子组件通讯的属性和事件
		
在html中使用元素,会有一些属性,如class,id,还可以绑定事件,自定义组件也是可以的.当在一个组件中,使用了其他自定义组件时,就会利用子组件的属性和事件来和父组件进行数据交流. 父子组件之间的 ...
 - HTML5全局属性和事件
		
全局属性和事件能够应用到所有标签元素上,在HTML4中有许多全局属性,比如id,class等.HTML5中又新增了一些特殊功能的全局属性和事件. 属性: HTML5属性能够赋给标签元素含义和语 ...
 - ExtJS要利用观察者模式 去实现自定义的事件
		
// 要利用观察者模式 去实现自定义的事件 //1:由于浏览器他自己能定义内置的事件(click/blur...) // 我们也应该有一个类似于浏览器这样的类,这个类 自己去内部定义一些事件(自定义事 ...
 - Asp.net mvc 自定义全局的错误事件HandleErrorAttribute无效
		
Asp.net mvc 自定义全局的错误事件HandleErrorAttribute,结果无效, 原因: 1.没有在RegisterGlobalFilters 里面添加或者你要的位置添加. 2.你把这 ...
 - Vue  局部组件和全局组件的使用
		
<template> <div id="app"> <!--<img alt="Vue logo" src="./ ...
 - vue教程3-03 vue组件,定义全局、局部组件,配合模板,动态组件
		
vue教程3-03 vue组件,定义全局.局部组件,配合模板,动态组件 一.定义一个组件 定义一个组件: 1. 全局组件 var Aaa=Vue.extend({ template:'<h3&g ...
 - Vue源码探究-全局API
		
Vue源码探究-全局API 本篇代码位于vue/src/core/global-api/ Vue暴露了一些全局API来强化功能开发,API的使用示例官网上都有说明,无需多言.这里主要来看一下全局API ...
 
随机推荐
- bzoj1037题解
			
[解题思路] DP.f[i][j][x][y]表示已选了i个♂和j个♀,其中♂比♀多x,♀比♂多y(x,y≥0). 递推式转移方程: (f[i+1][j][x+1][max(y-1,0)]+=f[i] ...
 - iOS ARC使用总结
			
在iOS ARC模式下,编译器会自动插入release 有些时候程序出现 message sent to deallocated object的时候,你不知道什么原因. 一种原因是因为你在ARC下使用 ...
 - P1655 小朋友的球
			
P1655 小朋友的球 题目描述 @发源于 小朋友最近特别喜欢球.有一天他脑子抽了,从口袋里拿出了N个不同的球,想把它们放到M个相同的盒子里,并且要求每个盒子中至少要有一个球,他好奇有几种放法,于是尝 ...
 - APIHOOK
			
#include <stdio.h> #include <windows.h> #include <Dbghelp.h> #pragma comment(lib,& ...
 - C++之引用与符号“&”
			
一.&的意思: 1.取地址符,这时候它用于数据的前面,比如int a=&b; 2.C++里还使用&作为引用符,如果你确认程序是标准的C而非C++的话,那么可以排除是引用了.引用 ...
 - Delphi 中的哈希表: THashedStringList
			
转自万一博客 Delphi 中的哈希表: THashedStringList unit Unit1; interface uses Windows, Messages, SysUtils, Var ...
 - java之jvm学习笔记六(实践写自己的安全管理器)
			
安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用AccessController的checkPerssiom方法,访问控 ...
 - HSE_VALUE 修改问题
			
MDK的例程给的外部晶振是25Mhz,以24Mhz为例,介绍修改方法. ·1. 修改HSE_VALUE 在 “stm32f4xx.h" 搜索 ”HSE_VALUE" 会看到下面这句 ...
 - 学习k8s的经验
			
最近在学k8s,总结一下安装k8s的坑. 1.晚上关于k8s的学习资料很多,多不如精,这个博客很好,https://blog.csdn.net/sinat_35930259/article/categ ...
 - 安装mysql时,服务无法启动的问题
			
1.下载mysql镜像文件:mysql-installer-community-8.0.17.0.msi 2.点击镜像进行安装,一直next即可 3.cmd以管理员身份,进入到安装的mysql安装目录 ...