JS基础-事件

事件

用户的行为:onclick、ondblclick、onfocus、onblur、window.onload
是用户跟页面的交互,当用户跟页面进行一些“交流”的时候,页面通过js就会触发一些事件,比如鼠标点击的时候就会触发onclick事件,给这个事件绑定一个函数,那么这个时候函数就会被调用,代码就会被执行。

事件类型:

鼠标事件:click,dbclick,mousedown,mouseup,mouseover,
    mouseout,mouseenter(鼠标穿过元素)、mouseleave(鼠标离开元素)、
    mousemove、scroll(适用于所有可以滚动的元素和window对象)、mousewheel
    鼠标滚轮、contextmenu  鼠标右键(上下文菜单:在不同环境下右键菜单不一样)

    其中
    mouseover:鼠标在元素身上移动穿过子元素的时候会被反复触发
    mouseenter:只是在进入元素的时候触发

键盘事件:keydown,keyup,keypress
事件举例:
<div id="box">box</div>
        <script>
            var box = document.getElementById("box");
            //绑定事件
            box.onclick = function(){
                alert("click");
            }
            
            function foo(){
                alert("foo");
            }
            
            box.onmouseover = foo;
            
        </script>

表单事件:对表单元素操作之后会触发的事件

  单选框、多选框、下拉菜单 状态改变的时候会触发  onchange 事件。
  表单提交的时候会触发 onsubmit   触发在<form>元素身上。
表单事件举例:
<form id="form">
            <input type="text" id="num">
            <select id="sel">
                <option>成都</option>
                <option>北京</option>
                <option>上海</option>
            </select>
            <input type="checkbox" id="check">
            
            <button type="button">按钮</button>
            <input type="submit" value="提交" id="btn">
        </form>
        <script>
            var input = document.getElementById("num");
            input.onfocus = function(){
                console.log("获得焦点");
            
            }
            input.onblur = function(){
                console.log("失去焦点");
                //console.log(input.value);
                var value = this.value;
                //是否大于6位
                if(value.length > 6){
                    console.log("满足要求");
                    
                }else{
                    console.log("请输入大于6位");
                }
            }
            
            var sel = document.getElementById("sel");
            //重新选择的时候,触发onchange事件
            sel.onchange = function(){
                console.log(this.value);
            }
            
            var check = document.getElementById("check");
            check.onchange = function(){
                console.log(this.checked); //是否选中的状态(true\false)
            }
            
            var form = document.getElementById('form');
            console.log(btn);
            form.onsubmit = function(e){
                //表单提交事件
                console.log("提交");
                e.preventDefault();
                return false;
            }
        </script>

this关键字:事件函数里面的this指的是事件触发对象。
事件的原理和hover类似。可以做到:hover做不到的事,:hover只能操作当前的元素,但是事件绑定之后可以选择任何元素。

事件触发三要素:通过谁触发? 通过什么触发?触发后要做什么?
事件的写法:

w3c标准:事件写在行内,但是因为结构和行为要分离,所以我们一般情况下用JavaScript的方法来绑定事件,只有再极少数情况下,才将事件写在行内,事件的绑定方法:

浏览器中的节点(对象).on+事件句柄 = function( ){
要干什么?(放在浏览器中,不执行,当事件发生的时候再执行。)
}

oDiv.onclick=function(){     

 alert(1)

}
事件总结:事件是给浏览器定义一个预处理函数,当事件触发的时候,执行函数,这就是事件。
事件对象兼容写法: e=e || window.event;


鼠标事件.png

案例:一串div跟着鼠标移动

<style>
            div{height: 20px;width: 20px;background: red;position: absolute;}
        </style>
    </head>
    <body>
        <script>
            var aDiv = [];
            var cache = document.createDocumentFragment();
            for(var i = 1; i <= 20; i++){
                var div = document.createElement("div");
                div.innerHTML = i;
                aDiv.push(div);
                //document.body.appendChild(div);
                cache.appendChild(div);
            }
            document.body.appendChild(cache);
            
            //document绑定mousemove事件
            document.onmousemove = function(e){
                e = e || event;
                var mouseX = e.clientX,
                    mouseY = e.clientY;
                
                /* aDiv[0].style.left = mouseX + "px";
                aDiv[0].style.top = mouseY + "px"; */
                
                //从后往前,一次进一步
                for(var i = aDiv.length-1; i > 0; i--){
                    aDiv[i].style.left = aDiv[i-1].style.left;
                    aDiv[i].style.top = aDiv[i-1].style.top;
                }
                //第0个赋值未当前鼠标坐标
                aDiv[0].style.left = mouseX + "px";
                aDiv[0].style.top = mouseY + "px";
                
            }
        </script>
    </body>

键盘事件:keydown、keyup、keypress

document.onkeydown = function(e){
    console.log(e.keyCode)   
}

