回调函数之事件

事件基础

常见的事件

mouseovermouseout
表示鼠标移入和移出,与mouseenter与mouseleave不同的是,后者没有冒泡。也就是在父元素上绑定了事件,子元素上不会有事件。
click
点击事件
dblclick
双击鼠标事件
blur与foucs
失去焦点与焦点事件。可以用在表单、链接和window上。
不要在用户填完一个表单失去焦点的时候验证表单。可以用change事件来代替它(当用户改变了表单的内容时验证)。但是最好的方法是用onsubmit。
change
用户在改变了表单域的值的时候触发。对于下拉选择框来说,当用户选择了任意一个选项就立即触发该事件。对于复选框和单选框来说,当用户选中或取消选中它的时候就触发该事件。对于文本输入框来说,当用户改变了它的内容的时候且失去焦点的时候就触发。
contextmenu
就是在页面上点击右键时触发,这个事件通常用在禁用上下文菜单来禁止查看源码。
load与unload
当页面完全加载后就会触发load事件
。用在window对象上,此外load事件还可以用在图片上,等到图片完全加载完之后就会触发load事件。
readystatchange
通常用在ajax上。
submit
通常用在用户提交表单的时候被触发。只有当按钮被激活的时候才会提交。
resize
用户在改变浏览器窗口的大小的时候触发。只对window对象可用。
scroll
用户在滚动某块内容的时候触发。不管用户是拖拉滚动条还是使用方向键还是鼠标滚轮。scroll事件对任何能够产生滚动条的元素可用。
textInput
当用户在可编辑区域输入字符的时候就会触发该事件。

事件处理器

一旦你决定用哪个事件,你需要告诉浏览器当事件发生时运行哪个函数。这就要注册事件处理程序。
当用element.onclick=m时,注意m函数没有括号。
也可以用匿名函数。
例如:

window.onload=init;
function init(){}

最常用的就是:

x.addEventListener('click',doThis,false)

移除的话就是:

x.removeEventListener('click',doThis,false)

removeEventListener和addEventListener接受相同的参数。缺点就是这种写法移除事件处理函数的时候必须提供函数的名字。而上面的写法就不必(btn.onclick=null)。这就意味着不能使用匿名函数。

var btn=document.getElementById('myBtn');
btn.addEventListener('click',function(){
    alert('this.id')
},false)
btn.removeEventListener('click',function(){
    alert(this.id)
},false)

虽然看似传入了相同的参数,但是,实际上第二个参数与前面的是完全不同的参数。

var btn=document.getElementById('myBtn');
var handler=function(){}
btn.addEventListener('click',handler,false);
btn.removeEventListener('click',handle,false)

这样就传入了相同的参数。通常用false而不用true。

事件流

假设你有一个<div>,它包含了一个<form>,里面又有一个表单。它们都有一个onclick事件。当点击表单的时候,<div><form>的事件处理程序会被触发么?。答案是肯定的,如果有一个事件发生,而有多个事件处理程序,它们都会被触发。但是哪个先触发,取决于是用了事件捕获还是事件冒泡。

事件冒泡和事件捕获

事件从它的目标事件(用户点击的事件)开始,触发目标的事件处理程序,然后沿着文档树逐级冒泡,直到document元素为止。对于每个遇到的HTML元素,它都会触发相关的事件处理程序。因此<div><form>的事件处理程序都会被触发。
而事件捕获刚刚相反,它会先触发文档的一级,沿着文档树向下游历,直到事件的目标为止。对于每个遇到的HTML元素,它都会触发相关的事件处理程序。
界面事件如submit和change事件没有冒泡。
在w3c模型中事件冒泡和事件捕获都会存在。当一个事件触发时,先被文档捕获,然后沿着文档向下游历,直到事件目标为止。这叫捕获阶段。到达目标阶段后冒泡就开始,事件沿着原路反方向游历,直到文档为止。每个事件处理程序都是针对其中一种过程设置的。true代表是捕获,false为冒泡。

事件对象

当事件发生的时候就会自动创建这个对象。而且它包含该事件的各种有用的信息,比如目标对象、事件类型、鼠标位置、用户按下的按键等。
event对象,可以用e来表示。当然也可以随意给它命名。
event对象的type属性包含着事件类型。
event对象的了stopPropagation()方法用于取消事件传播。
event对象的preventDefault属性取消事件的默认行为,只有cancelable属性设置为true的事件才能使用preventDefault来取消其默认行为。
target属性包含着目标对象。即事件究竟发生在哪个元素上,而不是绑定事件的元素。而this指的是绑定事件处理程序的元素。
鼠标的位置需要知道鼠标相对于document的位置。就是event的pageX和pageY属性或者clientX和clienY属性。
目标对象的eventPhase属性用于确定事件正位于事件流的哪个阶段。捕获阶段,eventPhase等于1,事件处理程序处于目标对象上,则等于2,如果是在冒泡阶段调用的事件处理程序,则等于3.

