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. Nexus Repository 搭建及使用

    Nexus Repository 是搭建maven的镜像的工具之一,在全球范围内使用挺广的. 一.Nexus 搭建过程 Nexus 镜像的搭建还是相对简单的,将下载的文件解压到相应的目录下,然后进入. ...

  2. Hadoop MapReduce编程 API入门系列之Crime数据分析(二十五)(未完)

    不多说,直接上代码. 一共12列,我们只需提取有用的列:第二列(犯罪类型).第四列(一周的哪一天).第五列(具体时间)和第七列(犯罪场所). 思路分析 基于项目的需求,我们通过以下几步完成: 1.首先 ...

  3. Java ServletContext详解

    转载: ServletContext,是一个全局的储存信息的空间,服务器开始,其就存在,服务器关闭,其才释放.request,一个用户可有多个:session,一个用户一个:而servletConte ...

  4. UVa 820 因特网带宽(最大流)

    https://vjudge.net/problem/UVA-820 题意: 给出所有计算机之间的路径和路径容量后求出两个给定结点之间的流通总容量. 思路: 裸的最大流问题.注意有个比较坑的地方,最后 ...

  5. UVa 120 煎饼

    https://vjudge.net/problem/UVA-120 题意:颠倒连续子序列,使之成为升序. 思路:按照从大到小的顺序,依次选择出一个数字进行分析: ①如果该数字已经在正确的位置上,则不 ...

  6. JVM内存管理的机制

    Eclipse崩溃,错误提示:MyEclipse has detected that less than 5% of the 64MB of Perm Gen (Non-heap memory) sp ...

  7. codeforces 55d//Beautiful numbers// Codeforces Beta Round #51

    题意:一个数能整除它所有的位上的数字(除了0),统计这样数的个数. 注意离散化,为了速度更快需存入数组查找. 不要每次memset,记录下已有的长度下符合条件的个数. 数位dp肯定是从高位到低位. 记 ...

  8. Ngnix location匹配规则

    Ngnix 站点:http://www.nginx.cn Location 匹配命令 ~ 波浪线表示执行一个正则匹配,区分大小写. ~* 表示执行一个正则匹配,不区分大小写. ^~ ^~表示普通字符匹 ...

  9. splice的多种用法

    (一)splice的多种用法: splice(n,m) 从索引n开始删除m个.返回删除项组成新数组 splice(n) 从索引n开始删除到末尾 splice(n,m,x) 从索引n开始删除m个,并且把 ...

  10. webService开发(JDK版)

    最近做社保查询的东西,然而这个是三个公司一起做的,需要调其他公司的接口,他们公司用了webService这个当年比较流行的技术,于是乎就研究了一下这个webService. HTTP协议 + XML方 ...