JS学习记录8,事件对象,事件的冒泡,事件的绑定,滚轮的事件,键盘的事件,获取鼠标坐标练习,使div可以跟随鼠标移动练习,拖拽练习,使文本框中不能有数字,div根据方向键移动,并解决事件对象兼容性问题

事件对象

当事件的响应被触发时,浏览器每次都会将一个事件对象作为实参传递给响应函数,在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标,键盘哪个按键被按下,鼠标滚轮滚动的方向等。
clientX可以获取鼠标指针的水平坐标
clientY可以获取鼠标指针的垂直坐标
获取鼠标在div里的坐标:

 window.onload = function () {
        /*
        *当鼠标在areaDiv中移动时,在showMsg中来显示鼠标坐标
        */
        //获取两个div
        var areaDiv = document.getElementById("areaDiv");
        var showMsg = document.getElementById("showMsg");
        //onmousemove该事件将会在鼠标在元素中移动时被触发
        areaDiv.onmousemove = function (event) {
            //在showMsg显示鼠标坐标
            var x = event.clientX;
            var y = event.clientY;
            showMsg.innerHTML = "此时鼠标坐标:x="+x+","+"y="+y;
        };
        };

效果:
鼠标坐标
在IE8中,事件函数被触发时,浏览器不会传递事件对象,在IE8及以下浏览器中,是将对象作为window对象的属性保存的。
即:

            var x = event.clientX;
            var y = event.clientY;

应该改为:

            var x = window.event.clientX;
            var y = window.event.clientY;

但是该方式火狐不兼容,所以应该这么改:

           if (!event){
                event =window.event;
            }
            var x = event.clientX;
            var y = event.clientY;

也可以

            event = event || window.event;
            var x = event.clientX;
            var y = event.clientY;

使div可以跟随鼠标移动

绑定鼠标移动事件,应该绑定给整个文档,以免鼠标移出div就不再跟随。

document.onmousemove = function(event){}

解决兼容问题后,再获取鼠标的坐标,设置div的偏移量。clientX与clientY获取的是鼠标在当前可见页面的坐标,div的偏移量,是相对于整个页面的,当出现滚动条时,div与鼠标会出现距离。所以应该使用pageXpageY可以获取鼠标相对于当前页面的坐标。
注意:如果想要让偏移量起作用,则需要开启box1的绝对定位。

var left = event.pageX;
var top = event.pageY;
box1.style.left = left + "px";
box1.style.top = top + "px";

但是这两个属性在IE8中并不支持,所以如果想要兼容IE8就不能使用,则可以这样修改。
先获取滚动条的滚动距离

var st = document.body.scrollTop;//chrome
var sl = document.body.scrollLeft;

chrome认为浏览器的滚动条时body的,可以通过body.scrollTop来获取,火狐等浏览器认为浏览器的滚动条是HTML的

var st = document.documentElement.scrollTop;//火狐等浏览器
var sl = document.documentElement.scrollLeft;

处理兼容性问题

var st = document.documentElement.scrollTop || document.body.scrollTop;
var sl = document.documentElement.scrollLeft || document.body.scrollLeft;

最后优化结果

var left = event.clientX;
var top = event.clientY;
box1.style.left = left +sl + "px";
box1.style.top = top +st + "px";

事件的冒泡(Bubble)

所谓的冒泡指的就是事件的向上传导,当后代元素事件被触发时,其祖先元素的相同事件也会被触发。在开发中,大部分情况冒泡都是非常有用的,如果不希望发生事件冒泡,可以通过事件对象来取消冒泡。
将事件对象的cancelBubble设置为true,即可取消冒泡

envent.cancelBubble = true;

事件的委派

事件的委派,指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。如果想要只绑定一次事件,即可应用到多个元素上,即使元素是后添加的,可以尝试将其绑定给元素的共同的祖先元素。
优点:事件的委派时利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能。
但是由于设置的面积很大,点击未期望的内容也会触发响应函数。
补充:target表示触发事件的对象。

//当点击的是ul中的class为link的对象则执行响应函数,否则不执行。
if(event.target.className == "link"){
   alert("单击响应函数");
}

事件的绑定

使用 对象.事件 = 函数 的形式绑定的响应函数,它只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,则后面的会覆盖掉前面的。
addEventListener()通过这个方法也可以为元素绑定响应函数。
参数:
第一个参数是事件的字符串,不要on;
第二个参数是回调函数,当事件被触发时该函数会被调用;
第三个参数是否在捕获阶段触发事件,需要一个布尔值,一般都传false。

btn.addEventListener("click",function(){
   alert(1);
},false);

使用addEventListener()方法可以同时为一个元素的相同事件同时绑定多个响应函数,这样当事件被触发时,响应函数将会按照函数的绑定顺序执行。
注意:该方法不支持IE8及以下的浏览器
在IE8中可以使用attachEvent()来绑定事件
参数:
第一个参数是事件的字符串,要on
第二个参数是回调函数

btn.attachEvent("onclick",function(){
   alert(1);
});

