import { document } from "./browser";
import { isFn, noop, options } from "./util"; var globalEvents = {};
export var eventPropHooks = {}; //用于在事件回调里对事件对象进行
export var eventHooks = {}; //用于在元素上绑定特定的事件
//根据onXXX得到其全小写的事件名, onClick --> click, onClickCapture --> click,
// onMouseMove --> mousemove export var eventLowerCache = {
onClick: "click",
onChange: "change",
onWheel: "wheel"
};
/**
* 判定否为与事件相关
*
* @param {any} name
* @returns
*/
export function isEventName(name) {
return /^on[A-Z]/.test(name);
} export var isTouch = "ontouchstart" in document; export function dispatchEvent(e, type, end) {
//__type__ 在injectTapEventPlugin里用到
e = new SyntheticEvent(e);
if (type) {
e.type = type;
}
var bubble = e.type; var hook = eventPropHooks[bubble];
if (hook && false === hook(e)) {
return;
} var paths = collectPaths(e.target, end || document);
var captured = bubble + "capture";
options.async = true;
triggerEventFlow(paths, captured, e); if (!e._stopPropagation) {
triggerEventFlow(paths.reverse(), bubble, e);
}
options.async = false;
options.flushBatchedUpdates();
} function collectPaths(from, end) {
var paths = [];
do {
if (from === end) {
break;
}
var events = from.__events;
if (events) {
paths.push({ dom: from, events: events });
} } while ((from = from.parentNode) && from.nodeType === 1);
// target --> parentNode --> body --> html
return paths;
} function triggerEventFlow(paths, prop, e) {
for (var i = paths.length; i--;) {
var path = paths[i];
var fn = path.events[prop];
if (isFn(fn)) {
e.currentTarget = path.dom;
fn.call(path.dom, e);
if (e._stopPropagation) {
break;
}
}
}
} export function addGlobalEvent(name) {
if (!globalEvents[name]) {
globalEvents[name] = true;
addEvent(document, name, dispatchEvent);
}
} export function addEvent(el, type, fn, bool) {
if (el.addEventListener) {
// Unable to preventDefault inside passive event listener due to target being
// treated as passive
el.addEventListener(
type,
fn,
bool || false
);
} else if (el.attachEvent) {
el.attachEvent("on" + type, fn);
}
} var rcapture = /Capture$/;
export function getBrowserName(onStr) {
var lower = eventLowerCache[onStr];
if (lower) {
return lower;
}
var camel = onStr.slice(2).replace(rcapture, "");
lower = camel.toLowerCase();
eventLowerCache[onStr] = lower;
return lower;
} eventPropHooks.click = function (e) {
return !e.target.disabled;
}; /* IE6-11 chrome mousewheel wheelDetla 下 -120 上 120
firefox DOMMouseScroll detail 下3 上-3
firefox wheel detlaY 下3 上-3
IE9-11 wheel deltaY 下40 上-40
chrome wheel deltaY 下100 上-100 */
/* istanbul ignore next */
const fixWheelType =
"onmousewheel" in document
? "mousewheel"
: document.onwheel !== void 666 ? "wheel" : "DOMMouseScroll";
const fixWheelDelta =
fixWheelType === "mousewheel"
? "wheelDetla"
: fixWheelType === "wheel" ? "deltaY" : "detail";
eventHooks.wheel = function (dom) {
addEvent(dom, fixWheelType, function (e) {
var delta = e[fixWheelDelta] > 0 ? -120 : 120;
var deltaY = ~~dom.__wheel + delta;
dom.__wheel = deltaY;
e = new SyntheticEvent(e);
e.type = "wheel";
e.deltaY = deltaY;
dispatchEvent(e);
});
}; var fixFocus = {};
"blur,focus".replace(/\w+/g, function (type) {
eventHooks[type] = function () {
if (!fixFocus[type]) {
fixFocus[type] = true;
addEvent(
document,
type,
dispatchEvent,
true
);
}
};
});
/**
*
DOM通过event对象的relatedTarget属性提供了相关元素的信息。这个属性只对于mouseover和mouseout事件才包含值;
对于其他事件,这个属性的值是null。IE不支持realtedTarget属性,但提供了保存着同样信息的不同属性。
在mouseover事件触发时,IE的fromElement属性中保存了相关元素;
在mouseout事件出发时,IE的toElement属性中保存着相关元素。
但fromElement与toElement可能同时都有值
*/
function getRelatedTarget(e) {
if (!e.timeStamp) {
e.relatedTarget = e.type === "mouseover" ? e.fromElement : e.toElement;
}
return e.relatedTarget;
} function contains(a, b) {
if (b) {
while ((b = b.parentNode)) {
if (b === a) {
return true;
}
}
}
return false;
} String("mouseenter,mouseleave").replace(/\w+/g, function (type) {
eventHooks[type] = function (dom, name) {
var mark = "__" + name;
if (!dom[mark]) {
dom[mark] = true;
var mask = name === "mouseenter" ? "mouseover" : "mouseout";
addEvent(dom, mask, function (e) {
let t = getRelatedTarget(e);
if (!t || (t !== dom && !contains(dom, t))) {
var common = getLowestCommonAncestor(dom, t);
//由于不冒泡,因此paths长度为1
dispatchEvent(e, name, common);
}
});
}
};
}); function getLowestCommonAncestor(instA, instB) {
var depthA = 0;
for (var tempA = instA; tempA; tempA = tempA.parentNode) {
depthA++;
}
var depthB = 0;
for (var tempB = instB; tempB; tempB = tempB.parentNode) {
depthB++;
} // If A is deeper, crawl up.
while (depthA - depthB > 0) {
instA = instA.parentNode;
depthA--;
} // If B is deeper, crawl up.
while (depthB - depthA > 0) {
instB = instB.parentNode;
depthB--;
} // Walk in lockstep until we find a match.
var depth = depthA;
while (depth--) {
if (instA === instB) {
return instA;
}
instA = instA.parentNode;
instB = instB.parentNode;
}
return null;
} if (isTouch) {
eventHooks.click = noop;
eventHooks.clickcapture = noop;
} export function createHandle(name, fn) {
return function (e) {
if (fn && fn(e) === false) {
return;
}
dispatchEvent(e, name);
};
} var changeHandle = createHandle("change");
var doubleClickHandle = createHandle("doubleclick"); //react将text,textarea,password元素中的onChange事件当成onInput事件
eventHooks.changecapture = eventHooks.change = function (dom) {
var mask = /text|password/.test(dom.type) ? "input" : "change";
addEvent(document, mask, changeHandle);
}; eventHooks.doubleclick = eventHooks.doubleclickcapture = function () {
addEvent(document, "dblclick", doubleClickHandle);
}; export function SyntheticEvent(event) {
if (event.nativeEvent) {
return event;
}
for (var i in event) {
if (!eventProto[i]) {
this[i] = event[i];
}
}
if (!this.target) {
this.target = event.srcElement;
}
this.fixEvent();
this.timeStamp = new Date() - 0;
this.nativeEvent = event;
} var eventProto = (SyntheticEvent.prototype = {
fixEvent: function () { }, //留给以后扩展用
preventDefault: function () {
var e = this.nativeEvent || {};
e.returnValue = this.returnValue = false;
if (e.preventDefault) {
e.preventDefault();
}
},
fixHooks: function () { },
stopPropagation: function () {
var e = this.nativeEvent || {};
e.cancelBubble = this._stopPropagation = true;
if (e.stopPropagation) {
e.stopPropagation();
}
},
persist: noop,
stopImmediatePropagation: function () {
this.stopPropagation();
this.stopImmediate = true;
},
toString: function () {
return "[object Event]";
}
});
/* istanbul ignore next */
//freeze_start
Object.freeze ||
(Object.freeze = function (a) {
return a;
});
//freeze_end

