JavaScript事件基础(事件对象,键盘,鼠标,冒泡)

事件对象

什么是event对象和事件冒泡
  • 获取事件的详细信息:鼠标位置,键盘按键
  • 例子:获取鼠标位置:clientX
  • document的本质:document.childNodes[0].tagName
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <script type="text/javascript">
        window.onload = function() {
            document.body.onclick = function() {
                alert('a');
            };
        };
    </script>
</body>
</html>
点击网页,是没有反应的,因为body里面什么也没有啊,没有被撑开,但是如果把document.body.onclick 换成document.onclick,就可以了,因为document代表的是整个网页啊。

关于document

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript">
        window.onload = function() {
            alert(document.childNodes[0].tagName);
        };
    </script>
</head>
<body>
</body>
</html>
alert(document.childNodes[0].tagName);// !
alert(document.childNodes[1].tagName);// HTML
DOCUTYPE其实也是一个节点,而且,DOCUTYPE和HTML两个节点有个共同的父级,就是document,理解为整个网页!
所以,以后给整个页面加事件的时候,一定要给document加,而不是body

事件对象

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript">
        window.onload = function() {
            document.onclick = function() {
                alert(event.clientX + ',' + event.clientY);
            };
        };
    </script>
</head>
<body>
</body>
</html>
在FireFox中,不认识event,在浏览器中,事件函数都带有一个参数的,就是 事件对象,系统传来的。

最终的兼容方案:

var oEvent = ev||event;

window.onload = function() {
    document.onclick = function(ev) {
        var oEvent = ev || event;
        alert(oEvent.clientX + ',' + oEvent.clientY);
    };
};

事件流

事件冒泡
<!DOCTYPE html>
<html onclick="alert('html');">
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        div {
            padding: 100px;
        }
    </style>
    <script type="text/javascript">
        window.onload = function() {
            document.onclick = function() {

            };
        };
    </script>
</head>
<body onclick="alert('body');">
    <div style="background: yellow;" onclick="alert(this.style.background);">
        <div style="background: green;" onclick="alert(this.style.background);">
            <div style="background: red;" onclick="alert(this.style.background);"></div>
        </div>
    </div>
</body>
</html>
在红色块中点击一下,依次弹出:red -> green -> yellow -> body -> html
事件冒泡顺序:red div -> green div -> yellow div -> body -> html -> document
冒泡,有时候有些用途,但大多数会带来一些麻烦
比如:
页面上一个小按钮,点击一下,下面的灰色临时div出来,点击网页其他部分,灰色临时div消失。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        div {
            width: 400px;
            height: 300px;
            background: #CCC;
            display: none;
        }
    </style>
    <script type="text/javascript">
        window.onload = function() {
            var oBtn = document.getElementById('btn1');
            var oDiv = document.getElementById('div1');
            oBtn.onclick = function() {
                oDiv.style.display = 'block';
                alert('按钮被点击');
            };
            document.onclick = function() {
                oDiv.style.display = 'none';
                alert('document被点击');
            };
        };
    </script>
</head>
<body>
    <input id="btn1" type="button" value="show" />
    <div id="div1"></div>
</body>
</html>
这样,你会发现,点击按钮,灰色临时div根本不会出来!
原因很简单,当你点击按钮的时候,那一瞬间,灰色临时div的确出现了,但冒泡了,事件不仅点到btn上,但也冒泡到document上了,所以也就是给document也传了一个事件,那么立刻就又display:none了。

取消冒泡

oEvent.cancelBubble = true;

鼠标事件

clientX , clientY
onmusemove

灰色小div跟着鼠标到处跑

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        div {
            width: 40px;
            height: 40px;
            background: #CCC;
            position: absolute;
        }
    </style>
    <script type="text/javascript">
    document.onmousemove = function(ev) {
        //灰色小div跟着鼠标到处跑
        var oEvent = ev || event;
        var oDiv = document.getElementById('div1');
        oDiv.style.left = oEvent.clientX + 'px';
        oDiv.style.top = oEvent.clientY + 'px';
    };
    </script>
</head>
<body>
    <div id="div1"></div>