使用attachEvent()方法可以同时为一个元素的相同事件同时绑定多个响应函数,它是后绑定先执行,执行顺序和addEventListener()相反。
注意:该方法只支持IE浏览器
定义一个函数,用来为指定元素绑定响应函数,解决兼容性问题。

/*
        *addEventListener()中的this,是绑定事件的对象
        * attachEvent()中的this,是window
        * 需要统一两个方法的this
        */
        //参数:1、obj 要绑定事件的对象 2、eventStr 事件字符串(不要on) 3、callback 回调函数
        function bind(obj,eventStr,callback) {
            if(obj.addEventListener){
                obj.addEventListener(eventStr,callback,false);
            }else {
                obj.attachEvent("on"+eventStr,function () {
                    //在匿名函数中调用回调函数,这样就可以指定this
                    callback.call(obj);
                });
            }
        };
        //调用
        bind(btn,"click",function () {
            alert(1);
        })

事件的传播

微软公司认为,认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就是说事件应该在冒泡阶段执行。
网景公司认为,认为事件应该是由外向内传播,也就是当事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后再向内传播给后代元素,也就是说事件应该在捕获阶段执行。
W3C综合了两个公司的方案,将事件的传播分成了三个阶段。
1、捕获阶段,在捕获阶段时从最外层的祖先元素,向目标元素事件的捕获,但是默认情况下此时不会触发事件。
2、目标阶段,事件捕获到目标元素,捕获结束开始在目标元素上触发事件。
3、冒泡阶段,事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件。
注意:
1、如果希望在捕获阶段就触发事件,可以将addEventListener的第三个参数设置为true,但是一般不用。
2、IE8及以下的浏览器没有捕获阶段。

拖拽事件练习

当我们拖拽网页中的内容时,浏览器会默认搜索引擎中搜索内容,此时会导致拖拽功能异常,这个是浏览器提供的默认行为,如果不希望发生,则可以通过在onmousedown后添加return false来取消默认行为,但是对IE8不起作用。当调用一个元素的setCapture()方法以后,这个元素将会把下一次所有的鼠标按下相关的事件捕获到自身上。
注意:该方法只有IE支持,但在火狐中不会报错,而如果使用Chrome调用,会报错,所以需要做出判断。

   //以下为在IE8的添加的内容
        /*
        *当调用一个元素的`setCapture()`方法以后,这个元素将会把下一次所有的鼠标按下相关的事件捕获到自身上。
        */
        //设置box1绑定一个鼠标按下事件
        box1.setCapture();
            //以下为在IE8中的内容
            //当鼠标松开时,取消对事件的捕获
            box1.releaseCapture();
拖拽box1
window.onload = function () {
    /*
    拖拽box1元素流程:
    1、当鼠标在被拖拽元素上按下时,开始拖拽onmousedown
    2、当鼠标移动时被拖拽元素跟随鼠标移动onmousemove
    3、当鼠标松开时,被拖拽元素被固定在该位置onmouseup
    */
    //获取box1
    var box1 = document.getElementById("box1");
    //为box1绑定鼠标按下事件
    //当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
    box1.onmousedown = function (event) {
        /*
        *当调用一个元素的`setCapture()`方法以后,这个元素将会把下一次所有的鼠标按下相关的事件捕获到自身上。
        */
        //设置box1绑定一个鼠标按下事件
        if(box1.setCapture){
            box1.setCapture();
        }
        //求出div的偏移量 鼠标.clientX - 元素.offsetLeft
        //求出div的偏移量 鼠标.clientY - 元素.offsetTop
        //在按下就确定位置
        event = event||window.event;
        var ol = event.clientX - box1.offsetLeft;
        var ot = event.clientY - box1.offsetTop;
        //为document绑定一个onmousemove事件
        document.onmousemove = function (event) {
            event = event||window.event;
            //当鼠标移动时被拖拽元素跟随鼠标移动onmousemove
            //获取鼠标坐标
            var left = event.clientX -ol;
            var top = event.clientY -ot;
            //修改box1的位置
            box1.style.left = left+"px";
            box1.style.top = top+"px";
        }
        //为元素绑定一个鼠标松开事件
        document.onmouseup = function () {
            //当鼠标松开时,被拖拽元素被固定在该位置onmouseup
            //取消document的onmousemove事件
            document.onmousemove = null;
            //松开之后onmouseup还没停止,所以应该取消
            document.onmouseup =null;
            //当鼠标松开时,取消对事件的捕获
            if (box1.releaseCapture){
                box1.releaseCapture();
            }
        }
        /*
        * 当我们拖拽网页中的内容时,浏览器会默认搜索引擎中搜索内容,
        * 此时会导致拖拽功能异常,这个是浏览器提供的默认行为,
        * 如果不希望发生,则可以通过在onmousedown后添加return false来取消默认行为
        * 但是对IE8不起作用
        */
        return false;
    }
    //想要box2页可以拖拽,可以尝试写一个函数
}
拖拽函数

先获取想要拖拽的元素,然后将元素作为实参传递给这个函数再调用即可。