易错

function test(){
    this.style.backgroundColor='red'
}//错误。this总是指向方法被调用的那个对象,在这里函数test被window对象调用。所以this指向的是window.任何函数都可以看做是js的全局对象(window)的一个方法。而且this必须封闭在一个函数中才有用。
x.onclick=function(){
    test()
}//错误。当用户点击x时候,事件处理程序调用test()。此时该函数是通过全局对象来调用的所以this指向的是window。
x.addEventListener('click',function(){test()},false);//错误。原因同上。

何时使用this,何时使用target?

一般来说,当注册同样的事件处理程序到许多元素上或者想要直接调用该事件处理程序的时候this是有用的。
当你依赖于事件冒泡使得事件沿文档树由下向上传播的时候,target是有用的。

实例

当点击的时候出现''clicked',当移入的时候背景颜色变为红色。当移出的时候背景颜色为默认值。

var btn=document.getElementById('myBtn')
var handler=function(event){
    switch(event.type){
        case 'click':
        alert('Clicked');
        break;
        case 'mouseover':
        event.target.style.background='red';
        break;
        case 'mouseout':
        event.target.style.background='';
        break;
    }
}
btn.onclick=handler;
btn.onmouseover=handler;
btn.onmouseout=handler;

事件委托

指定一个事件处理程序就可以管理某一类型的所有事件。事件委托用到了事件冒泡。例如,我们可以为整个页面指定一个onclick事件,而不必为每个元素设置单击事件。
也可以为document对象添加一个特定的事件。有如下优点:

  • document可以很快就会访问。只要可单击的元素呈现在页面上,就可以立即具备适当的功能。
  • 在页面上设置事件处理程序的时间减少。
  • 整个页面所占的内存减少。

移除事件处理程序应用

有这样一个需求当点击按钮的时候按钮消失变成一条网络消息。但是如果事件绑定在按钮上,当按钮消失的时候还绑定着事件处理程序呢。所以可以设置btn.onclick来移除事件处理程序。当然还有一种方法就是利用事件委托,把事件绑定在更高层次的元素上。

应用

1.当点击按钮开头添加时在<li>这里是</li>元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在最后一个 li 元素后添加用户输入的非空字符串.
当点击每一个元素li时控制台展示该元素的文本内容。

<ul class="ct">
    <li>这里是</li>
    <li>饥人谷</li>
    <li>任务班</li>
</ul>
<input class="ipt-add-content" placeholder="添加内容"/>
<button id="btn-add-start">开头添加</button>
<button id="btn-add-end">结尾添加</button>
<script>
var btn1=document.querySelector('#btn-add-start')
        var btn2=document.querySelector('#btn-add-end')
        var ct=document.querySelector('.ct')
        var ipt=document.querySelector('.ipt-add-content')
        btn1.addEventListener('click',function(){
            var Li=document.createElement('li')
            if(ipt.value){
            Li.innerText=ipt.value
            ct.insertBefore(Li,ct.firstChild)
          }
        })
        btn2.addEventListener('click',function(){
            var Li=document.createElement('li')
            if(ipt.value){
            Li.innerText=ipt.value
            ct.appendChild(Li)
           }
        })
        ct.addEventListener('click',function(e){
            console.log(e.target.innerText)
        })
</script>
  1. 补全代码,要求:当鼠标放置在li元素上,会在img-preview里展示当前li元素的data-img对应的图片。
<ul class="ct">
    <li data-img="1.png">鼠标放置查看图片1</li>
    <li data-img="2.png">鼠标放置查看图片2</li>
    <li data-img="3.png">鼠标放置查看图片3</li>
</ul>
<div class="img-preview"></div>
<script>
    var ct=document.querySelector('.ct')
    var img=document.querySelector('.img-preview')
    ct.addEventListener('mouseover',function(e){
        var imagelink=e.target.getAttribute('data-img');
        var image=document.createElement('img');
        image.setAttribute('src','imagelink');
        img.appendChild(image);
    });
</script>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,473评论 1 11
  • (续jQuery基础(1)) 第5章 DOM节点的复制与替换 (1)DOM拷贝clone() 克隆节点是DOM的常...
    凛0_0阅读 1,316评论 0 8
  • 事件流 JavaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互...
    DHFE阅读 822评论 0 3
  • 看了两遍温暖的遇见你,好喜欢女主啊,长得好漂亮,我好喜欢,积极,乐观,能干,爱笑,笑的好好看!好有感染力!她穿的好...
    阮雅阅读 246评论 0 0
  • 感恩种子智慧,感恩小宝的到来让我的平静许多,感恩上天保佑小宝,感恩上天的安排,感恩世界万物生长,感恩父母支持与包容...
    26a658189666阅读 102评论 0 0