element ui clickoutside 指令源码解读_element-ui clickoutside原理-程序员宅基地

技术标签: ELEMENT  vue.js  

import Vue from 'vue';
import { on } from 'element-ui/src/utils/dom';

const nodeList = [];
// 一个命名空间
const ctx = '@@clickoutsideContext';

let startClick;
// 全局种子id,自动增长,永不重复
let seed = 0;

// mousedown mouseup 委托事件点击事件
!Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e));

!Vue.prototype.$isServer && on(document, 'mouseup', e => {
  nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
});

function createDocumentHandler(el, binding, vnode) {
  return function(mouseup = {}, mousedown = {}) {
    // 推断当前点击是不是在clickoutside指令元素上
    // 如果是直接return
    // 否则执行对应的handler
    
    if (!vnode ||
      !vnode.context ||
      !mouseup.target ||
      !mousedown.target ||
      el.contains(mouseup.target) ||
      el.contains(mousedown.target) ||
      el === mouseup.target ||
      (vnode.context.popperElm &&
      (vnode.context.popperElm.contains(mouseup.target) ||
      vnode.context.popperElm.contains(mousedown.target)))) return;

    if (binding.expression &&
      el[ctx].methodName &&
      vnode.context[el[ctx].methodName]) {
      vnode.context[el[ctx].methodName]();
    } else {
      el[ctx].bindingFn && el[ctx].bindingFn();
    }
  };
}

/**
 * v-clickoutside
 * @desc 点击元素外面才会触发的事件
 * @example
 * ```vue
 * <div v-element-clickoutside="handleClose">
 * ```
 */
export default {
  bind(el, binding, vnode) {
    nodeList.push(el);
    const id = seed++;
    el[ctx] = {
      id,
      documentHandler: createDocumentHandler(el, binding, vnode),
      methodName: binding.expression,
      bindingFn: binding.value
    };
  },

  update(el, binding, vnode) {
    el[ctx].documentHandler = createDocumentHandler(el, binding, vnode);
    el[ctx].methodName = binding.expression;
    el[ctx].bindingFn = binding.value;
  },

  // 移除nodeList里面对应包含的元素, mouseup 时不会执行对应方法
  unbind(el) {
    let len = nodeList.length;

    for (let i = 0; i < len; i++) {
      if (nodeList[i][ctx].id === el[ctx].id) {
        nodeList.splice(i, 1);
        break;
      }
    }
    delete el[ctx];
  }
};

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_36878452/article/details/105218092

智能推荐

密钥管理概述_有中心的密钥分发模式中,会话密钥可以由( ) 生成。-程序员宅基地

文章浏览阅读4.5k次,点赞3次,收藏19次。密钥管理概述密钥管理包含:密钥生成、装入、存储、备份、分配、更新、吊销、销毁等内容,分配与存储是最棘手的问题。密钥生成:集中式密钥生成:由可信的密钥管理中心分布式密钥生成:网络中的多个节点协商密钥分配:集中式:由可信的密钥管理中心给用户分发(存在单点失效问题)分布式:多个服务器通过协商来分发密钥种类:主密钥:对密钥加密密钥进行加密的密钥,通常通过自然界中的真随机现象提取或由伪随机数生成器来生成密钥加密密钥:在传输会话密钥时,用来加密会话密钥的密钥,也称次主密钥或二级密钥。_有中心的密钥分发模式中,会话密钥可以由( ) 生成。

Machine Learning-Octave的下载与安装_octave下载安装-程序员宅基地

文章浏览阅读7.2k次,点赞2次,收藏12次。一、下载1.进入Octave下载页面:https://www.gnu.org/software/octave/download.html2.选择自己的系统,这里以windows版本的octave-4.4.1-w64-installer.exe为例,选择对应位数的版本,点击下载即可:3.安装1.双击下载好的文件进行安装3.点击Finish完成后,桌面自动生成两个图标:一个是命令..._octave下载安装

mvc路由原理 php_PHP MVC原理及实现-程序员宅基地