<script>
        window.onload = function () {
            var box1 = document.getElementById("box1");
            var box2 = document.getElementById("box2");
            drag(box1);
            drag(box2);
        };
        function drag(obj){
            obj.onmousedown = function (event) {
                if(obj.setCapture){
                    obj.setCapture();
                }
                event = event||window.event;
                var ol = event.clientX - obj.offsetLeft;
                var ot = event.clientY - obj.offsetTop;
                document.onmousemove = function (event) {
                    event = event||window.event;
                    var left = event.clientX -ol;
                    var top = event.clientY -ot;
                    obj.style.left = left+"px";
                    obj.style.top = top+"px";
                }
                document.onmouseup = function () {
                    document.onmousemove = null;
                    document.onmouseup =null;
                    if (obj.releaseCapture){
                        obj.releaseCapture();
                    }
                };
                return false;
            };
        }

    </script>

滚轮的事件

onmousewheel鼠标滚轮滚动时触发,但是火狐不支持,火狐中使用DOMMouseScroll来绑定滚动事件,该事件需要通过addEventListener()函数来实现。
event.wheelDelta获取滚轮滚动方向,向上为正值,向下为负值,但是火狐不支持,火狐中使用event.detail获取滚轮滚动方向,向上为负值,向下为正值。
实现当鼠标滚轮向下滚动时,box1变长,当滚轮向上滚动时,box1变短。

window.onload = function () {
            /*当鼠标滚轮向下滚动时,box1变长,当滚轮向上滚动时,box1变短*/
            var box1 = document.getElementById("box1");
            //为box1绑定一个鼠标滚轮滚动的事件
            box1.onmousewheel = function (event) {
                //火狐不支持onmousewheel,火狐中使用DOMMouseScroll来绑定滚动事件,
                // 该事件需要通过addEventListener()函数来实现
                event = event || window.event;
                //判断滚轮滚动方向
                //event.wheelDelta可以获取鼠标滚轮滚动的方向
                //向上150,向下-150,不看大小只看正负
                if(event.wheelDelta>0||event.detail<0){
                    box1.style.height = box1.clientHeight -20+"px";
                }else {
                    box1.style.height = box1.clientHeight +20+"px";
                }
                //wheelDelta火狐不支持,火狐中使用event.detail,向上-3,向下3
                //当鼠标滚轮向下滚动时,box1变长
                //当滚轮向上滚动时,box1变短
                event.preventDefault && event.preventDefault();
                //在火狐中取消默认行为,但是IE8不支持,所以要做判断
                return false;//取消默认行为
            }
            bind(box1,"DOMMouseScroll",box1.onmousewheel);
        }
        function bind(obj,eventStr,callback) {
            if(obj.addEventListener){
                obj.addEventListener(eventStr,callback,false);
            }else {
                obj.attachEvent("on"+eventStr,function () {
                    //在匿名函数中调用回调函数,这样就可以指定this
                    callback.call(obj);
                });
            }
        };

键盘的事件

键盘事件一般都会绑定给一些可以获取到焦点的对象,或者是document。
onkeydown 按键被按下,对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发;当onkeyup连续触发时,第一次和第二次之间会间隔长一点,其他的会非常快。这种设计是为了防止人误操作。
onkeyup 按键被松开。
keyCode 获取按键的编码,可以判断哪个按键被按下。
altKey、ctrlKey、shiftKey 这三个用来判断alt ctrl 和 shift 是否被按下,如果按下则返回true,否则返回false。

event.keyCode === 89 && event.ctrlKey//判断是不是同时按下ctrl和y健

在文本框中输入内容属于onkeydown的默认行为,如果在onkeydown中取消了默认行为,则输入的内容不会出现在文本框中。
使文本框中不能有数字

window.onload = function () {
            var inp = document.getElementsByTagName("input")[0];
            inp.onkeydown = function(event){
                event = event||window.event;
                //数字编码 48-57
                if(event.keyCode>=48 && event.keyCode<=57){
                    return false;
                }
            };
        };

结合定时器使div根据不同的方向键不同的方向移动

        window.onload = function () {
            //速度由定时器控制,方向由键盘控制
                var speed = 20;
                var dir = 0;
                setInterval(function () {
                    switch (dir) {
                        case 37:
                            box1.style.left=box1.offsetLeft-speed+"px"
                            break;
                        case 38:
                            box1.style.top=box1.offsetTop-speed+"px"
                            break;
                        case 39:
                            box1.style.left=box1.offsetLeft+speed+"px"
                            break;
                        case 40:
                            box1.style.top=box1.offsetTop+speed+"px"
                            break;
                    }
                },30)
            //给document绑定键盘事件
            document.onkeydown = function (event) {
                event = event || window.event;
                //左、上、右、下 37、38、39、40
                //当用户按了ctrl以后,速度加快
                if (event.ctrlKey) {
                    speed = 50;
                }else {
                    speed=10;
                }
                dir = event.keyCode;
            };
                //当按键松开时,div不再移动
            document.onkeyup = function () {
                dir = 0;
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小婵婵不怕鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值