</body>
</html>
其实,这个程序有很大的漏洞,那就是不理解clientX和clientY,如果body给个高度,比如2000px,那么,灰色小块就会和鼠标脱离。clientX是鼠标位置在可视区到左边的距离,如果网页很大,根本不止一屏幕,那么可视区只是整个网页的一部分,这时候,可视区如果不是网页的最顶端部分,而是网页卷去了一部分,也就是scrollTop>0了,“==oDiv.style.top = oEvent.clientY + ‘px’;==”这句话就出问题了,top值这时候大于clientY了。也即是说,clientX 和 clientY是根据可视区定位的,但是,div可是根据body定位的(left,top)。

法则:

但凡是用到clientX,clientY的时候,一定用到scrollLeft,scrollTop,不然几乎是一定会出问题的.
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        div {
            width: 40px;
            height: 40px;
            background: #CCC;
            position: absolute;
        }
    </style>
    <script type="text/javascript">
    document.onmousemove = function(ev) {
        var oEvent = ev || event;
        var oDiv = document.getElementById('div1');

        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

        oDiv.style.left = oEvent.clientX + 'px';
        oDiv.style.top = oEvent.clientY + 'px';
    };
    </script>
</head>
<body>
    <div id="div1"></div>
</body>
</html>

封装scrollTop和scrollLeft

因为经常用到,写起来麻烦,封装成库
function getPos(ev) {
    var st = document.documentElement.scrollTop || document.body.scrollTop;
    var sl = document.documentElement.scrollLeft || document.body.scrollLeft;
    return {x:ev.clientX+sl, y:ev.clientY+st};
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        div {
            width: 40px;
            height: 40px;
            background: #CCC;
            position: absolute;
        }
    </style>
    <script type="text/javascript">

        function getPos(ev) {
            var st = document.documentElement.scrollTop || document.body.scrollTop;
            var sl = document.documentElement.scrollLeft || document.body.scrollLeft;
            return {x:ev.clientX+sl, y:ev.clientY+st};
        }

        document.onmousemove = function(ev) {
            var oEvent = ev || event;
            var oDiv = document.getElementById('div1');
            var pos = getPos(oEvent);

            oDiv.style.left = pos.x + 'px';
            oDiv.style.top = pos.y + 'px';
        };
    </script>
</head>
<body style="height: 30000px">
    <div id="div1"></div>
</body>
</html>
下面的功能是很多个div,跟在鼠标后面一大串
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        div {
            width: 50px;
            height: 50px;
            background: red;
            position: absolute;
            left: 300px;
            top: 200px;
        }
        img {
            width: 100%;
            height: 100%;
        }
    </style>
    <script type="text/javascript">
        function getPos(ev) {
            var st = document.documentElement.scrollTop || document.body.scrollTop;
            var sl = document.documentElement.scrollLeft || document.body.scrollLeft;
            return {x:ev.clientX+sl, y:ev.clientY+st};
        }
        var k = 0;
        document.onmousemove = function(ev) {
            k++;
            var oEvent = ev || event;
            var pos = getPos(oEvent);
            var aDiv = document.getElementsByTagName('div');
            var len = aDiv.length;

            aDiv[0].style.left = pos.x + 'px';
            aDiv[0].style.top = pos.y + 'px';

            for (var i = len - 1; i > 0; i--) {
                aDiv[i].style.left = aDiv[i - 1].offsetLeft + 'px';
                aDiv[i].style.top = aDiv[i - 1].offsetTop + 'px';
            }
        };
    </script>
</head>
<body>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
    <div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>

</body>
</html>

键盘事件,keyCode

onkeydown
onkeyup
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>zns</title>
</head>
<body>
    <script type="text/javascript">
        document.onkeydown = function(ev) {
            var oEvent = ev || event;
            alert(oEvent.keyCode);
        };
    </script>
</body>
</html>
a:65  b:66 ......
要求:键盘控制div的移动
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>zns</title>
    <style type="text/css">
        #div1 {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
        }
    </style>
</head>
<body>
    <div id="div1"></div>
    <script type="text/javascript">
        var oDiv = document.getElementById('div1');
        document.onkeydown = function(ev) {
            var oEvent = ev || event;
            var code = oEvent.keyCode;
            switch(code) {
                case 37:
                    oDiv.style.left = oDiv.offsetLeft - 5 + 'px';
                    break;
                case 38:
                    oDiv.style.top = oDiv.offsetTop - 5 + 'px';
                    break;
                case 39:
                    oDiv.style.left = oDiv.offsetLeft + 5 + 'px';
                    break;
                case 40:
                    oDiv.style.top = oDiv.offsetTop + 5 + 'px';
                    break;                      
            }
        };
    </script>