文章浏览阅读146次。一、mvc原理mvc是一种程序开发设计模式,它实现了显示模块与功能模块的分离。提高了程序的可维护性、可移植性、可扩展性与可重用性,降低了程序的开发难度。它主要分模型、视图、控制器三层。模型(model)它是应用程序的主体部分,主要包括业务逻辑模块(web项目中的Action,dao类)和数据模块(pojo类)。模型 与数据格式无关,这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次就..._php mvc路由执行流程

Uboot启动流程(一)_init_sequence_r-程序员宅基地

文章浏览阅读757次。Uboot启动流程简要列举,帮助梳理启动流程。详细过程参考Uboot源码和《STM32MP1嵌入式Linux驱动开发指南》讲解_init_sequence_r

Android之OkHttp详解(非原创)-程序员宅基地

文章浏览阅读309次。文章大纲一、OkHttp简介二、OkHttp简单使用三、OkHttp封装四、项目源码下载一、OkHttp简介1. 什么是OkHttp  一般在Java平台上,我们会使用Apache HttpClient作为Http客户端,用于发送 HTTP 请求,并对响应进行处理。比如可以使用http客户端与第三方服务(如SSO服务)进行集成,..._android okhttp3封装使用

GIT常用命令_ugit新增仓库-程序员宅基地

文章浏览阅读198次。文章目录git笔记安装配置新建仓库。提交、关联从现有仓库克隆从另一个仓库合并代码到本地更新本地分支远端标签导出问题解决回滚到任意版本提交代码时 无法直接 git pull 问题。因为 本地分支没有和远程分支进行关联当控制台提示本地版本 滞后 远程版本时, 使用强制提交 覆盖远程分支(慎用!慎用!慎用!)代码写错分支,怎么办?欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左_ugit新增仓库

随便推点

Linux-sed文本处理流编辑器-程序员宅基地

文章浏览阅读9.7k次,点赞4次,收藏6次。概述Linux sed命令是利用script来处理文本文件。sed可依照script的指令,来处理、编辑文本文件。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。语法sed [-hnV][-e][-f<script文件>][文本文件]参数说明:-e<script>或–expression=<script> 以选项中指定的script来处理输入的文本文件。

myBatis中传入的参数是map,map里面存了字符串也存了对象,* mapper.xml文件中的sql该怎么写_mapper存储对象的字段sql-程序员宅基地

文章浏览阅读6.8k次。(1)map中字符串的使用 &lt;if test="startInvokeStartTime != null"&gt;and invoke_start_time &gt;=#{startInvokeStartTime,jdbcType=TIMESTAMP}&lt;/if&gt;&lt;if test="endInvokeStartTime != null"&gt; ..._mapper存储对象的字段sql

Python 执行时遇到 UnicodeDecodeError: 'cp950' codec can't decode ...._unicodeencodeerror: 'cp950' codec can't encode cha-程序员宅基地

文章浏览阅读5.5w次。Python 执行时如何解决 UnicodeDecodeError: 'cp950' codec can't decode .... 问题_unicodeencodeerror: 'cp950' codec can't encode character '\u8682' in positio

最新的一版,通用Android-客户端架构设计,只有你还没看过_java generate android project-程序员宅基地

文章浏览阅读919次。###日志系统日志系统要完成以下几个功能:1、Debug时的日志需求2、日志写入文件的需求,方便上线查看3、日志上报4、日志加密系统日志监控:日志奔溃信息监控修改医行者中的日志系统可以达到需求, 也可以修改Github开源项目格式化日志输出项目: Logger 和 日志收集项目:Log 达到要求。网络系统Gitbub: OkHttphttps://github.com/square/okhttpOkHttp封装:HttpGet、HttpPost、File Upload,OKHttp的使_java generate android project

原生js实现点击图片和点击按钮切换背景图片案例_前端 点击更换背景图-程序员宅基地

文章浏览阅读1.4k次。代码验证:我是新手不要喷哦<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"&._前端 点击更换背景图

JavaScript—改变字体颜色和大小_js 展示字体大小和颜色-程序员宅基地

文章浏览阅读5.7k次。写一个定时器,每个一秒修改一次div内文本颜色和文字大小 最开始这个文字是默认大小,大小开始增大,当增大了6次以后, 文字大小开始缩小,缩小6次,文字在开始增大。首先改变字体颜色和大小.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="I..._js 展示字体大小和颜色