anu - event的更多相关文章

  1. 如何利用ETW(Event Tracing for Windows)记录日志

    ETW是Event Tracing for Windows的简称,它是Windows提供的原生的事件跟踪日志系统.由于采用内核(Kernel)层面的缓冲和日志记录机制,所以ETW提供了一种非常高效的事 ...

  2. [.NET] C# 知识回顾 - Event 事件

    C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...

  3. Atitit 解决Unhandled event loop exception错误的办法

    Atitit 解决Unhandled event loop exception错误的办法 查看workspace/.metadata/.log org.eclipse.swt.SWTError: No ...

  4. Java模拟Windows的Event

    场景 开发中遇到一个场景,业务操作会不定时的产生工作任务,这些工作任务需要放入到一个队列中,而另外会有一个线程一直检测这个队列,队列中有任务就从队列中取出并进行运算. 问题 业务场景倒是简单,只不过这 ...

  5. 事件EVENT与waitforsingleobject的使用

    事件event与waitforsingleobject的配合使用,能够解决很多同步问题,也可以在数据达到某个状态时启动另一个线程的执行,如报警. event的几个函数: 1.CreateEvent和O ...

  6. 火狐浏览器中event不起作用解决办法--记录(一)

    今天遇到了这个问题.IE,谷歌下都没问题,但在FF下却不起作用,很郁闷查了半天,看别人博文写了老长,结果试了要么起作用,但太麻烦,要么不起作用,说了那么多跟没说一样. 其实只要这一句代码就行:e=ar ...

  7. Event事件

    妙味课堂-Event事件 1.焦点:当一个元素有焦点的时候,那么他就可以接受用户的输入(不是所有元素都能接受焦点) 给元素设置焦点的方式: 1.点击 2.tab 3.js 2.(例子:输入框提示文字) ...

  8. Event Sourcing Pattern 事件源模式

    Use an append-only store to record the full series of events that describe actions taken on data in ...

  9. 严重: Exception sending context initialized event to listener instance of class

    问题描述:Exception sending context initialized event to listener instance of class org.springframework.w ...