</body>
</html>
上面代码,满足了左键右键移动div的要求,但是,基于系统本身的特点(原因:系统要区分用户是否连续输入,第一个到第二个之间有一个停顿时间。比如,当你长按a的时候,屏幕上先是出现一个a,顿一下然后才出现第二个第三个一串a,这是系统为了考虑行动缓慢的老人,故意延迟一下时间,因为老人按的比较慢,避免出现一串a)但也同时造成了我们的困扰,你按一下左键,也是顿一下,这是不行的,如何解决??解决方案:先开一个定时器,让div一直处于(往4个方向)准备移动的状态(初始4个方向的值都是false,div就保持在原地不动),当按下某个方向键,这个方向的值就改变为true,div就会开始往这个方向移动,松开方向键,这个方向的值就改变为false , div就停止这个方向移动了
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>zns</title>
    <style type="text/css">
        #div1 {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
        }
    </style>
</head>
<body>
    <div id="div1"></div>
    <script type="text/javascript">
        var oDiv = document.getElementById('div1');

        var key_left = false;
        var key_right = false;
        var key_bottom = false;
        var key_top = false;
        var timer = null;

        setInterval(function() {
            if(key_left) {
                oDiv.style.left = oDiv.offsetLeft - 5 + 'px';
            } else if(key_right) {
                oDiv.style.left = oDiv.offsetLeft + 5 + 'px';
            } else if(key_top) {
                oDiv.style.top = oDiv.offsetTop - 5 + 'px';
            } else if(key_bottom) {
                oDiv.style.top = oDiv.offsetTop + 5 + 'px';
            }
        }, 50);


        document.onkeydown = function(ev) {
            var oEvent = ev || event;
            var code = oEvent.keyCode;
            switch(code) {
                case 37:
                    key_left = true;
                    break;
                case 38:
                    key_top = true;
                    break;
                case 39:
                    key_right = true;
                    break;
                case 40:
                    key_bottom = true;
                    break;
            }
        };

        document.onkeyup = function(ev) {
            var oEvent = ev || event;
            var code = oEvent.keyCode;

            switch(code) {
                case 37:
                    key_left = false;
                    break;
                case 38:
                    key_top = false;
                    break;
                case 39:
                    key_right = false;
                    break;
                case 40:
                    key_bottom = false;
                    break;
            }
        };
    </script>
</body>
</html>

#### 需求:回车键按下,input框内的内容追加到textarea中

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>zns</title>
    <style type="text/css">
        #div1 {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
        }
    </style>
</head>
<body>
    <input id="txt1" type="text" /><br>
    <textarea id="txt2" rows="10" cols="40" style="margin-top: 10px;"></textarea>
    <script type="text/javascript">
        var oTxt1 = document.getElementById('txt1');
        var oTxt2 = document.getElementById('txt2');
        // oTxt1内写完时候,焦点在oTxt1内,这时候回车,keydown应该加在oTxt1上
        oTxt1.onkeydown = function(ev) {
            var oEvent = ev || event;
            if(oEvent.keyCode == 13) {
                oTxt2.value += oTxt1.value + '\n';
                oTxt1.value = '';
            }
        };

    </script>
</body>
</html>

需求:回车和Ctrol键同时按下才提交

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>zns</title>
    <style type="text/css">
        #div1 {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
        }
    </style>
</head>
<body>
    <input id="txt1" type="text" /><br>
    <textarea id="txt2" rows="10" cols="40" style="margin-top: 10px;"></textarea>
    <script type="text/javascript">
        var oTxt1 = document.getElementById('txt1');
        var oTxt2 = document.getElementById('txt2');
        // oTxt1内写完时候,焦点在oTxt1内,这时候回车,keydown应该加在oTxt1上
        oTxt1.onkeydown = function(ev) {
            var oEvent = ev || event;
            if(oEvent.keyCode == 13 && oEvent.ctrlKey) {
                oTxt2.value += oTxt1.value + '\n';
                oTxt1.value = '';
            }
        };

    </script>
</body>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值