第七课 js事件

event事件对象

1、什么是event事件对象?

用来获取事件的详细信息:鼠标位置、键盘按键

——例子:获取鼠标位置:clientX

(1)首先对于点击事件,如果我们想要在页面打开后,在页面的任何一个地方点击都会弹出来一个框,那我们应该怎么做呢?

<script type="text/javascript">
        document.onclick=function () {
            alert(event.clientX+","+event.clientY);    //在火狐下不弹出来,出现错误!
        }    
        </script>

其实上面的event就是一个事件对象,它里面包含了事件的各种信息;其中clientX就是其中一个;

在火狐下事件处理函数则需要添加参数;

<script type="text/javascript">
        document.onclick=function (ev) {
            alert(ev.clientX+","+ev.clientY);      //ev在IE下为undefined,但是在火狐下面则是一个鼠标事件对象;
        }    
        </script>

获取event对象(兼容性写法):

——var oEvent=ev||event;

或||

<script type="text/javascript">        
var a=12||'abc';      //12
        alert(a);    
        </script>

这样的话那我们上面的鼠标点击显示位置事件就可以用这种方式来简化代码了:

<script type="text/javascript">
        document.onclick=function (ev) {            
        var oEvent=ev||event;
                alert(oEvent.clientX+","+oEvent.clientY);
            }    
            </script>

事件流

(1)事件冒泡

取消冒泡:oEvent.cancelBubble=true

例子:仿select控件

DOM事件流

首先我们来看一下这个事件冒泡的问题:

<!DOCTYPE html>
<html onclick="alert('html');">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
</head>
<body onclick="alert('body');">
<div style="width:300px; height:300px; background:red;" onclick="alert(this.style.background);">
    <div style="width:200px; height:200px; background:green;" onclick="alert(this.style.background);">
        <div style="width:100px; height:100px; background:#CCC;" onclick="alert(this.style.background);">
        </div>
    </div>
</div>
</body>
</html>

这个事件冒泡的问题会在大部分的时候给我们带来很多问题,而不会有太大的用处,下面再来看一个例子(自定义的下拉列表);

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style type="text/css">
        #div1{width:100px;height:150px;background:#ccc;display:none;}
    </style>
    <title>Title</title>
    <script type="text/javascript">
        window.onload=function () {
            var oBtn=document.getElementById("btn1");
            var oDiv=document.getElementById("div1");
            oBtn.onclick=function () {
                oDiv.style.display="block";
            };
            document.onclick=function () {
                oDiv.style.display="none";
            };
        }
    </script>
</head>
<body>
<input id="btn1" type="button" value="显示">
<div id="div1"></div>
</body>
</html>

当我们用上面代码的时候点击按钮没有反应,这是为什么呢?我们现在来看一下再在上面加两个弹出框的代码:

<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("页面被点击了")
            };
        }    
        </script>

当使用上述代码的时候我们发现当点击按钮的时候,下面的div会出现,且页面先弹出框”按钮被点击了“,接着会再弹出“页面被点击了”;而当我们点击页面的时候只弹出“页面被点击了”,说到这里我们就看到了事件冒泡的问题了;那么我们来分析一下接下来怎么处理:

现在我们就要用到这个取消冒泡的属性了,即cancelBubble;