随机推荐

  1. 线程面试top50题

    转载:java线程面试题: 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.大多数待遇丰厚的Java开 ...

  2. 使用 PYTHON 为 PIP 搭建 HTTP 代理

    在一台没有 Root 权限的机器上,部署使用 Python 编写的服务,似乎只有 virtualenv 一条路可以选了. 当然我见过一些同事会在自己的家目录编译一个,然后设置一下 $PATH ,但是从 ...

  3. 重拾IP路由选择:CCNA学习指南中的IP路由选择

    IP路由选择技术 是网络技术的核心部分,也是目前研究的热点,其中的 动态路由选择协议 比如RIPv1,RIPv2,OSPF等,解决了数据在网络中转递的诸多问题. 在TCP/IP协议详解的学习过程中,我 ...

  4. Java I/O学习 文件读写工具

    import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import jav ...

  5. Spring/Spring MVC/Spring Boot的区别

    1.spring boot更简单,容易上手: 2.spring boot对第三方技术进行了很好的封装,提供了大量的第三方接口: 3.通过依赖配置,不需要XML等配置文件: 4.提供了安全性等特性. S ...

  6. Python -- Scrapy 框架简单介绍(Scrapy 安装及项目创建)

    Python -- Scrapy 框架简单介绍 最近在学习python 爬虫,先后了解学习urllib.urllib2.requests等,后来发现爬虫也有很多框架,而推荐学习最多就是Scrapy框架 ...

  7. C#两种数据类型

    C#的两种类据类型:值类型和引用类型   什么是值类型,什么是引用类型 概念:值类型直接存储其值,而引用类型存储对其值的引用.部署:托管堆上部署了所有引用类型. 引用类型:基类为Objcet 值类型: ...

  8. [Java学习] Java Object类

    Object 类位于 java.lang 包中,是所有 Java 类的祖先,Java 中的每个类都由它扩展而来. 定义Java类时如果没有显示的指明父类,那么就默认继承了 Object 类.例如: 1 ...

  9. TortoiseXX 与TotalCommander (TC)的图标问题

    TortoiseXX通过overlay图标标志文件或文件夹是否被修改等状态,非常有用. 可惜TotoalCommander上,这些图标都没有显示. 其实,只需要在TC的菜单 配置->显示-> ...

  10. WPF 的 数据源属性 和 数据源

    (一)数据源(数据对象)属性 :path 或  path的值(path=VM.Property或M.Property),通常具有通知功能(特例除外). (二)path不能孤立而存在,它一定具有所归属的 ...