美文网首页
事件机制(高级)

事件机制(高级)

作者: 致自己_cb38 | 来源:发表于2018-11-18 12:32 被阅读0次

    1、事件

    click
    dbclick
    mouseover
    mouseout
    mouseenter
    mouseleave
    onload
    change
    blur
    input
    submit
    focus
    scroll
    resize

    2、 如果对一个标签设置了点击事件之后,没有效果?

    • 有没有报错。
    • 事件有没有写错
    • 元素有没有获取到

    3、document是整个文档的父级。

    event对象是事件发生的时候产生的一个对象。但是FF不支持。

    4、获取一个兼容的event对象。

    • var ev = ev || event ;
    • event.clientX:相对于窗口可视区域的X坐标
      event.clientY:相对于窗口可视区域的Y坐标

    5、封装的鼠标点击位置的坐标获取方法。

    function getPos(ev){
        var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft ||   document.body.scrollLeft;
        var scrollTop = window.pageYOffset || document.documentElement.scrollTop ||     document.body.scrollTop;
        return {
            left:scrollLeft+ev.clientX,
            top:scrollTop + ev.clientY
        };
    }
    

    6、事件流

    事件冒泡:事件冒泡就是内层元素的事件会随着文档流向上冒泡,如果上层具有相同的事件,那么这个事件也会响应。直到冒泡到顶层对象document。

    event.cancelBubble = true; //停止冒泡
    

    eg:仿select

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            div{
                width:400px;
                height:200px;
                background: #ccc;
                display: none;
            }
        </style>
    </head>
    <body>
        <button>选择</button>
        <div></div>
    </body>
    <script>
        var btn = document.getElementsByTagName('button')[0];
        var div = document.getElementsByTagName('div')[0];
        btn.onclick = function(ev){
            var ev = ev||event;
            div.style.display = 'block';
            ev.cancelBubble = true;
        };
        document.onclick = function(){
            div.style.display = 'none';
        };
    </script>
    </html>
    

    7、 键盘事件

    • keydown
      keypress
      keyup
    • 按键的编码 。 ev.keyCode
    • 按键编码是连续的。0-9,a-z
    • ctrlKey、shiftKey、altKey 这个是键盘事件的功能键,如果这些键按下的话,对应的key值是true。这样可以实现多按键操作。(Ctrl+enter ctrl+c ctrl+v……)
      eg:模拟坦克
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            div{
                width:50px;
                height:50px;
                background: green;
                position: absolute;
            }
            span{
                display: block;
                background: red;
                height:20px;
                width:20px;
                border-radius: 20px;
                display:none;
                position: absolute;
            }
        </style>
    </head>
    <body>
        <div></div>
    <script>
        var div = document.querySelector('div');
        var is_left = false;
        var is_right = false;
        var is_top = false;
        var is_bottom = false;
        document.onkeydown = function(ev){
            var ev = ev || event;
            switch(ev.keyCode){
                case 37:
                    is_left = true;
                    break;
                case 38:
                    is_top = true;
                    break;
                case 39:
                    is_right = true;
                    break;
                case 40:
                    is_bottom = true;
                    break;
                case 32:
                    var span = document.createElement('span');
                    //子弹的初始位置
                    span.style.display = 'block';
                    span.style.left =( div.offsetLeft + div.offsetWidth/2) - 10 + 'px'
                    span.style.top = div.offsetTop - 20 + 'px'
                    document.body.appendChild(span);
                    break;
                default:
                    break;
            }
        };
        document.onkeyup = function(){
            is_left = is_bottom = is_top = is_right = false;
        }
        setInterval(function(){
            //按键移动
            if(is_left){
                div.style.left = div.offsetLeft - 10 + 'px';
            }
            if(is_top){
                div.style.top = div.offsetTop - 10 + 'px';
            }
            if(is_right){
                div.style.left = div.offsetLeft + 10 + 'px';
            }
            if(is_bottom){
                div.style.top = div.offsetTop + 10 + 'px';
            }
            var s = document.getElementsByTagName('span');
            //子弹移动
            for(var i =0;i<s.length;i++){
                s[i].style.top = s[i].offsetTop - 2 + 'px';
            }
        },30);
    </script>
    </body>
    </html>
    

    eg:只能输入数字的输入框

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        电话号码:<input type="text">
    </body>
    <script>
        var oin = document.querySelector('input');
        oin.onkeydown = function(ev){
            var ev = ev||event;
            if((ev.keyCode<48 || ev.keyCode>57) && ev.keyCode!=8){
                return false;
            }
        };
    </script>
    </html>
    

    8、鼠标右键的菜单事件 on contextmenu

    9、return false 或preventDefault()能够阻止事件的默认行为。

    10、拖拽事件

    复合事件:鼠标按下——鼠标移动——鼠标放开
    eg:

    var  d = document.querySelector('div');
        d.onmousedown = function(ev){
            var ev = ev || event;
            var x = ev.clientX - d.offsetLeft;
            var y = ev.clientY-d.offsetTop;
            d.onmousemove = function(ev){
                var ev = ev || event;
                d.style.left = ev.clientX - x + 'px';
                d.style.top = ev.clientY - y + 'px';
            };
            d.onmouseup = function(){
                d.onmousemove = function(){};
            };
        };
    

    11、事件绑定:给元素添加一个事件。

    div.onclick = function(){};

    • 上面这种事件的添加方式DOM0级的事件方式。
    • 这种方式每一种事件都只能添加一个。如果添加多个,那么只有后添加的会生效。本质上是覆盖。

    12、怎么去添加多个相同事件事件。

    • IE :
      attachEvent(对象,事件);
    • FF,chrome:
      addEventListener(对象,事件(不加on),是否捕获)
      第三个参数:是否捕获。默认是false。在冒泡阶段执行。
      如果这个参数是true,那么函数是在捕获阶段执行。
      取消事件监听:removeEventListener
      eg:封装事件监听
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    
    </body>
    <script>
        //对象  事件  函数  是否捕获
        function myEventListener(obj,e,func,is_capture){
            if(obj.attachEvent){
                obj.attachEvent('on'+e,func);
            }else{
                if(is_capture){
                    obj.addEventListener(e,func,is_capture);
                }else{
                    obj.addEventListener(e,func);
                }
            }
        }
        myEventListener(document,'click',fun1);
        myEventListener(document,'click',function(){
            console.log(2);
        });
        function fun1(){
            console.log(1);
            console.log(this);
        }
        fun1(); //1 window
    </script>
    </html>
    

    13、setCapture可以将鼠标事件锁定在指定的元素上,当元素捕获了鼠标事件后,该事件只能作用在当前元素上。

    • 以下情况会导致事件锁定失败:

      • 当窗口失去焦点时,锁定的事件,自动就会取消。
        alert也会导致事件的锁定取消。解决办法是在alert之后再次锁定。
      • 鼠标右键也会导致事件解锁。
    • setCapture只可以作用于以下事件:
      onclick
      ondblclick
      onmousedown
      onmouseup
      onmouseover
      onmouseout
      setCapture不可作用于键盘等其它事件,只能作用于鼠标事件。主要用于: onmouseover 与 onmouseout 事件。

    • setCapture该法是IE浏览器专有。

    • setCapture 使用格式

      • setCapture 有一个布尔值参数,用于设置是否捕获其子元素的鼠标事件。
           当参数是ture时 ,当前元素会捕获其内的所有子元素的鼠标事件,即指定元素内的子元素不会触发鼠标事件,也就是当前元素内的子元素与当前元素外的元素一致。
          当参数为false时,当前元素不会捕获该其内的所有子元素的鼠标事件。容器内的对象能够正常地触发事件和取消冒泡。

    案例

    • 完善鼠标移动
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            .outer{
                width:800px;
                height:400px;
                margin:100px;
                background: #ccc;
                position: relative;
                left:50px;
            }
            div div{
                width:100px;
                height:100px;
                background: red;
                position: absolute;
            }
        </style>
    </head>
    <body>
        <div class="outer">
            <div></div>
        </div>
    </body>
    <script>
        var div = document.getElementsByClassName('outer')[0].children[0];
        var outer =  document.getElementsByClassName('outer')[0];
        outer.onmousemove = function(ev){
            var ev = ev || event;
            var pos = getPos(ev);
            //元素到边框的距离
            var l = pos.left - this.offsetLeft;
            var t = pos.top- this.offsetTop;
            //判断元素到边框的边界值
            if(l>=parseInt(getStyle(this,"width"))-div.offsetWidth){
                l = parseInt(getStyle(this,"width"))-div.offsetWidth;
            }
            if(t>=parseInt(getStyle(this,"height"))-div.offsetHeight){
                t = parseInt(getStyle(this,"height"))-div.offsetHeight;
            }
            div.style.left =  l+ 'px';
            div.style.top = t+'px';
        };
        function getStyle(obj,style){
                if(obj.currentStyle){
                    return obj.currentStyle[style];
                }else{
                    return getComputedStyle(obj,null)[style];
                }
            }
        function getPos(ev){
            var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft ||   document.body.scrollLeft;
            var scrollTop = window.pageYOffset || document.documentElement.scrollTop ||     document.body.scrollTop;
            return {
                left:scrollLeft+ev.clientX,
                top:scrollTop + ev.clientY
            };
        }
    </script>
    </html>
    
    • 多物体跟随鼠标移动
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
    
                div{
                    width:20px;
                    height:20px;
                    border-radius: 20px;
                    background: red;
                    position: absolute;
                }
        </style>
    </head>
    <body>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </body>
    <script>
    var div = document.getElementsByTagName('div');
    document.onmousemove = function(ev){
        var ev = ev||event;
        for(var i=div.length-1;i>=0;i--){
            if(i==0){
                //获取第一个小圆的位置
                div[i].style.left= getPos(ev).left +'px';
                div[i].style.top= getPos(ev).top+'px';
            }else{
                //获取每个小圆的位置
                div[i].style.left= parseInt(div[i-1].offsetLeft) +'px';
                div[i].style.top= parseInt(div[i-1].offsetTop)+'px';
            }
        }
    };
    function getPos(ev){
        var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft ||   document.body.scrollLeft;
        var scrollTop = window.pageYOffset || document.documentElement.scrollTop ||     document.body.scrollTop;
        return {
            left:scrollLeft+ev.clientX,
            top:scrollTop + ev.clientY
        };
    }
    </script>
    </html>
    
    • 兼容拖拽
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            *{
                margin:0;
                padding:0;
            }
            div{
                position: absolute;
                width:100px;
                height:100px;
                border-radius: 100px;
                background:cyan;
            }
        </style>
    </head>
    <body>
        dnasjkndjnasdlsajl
        <div>ahdhawdiuqhwui</div>
        dsanbhjdbjkashui
    </body>
    <script>
        var div = document.querySelector('div');
        //拖拽
        div.onmousedown = function(ev){
             var ev =  ev || event;
            //计算鼠标点击的位置相对于目标的位置
            var x = ev.clientX - div.offsetLeft;
            var y = ev.clientY - div.offsetTop;
            //判断元素是否捕捉
            var dest = div.setCapture ? div : document;
            dest.onmousemove = mousemove;
            dest.onmouseup = mouseup;
            function mousemove(ev){
                var ev = ev || event;
                //获取元素相对于浏览器的距离
                var left =  ev.clientX - x;
                var top = ev.clientY - y;
                //偏正超出范围
                if(left<0){
                    left = 0;
                }else if(left>window.innerWidth-div.offsetWidth){
                    left = window.innerWidth-div.offsetWidth;
                }
                if(top<0){
                    top = 0;
                }else if(top>window.innerHeight-div.offsetHeight){
                    top = window.innerHeight-div.offsetHeight;
                }
                div.style.left = left + 'px';
                div.style.top = top + 'px';
                if(div.setCapture){
                    div.setCapture();
                }
            };
            function mouseup(){
                this.onmousemove = null;
                this.onmouseup = null;
            }
            return false;
        };
    </script>
    </html>
    

    相关文章

      网友评论

          本文标题:事件机制(高级)

          本文链接:https://www.haomeiwen.com/subject/rnawfqtx.html