js的事件机制

1事件机制

1.1常见事件类型
鼠标事件类型
onclick
ondblclick

onmousedown:鼠标按下时触发
onmousemove:鼠标移动时触发
onmouseup:鼠标抬起时触发

onmouseover:鼠标移到元素上时触发
onmouseout:鼠标移出元素时触发

onmouseenter:鼠标移入元素内触发,触发一次
onmouseleave:鼠标移出元素时触发一次

oncontextmenu:鼠标右键时出现菜单时触发

键盘事件类型
onkeydown:当用户按下键盘上任意键触发,如果按住不放,会重复触发
onkeypress:当用户按下键盘上的字符键触发,如果按住不放,会重复触发
onkeyup:当用户释放键盘上的键触发

HTML事件

onload:当页面(包含图片资源、音频、视频等资源)完全加载后在window 上面触发,或当框架集加载完毕后在框架集上触发。
onresize:窗口调整大小是触发
onscroll:当窗口的滚动条滚动时触发

HTML 表单事件
onselect: 当用户选择文本框(input 或textarea)中的一个或多个字符触发并松开鼠标时触发
onchange: 当文本框(input 或textarea)内容改变且失去焦点后触发或者Select 选中的内容变化
oninput:当用户输入是开始执行
onfocus:当元素获取焦点时触发
onblur:当元素失去焦点时触发

focus/blur事件可以用在window上,当用户切出标签或者最小化win窗口时,触发blur,当用户切回标签或者切回窗口时触发。

onsubmit:当用户提交(单击提交按钮)表单时触发
onreset:当用户点击reset按钮时触发

模拟事件
模拟事件就是和事件触发时的效果一样,但不是事件而是对象的一个方法。

input.focus() 让input获取焦点
input.blur 让input失去焦点

button.click() 让按钮等元素被单击

form.submit() 让表单被提交
form.reset() 让表单被重置


1.2事件流
1.2.1事件流原理
事件流分三个阶段:事件捕获阶段、目标阶段、冒泡阶段
事件捕获阶段:当一个事件发生了,从HTML最外层(body)向目标元素靠近的阶段。
目标阶段:事件处于目标元素时
冒泡阶段:事件从目标元素流向body的阶段

事件流原理


事件处理程序:事件处理程序就是对一个事件进行响应的程序。开发者可以通过绑定的方式给一个元素添加一个事件处理程序。
dom.addEventListener(eventType,listener,useCapture):给元素添加一个事件监听者。
eventType:事件类型
listener:监听者 => 监听程序
useCapture:执行时机。true:捕获阶段执行 false:冒泡阶段执行

在事件流动的过程中,开发者可以绑定事件处理程序。

1.2.2兼容性
addEventListener 
    IE    非IE
addEventListener    IE9、IE10、IE11、Edge ✔     Chrome/firefox/safari/opera ✔
attachEvent    IE5、IE6、IE7、IE8 ✔    ✘

attachEvent的事件处理程序默认就是冒泡阶段执行,IE5-IE8不支持捕获阶段。

function addEvent(aDom,type,fun){
    if(aDom.addEventListener){
        aDom.addEventListener(type,fun,false);
    }else if(aDom.attachEvent){
        aDom.attachEvent("on"+type,fun);
    }else{
        aDom.setAttribute("on"+type,fun);
    }
}

可以给一个Dom设置多个监听者,先监听的先处理。
// 可以给一个对象设置多个监听者
        oMain.addEventListener("click",function(){
            console.log("main1")
        },false);
        
        oMain.addEventListener("click",function(){
            console.log("main2")
        },false);

1.3事件对象
事件对象是事件执行过程中的一个对象,包含事件的一些特定信息。
一般鼠标事件产生MouseEvent对象,键盘事件产生KeyboardEvent,MouseEvent和KeyBoardEvent都继承了Event对象,其中Event对象存储共有的属性。

type:事件类型
cancelBubble:关闭冒泡机制
target/srcElement:目标元素

1.3.1事件的目标元素
target/srcElement 可以获取事件的目标元素,其存在兼容性。
e.target for w3c/ie9/ie9+
e.srcElement for ie6/ie7/ie8

var target = e.target || e.srcElement

1.3.2阻止事件冒泡
阻止事件冒泡就是在事件的冒泡阶段,不在让事件继续向上传递。
e.stopPropagation for w3c/ie9/ie9+
e.cancelBubble for ie6/ie7/ie8

function stopBubble(event){
    if(event.stopPropagation){
        // for w3c/ie9/ie9+
        event.stopPropagation();
    }else{
        event.cancelBubble = true;
    }
}

1.3.3阻止默认事件
一些元素例如a、submit、reset等元素都存在默认事件,如果要阻止默认事件
event.preventDefault
event.returnValue = false

在事件处理程序中,如果让事件处理程序直接返回false,可以阻止默认事件。且兼容ie6/ie7/ie8
<a id="test" href="###" onclick="javascript:return false;">百度</a>


1.3.4事件委托(事件代理)