<script type="text/javascript">
        window.onload=function () {            
        var oBtn=document.getElementById("btn1");            
        var oDiv=document.getElementById("div1");

            oBtn.onclick=function (ev) {                
            var oEvent=ev||event;
                oDiv.style.display="block";                
                //alert("按钮被点击了")                
                oEvent.cancelBubble=true;
            };
            document.onclick=function () {
                oDiv.style.display="none";                
                //alert("页面被点击了")            };
        }    
        </script>

鼠标事件

1、鼠标位置

可视区位置:clientX、clientY(鼠标的坐标)

这里我们注意,现在我们只知道它是鼠标的坐标,但是我们不知道它是鼠标的什么坐标,现在我们来看一个实例:

——例子:跟随鼠标的Div

(1)onmousemove 事件会在鼠标指针移动时发生。

注释:每当用户把鼠标移动一个像素,就会发生一个 mousemove 事件。这会耗费系统资源去处理所有这些 mousemove 事件。因此请审慎地使用该事件.

<head>
    <style type="text/css">
        #div1 {width:100px; height:100px; background:red; position:absolute;}    
        </style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
    <script type="text/javascript">
    document.onmousemove=function (ev)
    {        
    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>

这里又出现了其他的问题,代码如下所示;

<!DOCTYPE html>
<html lang="en">
<head>
    <style type="text/css">
        #div1 {width:100px; height:100px; background:red; position:absolute;}
    </style>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <script type="text/javascript">
        document.onmousemove=function (ev)
        {
            var oEvent=ev||event;
            var oDiv=document.getElementById('div1');
            oDiv.style.left=oEvent.clientX+'px';
            oDiv.style.top=oEvent.clientY+'px';
        };
    </script>
</head><body style="height:2000px;">
<div id="div1"></div>
</body>
</html>

当我们给body加一个高度之后我们就会发现这个div跟鼠标脱离了,那这是为什么呢,接下来我们来看一下问题出现在哪里?
实际上这个clientX说的是可视区坐标,那什么是可视区呢?什么又是可视区坐标呢?

image.png

这里又出现了一个滚动距离(滚动条):scrollTop属性;

-消除滚动条的影响

-滚动条的意义——可视区与页面顶部的距离

  <style type="text/css">
    #div1 {width:100px; height:100px; background:red; position:absolute;}    
    </style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
    <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;
            var scrollLeft=document.documentElement.scrollLeft||document.body.scrollLeft;

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

注意:小小的经验:主要你用到了clientX,你就一定要加scrollLeft;只要用到了clientY,你就一定要加scrollTop。

键盘事件

onclick=onmousedown+onmouseup;(鼠标点击)

onpress=onkeydown+onkeyup;(键盘按下)

keyCode(键码)

<script>
        document.onkeydown=function (ev) {            
        var oEvent=ev||event;
            alert(oEvent.keyCode);
        };    
        </script>

获取用户按下键盘的哪个按键

——例子:键盘控制Div移动

<!DOCTYPE html>
<html lang="en">
<head>
    <style type="text/css">
        #div1 {width:100px; height:100px; background:red; position:absolute;}
    </style>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <script type="text/javascript">
        document.onkeydown=function (ev)
        {
            var oEvent=ev||event;
            var oDiv=document.getElementById('div1');
            //←        37            //右        39
            if(oEvent.keyCode==37)
            {
                oDiv.style.left=oDiv.offsetLeft-10+'px';
            }
            else if(oEvent.keyCode==39)
            {
                oDiv.style.left=oDiv.offsetLeft+10+'px';
            }
        };
    </script>
</head>
<body>
<div id="div1"></div>
</body>
</html>

其他属性

点击回车提交留言
ctrlKey、shiftKey、altKey

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <script>
        window.onload=function ()
        {
            var oBtn=document.getElementById('btn1');
            var oTxt1=document.getElementById('txt1');
            var oTxt2=document.getElementById('txt2');

            oBtn.onclick=function ()
            {
                oTxt1.value+=oTxt2.value+'\n';
                oTxt2.value='';
            };
            oTxt2.onkeydown=function (ev)
            {
                var oEvent=ev||event;
                if(oEvent.keyCode==13 && oEvent.ctrlKey)
                {
                    oTxt1.value+=oTxt2.value+'\n';
                    oTxt2.value='';
                }
            };
        };
    </script>
</head>
<body>
<textarea id="txt1" rows="10" cols="40"></textarea><br />
<input id="txt2" type="text" />
<input id="btn1" type="button" value="留言" />
</body>
</html>

默认行为

  1. 什么是事件的默认行为(默认事件)

(1)浏览器不需要我们去编写,浏览器自身就已经具备的功能;(点击右键弹出页面菜单)

(2)如何阻止默认行为

2. 上下文菜单:oncontextmenu(右键菜单)
   点击右键就会弹出a,且会出现右键菜单;

  <script type="text/javascript">
        document.oncontextmenu=function () {
            alert("a")
        };    
        </script>

事件处理函数中返回false,可以阻止默认行为。阻止右键菜单,点击无法弹出。

<script type="text/javascript">
        document.oncontextmenu=function () {            
        return false;
        };    
        </script>

再来看一下一个阻止表单提交的实例:

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
    <script type="text/javascript">
        window.onload=function ()
        {            
        var oForm=document.getElementById('form1');            
        oForm.onsubmit=function ()
            {
                return false;
            };
        };    
        </script>
</head>
<body>
    <form id="form1" action="http://www.baidu.com/">        
    <input type="submit" />
    </form>
</body>

无论怎么点击提交按钮都无法提交网址。这样就可以进行表单校验了。

文本框内禁止输入内容实例(阻止onkeydown)

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
    <script type="text/javascript">
    window.onload=function ()
    {        
    var oTxt=document.getElementById('txt1');        
    oTxt.onkeydown=function ()
        {
            return false;
        };
    };    
    </script>
</head>
<body>
    <input id="txt1" type="text" />
</body>

自定义右键菜单实例

<!DOCTYPE html>
<html lang="en">
<head>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        #ul1 {
            width: 100px;
            background: #CCC;
            border: 1px solid black;
            position: absolute;
            display: none;
            list-style: none
        }
    </style>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>无标题文档</title>
    <script type="text/javascript">
        document.oncontextmenu = function (ev) {
            var oEvent = ev || event;
            var oUl = document.getElementById('ul1');

            oUl.style.display = 'block';
            oUl.style.left = oEvent.clientX + 'px';
            oUl.style.top = oEvent.clientY + 'px';
            return false;            //让系统的右键菜单消失
        };
        document.onclick = function () {
            var oUl = document.getElementById('ul1');
            oUl.style.display = 'none';                          //点击页面就消失;
        };
    </script>
</head>
<body>
<ul id="ul1">
    <li>登陆</li>
    <li>回到首页</li>
    <li>注销</li>
    <li>加入VIP</li>
</ul>
</body>
</html>

只能输入数字的输入框实例:onkeydown、onkeyup
keyCode=8是退格键

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <script type="text/javascript">
        window.onload=function ()
        {
            var oTxt=document.getElementById('txt1');
            oTxt.onkeydown=function (ev)
            {

                var oEvent=ev||event;
                if(oEvent.keyCode!=8 && (oEvent.keyCode<48 || oEvent.keyCode>57))
                {
                    return false;
                }
            };
        };    
        </script>
</head>
<body>
<input id="txt1" type="text" />
</body>
</html>

事件绑定的另外一种方式

addEventListener

先来看一个片段:

html代码

<div id="box">追梦子</div>

用on的代码

 1 window.onload = function(){
 2     var box = document.getElementById("box");
 3     box.onclick = function(){
 4         console.log("我是box1");
 5     }
 6     box.onclick = function(){
 7         box.style.fontSize = "18px";
 8         console.log("我是box2");
 9     }
10 }
     运行结果:“我是box2”

第二个onclick把第一个onclick给覆盖了,虽然大部分情况我们用on就可以完成我们想要的结果,但是有时我们又需要执行多个相同的事件,很明显如果用on完成不了我们想要的,addEventListener可以多次绑定同一个事件并且不会覆盖上一个事件。

用addEventListener的代码

1 window.onload = function(){
2     var box = document.getElementById("box");
3     box.addEventListener("click",function(){
4         console.log("我是box1");
5     })
6     box.addEventListener("click",function(){
7         console.log("我是box2");
8     })
9 }
    运行结果:我是box1
         我是box2

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271