键盘上每一个键都有一个唯一的编码,用来识别当前用户正在操作的是键盘上哪一个键.

有兼容问题 兼容写法:e.keyCode || e.which

特殊键码:是否按下alt ctrl 和 shift
e.altKey
e.ctrlKey
e.shiftKey
返回值是布尔值;
可以用来判断组合键

if(e.keyCode==13&&e.altKey){
     alert('同时按下了enter和alt');
}

默认行为(浏览器)

有一些html元素默认的行为,比如说a标签,点击后有跳转动作;form表单中的submit类型的input有一个默认提交跳转事件;reset类型的input有重置表单行为。
但是,有些时候我们是不需要默认事件的,所以就需要阻止默认事件.

方法1.return false;

方法2.
if(e.preventDefault) {
      e.preventDefault();
      }
else {
    window.event.returnValue = false;    
    //return false;
}

一个完整事件包含 捕获阶段 ---> 目标阶段 --->冒泡阶段
子元素的事件被触发时,父级也会被触发(冒泡)

<body>
        <div id="yeye">
            <div id="baba">
                <div id="erzi"></div>
            </div>
        </div>
        <script>
            yeye.onclick = function(){
                console.log("yeye");
            }
            baba.onclick = function(e){
                console.log("baba");
                //阻止冒泡
                e.stopPropagation();
                e.cancelBubble=true;//兼容IE
            }
            erzi.onclick = function(){
                console.log("erzi");
            }
        </script>
    </body>

冒泡是可以阻止的

 e.stopPropagation( );
 e.cancelBubble=true;//兼容IE
事件监听

DOM2级事件处理是所有DOM节点中的方法,可以重复绑定,但是浏览器兼容存在问题;

 //DOM2级
if(window.attachEvent){
    oDiv.attachEvent("onclick", function(){ ... });  // IE只有冒泡阶段,所以没有第三个参数,而且需要加on;
}else{
    oDiv.addEventListener( "click", function(){ ... },false);  // false指冒泡阶段
}
/* 监听事件
     * @param obj DOMObj 监听事件的对象
     * @param type string 事件句柄
     * @param fn   function 事件处理函数 
     * @param [isCapture] boolean false代表冒泡,true代表捕获 默认值是false
     */
    on : function(obj, type, fn, isCapture){
        if(isCapture === undefined) isCapture = false;
        if(obj.attachEvent){
            //IE只能再冒泡阶段处理事件
            obj.attachEvent("on"+type, fn);
        }else{
            obj.addEventListener(type, fn, isCapture);
        }
    },
<body>
        <div id="yeye">
            <div id="baba">
                <div id="erzi"></div>
            </div>
        </div>
        <script>
            //绑定只能绑一个,后面覆盖前面
            /* yeye.onclick = function(){
                console.log("yeye");
            }
            yeye.onclick = function(){
                console.log("yeye2222");
            } */

            //监听事件,可以同时监听多个
            //第三个参数传false代表不捕获(再冒泡阶段处理事件)
            //第三个参数传true代表捕获(再冒捕获段处理事件)
//          yeye.addEventListener("click", function(){
//              console.log("yeye");
//          },true);
//          
//          yeye.addEventListener("click", function(){
//              console.log("yeye222");
//          },true);
//          
//          baba.addEventListener("click", function(){
//              console.log("baba");
//          },true);
//          
//          erzi.addEventListener("click", function(){
//              console.log("erzi");
//          },true);

            tools.on(yeye, "click", function(){
                console.log("yeye");
            })
        </script>
    </body>

移除事件监听,第二个参数为必须,移除的事件处理函数

oDiv.removeEventListener( "click",fn)

oDiv.detachEvent("onclick",fn)
事件委托(事件代理)委派

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以处理某一类型的所有事件

使用场景主要用于事件源不确定的情况,可以把事件委托给父级
判断事件源:
e.target || e.srcElement

<body>
        <ul>
            <li>item1</li>
            <li>item2</li>
            <li>item3</li>
            <li>item4</li>
        </ul>
        <button>按钮</button>
        <script>
            var ul = document.querySelector("ul");
            /* var aLi = document.querySelectorAll("li");
            aLi = Array.from(aLi);
            console.log(aLi);
            aLi.forEach(function(li, index){
                li.onclick = function(){
                    console.log(this.innerHTML);
                }
            }) */
            
            //事件委托
            ul.onclick = function(e){
                e = e || event;
                //获取事件源
                var target = e.srcElement || e.target;
                if(target.nodeName === "LI")
                    console.log(target.innerHTML);
                
                //this
            }
            
            document.querySelector("button").onclick = function(){
                var li = document.createElement("li");
                li.innerHTML = "wgrf";
                ul.appendChild(li);
            }
            
        </script>
    </body>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335