通俗地讲,就是当你需要完成某件事时,由于时间或者其他原因导致你不能直接去做这件事,此时你委托别人帮你完成这件事。帮你完成这件事的人就是委托者。

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件

addEvent(oMsgs,"click",function(event){
        var e = event||window.event;
        var target = e.target || e.srcElement;
        // console.log(target);
        if(target.nodeName.toLowerCase() === 'a'){
             
            var oLi = target.parentNode.parentNode;
            
            var start = oLi.offsetHeight;
             var end = 0;
             var change = end - start;
    
             animateFn(start,change,oLi,function(){
                 oMsgs.removeChild(oLi);
             });
        }
        
        stopBubble(e);
    });

1.3.5MouseEvent
clientX/clientY
screenY/screen

1.3.6KeyboardEvent
keyboardevent中特有属性
key:表示按键盘上的任意键
keyCode:键盘标号。a-65/回车-13/空格-32/
crtlKey/altKey/shiftKey:默认是false,如果按了就是true

// 添加快捷键ctrl+enter提交
    addEvent(document,"keyup",function(event){
        var e = event||window.event;
        
        if(e.ctrlKey && e.keyCode == 13){
            // console.log("提交");
            sendMsg();
        }
    });


1.4DOM ready
DOMContentLoaded表示文档结构加载完成时执行,不等待stylesheets, images, and subframes加载结束。我们把这个过程称为DOM ready。

ie6/7/8 浏览器通过document的onreadystatechange事件监测dom是否加载完成

function addDomContentLoadedEvent(fn){
    // for w3c
    if(document.addEventListener){
        console.log("addEventListener");
        document.addEventListener("DOMContentLoaded",function(event){
            fn && fn(e);
        },false);
    }else if(document.attachEvent){
        // for ie6/7/8
        document.attachEvent("onreadystatechange",function(){
            if(document.readyState === 'complete'){
                fn && fn(window.event);
            }
        });
    }
}

1.5MouseWheel
onmousewheel:当鼠标滚轮滚动时触发,ie6/7/8/9/9+、edge、chrome、safari、opera
wheelDelta:表示滚轮的滚动,向上滚动一格+120;向下滚动一格-120


firefox 通过DOMMouseScroll事件支持。
detail:表示滚动的滚动,向上滚动一格-3;向下滚动一格+3

function wheelFn(fn){
    
    var down = false;
    if(window.navigator.userAgent.indexOf("Firefox") > -1){
        document.addEventListener("DOMMouseScroll",function(event){
            var e = event || window.event;
            
            if(e.detail > 0){
                down = true;
            }else{
                down = false;
            }
            
            fn && fn(down);
            
        },false);
    }else{
        document.onmousewheel = function(event){
            var e = event||window.event;
            
            console.log(e.wheelDelta);
            if(e.wheelDelta < 0){
                down = true;
            }else{
                down = false;
            }
            
            fn && fn(down);
        }
    }
}


1.6TouchEvent
在移动端(手机、平板),可以通过手势的来操作设备。
touchstart:当手指触摸屏幕时触发;即使已经有一个手指放在了屏幕上也会触发。
touchmove:当手指在屏幕上滑动时连续的触发。在这个事件发生期间,调用preventDefault()可阻止滚动。
touchend:当手指从屏幕上移开时触发。

touchcanel:当手持设备来电话、自动关机时触发,一般不用。

Touch事件也拥有事件对象(TouchEvent),其中包含一个Touches数组,里面存的是手指(Touch)

Touch中有一些属性
clientX:触摸目标在视口中的X坐标。
clientY:触摸目标在视口中的Y坐标。
identifier:表示触摸的唯一ID。
pageX:触摸目标在页面中的x坐标。
pageY:触摸目标在页面中的y坐标。
screenX:触摸目标在屏幕中的x坐标。
screenY:触摸目标在屏幕中的y坐标。
target:触摸的DOM节点坐标

oMain.addEventListener("touchstart",function(event){
            // event是TouchEvent类型
            console.log(event);
            var touch = event.touches[0];
            
            var startX = touch.clientX;
            var startY = touch.clientY;
            
            var left = this.offsetLeft;
            var top = this.offsetTop;
            
            function move(event){
                var touch = event.touches[0];
                
                var endX = touch.clientX;
                var endY = touch.clientY;
                
                var dltX = endX - startX;
                var dltY = endY - startY;
                
                this.style.left = (left + dltX) +'px';
                this.style.top = (top+dltY)+'px';
            }
            
            oMain.addEventListener("touchmove",move,false);
            
            oMain.addEventListener("touchend",function(){
                // console.log("end");
                oMain.removeEventListener("touchmove",move,false);
            },false);

        },false);

研究Touch.js Hammer.js

1.7碰撞检测
[1]一定要定位
[2]一定要计算上下左右的距离


1.7.1设备相关(C)
window.addEventListener("deviceorientation",function(){
    div1.innerHTML=event.alpha;
    // alpha,beta,gamma
},false)

来源:https://www.cnblogs.com/wwthuanyu/p/10974187.html
原文地址:https://www.cnblogs.com/ympjsc/p/12285280.html