🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> 没有jquery情况下,使用原生js去写一个事件是很烦的,各种兼容和封装,结果还不一定能考虑的那么全,这时造轮子还不如使用现成的轮子,当然作为一个前端, 即使不造,也要知道如何写的,具体look at the following.. ## 一、事件兼容性 **1、添加事件** ~~~ // 其他:addEventListener // IE:attachEvent /* @param ele object(元素对象) @param type string(事件类型) @param handler function(处理函数) */ function addEventFn(ele, type, handler) { if(ele.addEventListener) { ele.addEventListener(type, handler, false); } else if(ele.attachEvent) { ele.attachEvent('on'+type, handler); } else { ele['on'+type] = handler; } } addEventFn(document.body, 'click', function(e) { // e是W3C标准,window.event针对ie浏览器 e = e || window.event; // 事件目标 var target = e.target || e.srcElement; // 阻止事件冒泡 if(e.stopPropagation) { e.stopPropagation(); // W3C标准 } else { e.cancelBuble = true; // 针对IE } // 阻止默认事件 if(e.preventDefault) { e.preventDefault(); // W3C标准 } else { e.returnValue = false; // 针对IE } }); ~~~ **2、删除事件** ~~~ // 其他:removeEventListener // IE:detachEvent /* @param ele object(元素对象) @param type string(事件类型) @param handler function(处理函数) */ function removeEventFn(ele, type, handler) { if(ele.removeEventListener) { ele.removeEventListener(type, handler, false); } else if(ele.detachEvent) { ele.detachEvent('on'+type, handler); } else { ele['on'+type] = ''; } } function alertFn() { alert(1); } addEventFn(document.body, 'click', alertFn); removeEventFn(document.body, 'click', alertFn); ~~~ **3、触发事件** ~~~ // W3C标准:dispatchEvent // 低版本IE:fireEvent(IE8及以下) function addEventFn(ele, type, handler) { if(ele.addEventListener) { ele.addEventListener(type, handler, false); } else if(ele.attachEvent) { ele.attachEvent('on'+type, handler); } else { ele['on'+type] = handler; } } addEventFn(document.body, 'click', function() { alert(1); }); /* @param ele object(元素对象) @param sort string(事件分类) @param type string(事件类型) */ function triggerEventFn(ele, sort, type) { if(ele.dispatchEvent) { var evt = document.createEvent(sort); evt.initEvent(type, true, true); // initEvent(eventType, canBubble, cancelable) ele.dispatchEvent(evt); } else { var evt = document.createEventObject(); ele.fireEvent('on'+type, evt); } } triggerEventFn(document.body, 'HTMLEvents', 'click'); ~~~ **4、滚轮事件** ~~~ // 其他:mousewheel // 火狐:DOMMouseScroll var mousewheel = document.mozHidden != false ? 'mousewheel' : 'DOMMouseScroll'; // document.mozHidden是firefox的私有属性 addEventFn(document, mousewheel, function() { e = e || window.event; var delta = e.wheelDelta ? (e.wheelDelta / 120) : (- e.detail / 3); // 使滚轮滚动的值为1 if(delta > 0) { console.log('向上滚动'); } else { console.log('向下滚动'); } }); // jquery $('.box').on('mousewheel DOMMouseScroll', function(e) { var delta = e.originalEvent.wheelDelta ? (e.originalEvent.wheelDelta / 120) : (- e.originalEvent.detail / 3); if(delta < 0) { console.log('向下'); } else { console.log('向上'); } }); ~~~ **5、鼠标左中右事件** ~~~ // 阻止右键菜单 document.oncontextmenu = function(e) { e = window.event || event; if(e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } } // 鼠标点击 document.body.onmousedown = function(e) { e = window.event || event; switch (e.button) { case 0: alert('点击了左键'); break; case 1: alert('点击了中键'); break; case 2: alert('点击了右键'); break; default: alert('没有效果'); break; } } ~~~ **6、DOM加载完成** ~~~ function ready(fn) { if (document.readyState != 'loading'){ fn(); } else if (document.addEventListener) { document.addEventListener('DOMContentLoaded', fn); } else { document.attachEvent('onreadystatechange', function() { if (document.readyState != 'loading') fn(); }); } } ~~~ **7、触发事件** ~~~ if (document.createEvent) { var event = document.createEvent('HTMLEvents'); event.initEvent('change', true, false); el.dispatchEvent(event); } else { el.fireEvent('onchange'); } ~~~ ## 二、H5新出事件 **1、touch事件** ~~~ // 手指在box容器中点击时的记录 var startX, startY; $('.box').on("touchstart", function(e) { startX = e.originalEvent.changedTouches[0].pageX; // 记录 最初点击时第一个触摸点的x坐标 startY = e.originalEvent.changedTouches[0].pageY; // 记录 最初点击时第一个触摸点的y坐标 }); // 阻止touchmove时的box默认事件 $('.box').on('touchmove', function(e) { e.preventDefault(); }); // 记录/操作 当手指离开的操作 $('.box') $('.box').on("touchend", function(e) { var moveEndX = e.originalEvent.changedTouches[0].pageX; // 手指离开时的x坐标 var moveEndY = e.originalEvent.changedTouches[0].pageY; // 手指离开时的y坐标 var X = moveEndX - startX; // 离开时的x坐标 - 开始触摸的x坐标 = 横向偏移值 var Y = moveEndY - startY; // 离开时的y坐标 - 开始触摸的y坐标 = 纵向偏移值 if ( Math.abs(X) > Math.abs(Y) && X > 0 ) { // 从左到右 alert("left 2 right"); } else if ( Math.abs(X) > Math.abs(Y) && X < 0 ) { // 从右到左 alert("right 2 left"); } else if ( Math.abs(Y) > Math.abs(X) && Y > 0) { // 从上到下 alert("top 2 bottom"); } else if ( Math.abs(Y) > Math.abs(X) && Y < 0 ) { // 从下到上 alert("bottom 2 top"); } else{ alert("just touch"); } }); ~~~ **2、drag事件** 在拖动目标上触发事件 (源元素): ondragstart - 用户开始拖动元素时触发 ondrag - 元素正在拖动时触发 ondragend - 用户完成元素拖动后触发 释放目标时触发的事件: ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件 ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件 ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件 ondrop - 在一个拖动过程中,释放鼠标键时触发此事件 dataTransfer对象(了解就行了): dropEffect 设置放下效果(copy move link none) effectAllowed 允许的效果 (copy move link copyLink copyMove linkMove allnone uninitialized(默认值,等同于all)) files FileList对象 setDragImage() setData() getData() clearData() 详细 [【传送门】](https://segmentfault.com/a/1190000007336316)