JavaScript笔记(事件属性)

1 JavaScript DOM事件

DOM事件模型是什么:指的是冒泡和捕获
DOM事件流是什么:捕获阶段 -> 目标阶段 -> 冒泡阶段

1.1 事件流

参考文章:《js之事件冒泡和事件捕获详细介绍》

事件流分为两种:事件冒泡事件捕获

事件冒泡:事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的那个节点(文档),如:
这里写图片描述

事件捕获最不具体的节点应该更早接收到事件,而最具体的节点最后接收到事件,如:
这里写图片描述

二者综合起来就是DOM事件事件流了:
这里写图片描述

1.2 事件属性的绑定

1.2.1 HTML事件处理程序

HTML事件处理程序是指直接在HTML元素标签中添加如onclick = funcA()属性,这样的缺点是:HTML和JS代码紧密的耦合在一起

1.2.2 DOM 0级事件处理程序

形如element.onclick = function(){};删除事件属性element.onclick = null。优点:简单,跨浏览器

1.2.3 DOM 2级事件处理程序

DOM2级事件定义了两个方法:用于处理指定删除事件处理程序的操作,分别是addEventListener()removeEventListener(),与DOM 0级不同的是DOM 1级重复定义的事件,不会被新的事件替换掉,而是按先后顺序执行。

addEventListener()removeEventListener()都接受三个参数,分别是:事件名(如click),事件函数以及布尔值(数值为true时,表示在捕获阶段调用;数值为false时,表示在冒泡阶段调用)如:

<input type="button" value="按钮" id="btn3">
<script>
var btn3 = document.getElementById('btn3');
btn3.addEventListener('click',showMessage,false);
btn3.addEventListener('click',function(){
    alert(this.value);
},false)
btn3.removeEventListener('click',showMessage,false)
</script>

IE9前的版本并不支持addEventListener()removeEventListener(),它们使用attachEvent()detachEvent()attachEvent()detachEvent()接收两个参数,分别是事件名事件函数

为此,可以编写一个小组件处理兼容问题:

var eventUtil = {
    addHanler:function(element,type,handler){
        if (element.addEventListener) {
            element.addEventListener(type,handler,false);
        } else if (element.attachEvent){
            element.attachEvent(type,handler);
        } else {
            //使用DOM 0级事件处理程序
            element['on' + type] = handler;
        }
    }
     removeHandler:function(element,type,handler){
         if (element.removeEventListener){
             element.removeEventListener(type,handler,false);
         } else if (element.detachEvent) {
             element.detachEvent(type,hanlder);
         } else {
             element['on' + type] = handler
         }
     }
}

//跨浏览器添加事件处理程序;
eventUtil.addHandler(btn3,'click',showMessage);

1.3 事件对象

在触发DOM上的事件时都会产生一个对象event,该对象有以下属性及方法:

  • type :获取事件类型
  • target:获取事件目标
  • event.currentTarget:返回绑定事件的元素
  • stopPropagation():停止事件冒泡
  • preventDefault(): 阻止事件的默认行为

IE有另一个事件对象window.event,该对象有以下属性及方法:

  • type:获取事件类型
  • srcElement:获取事件目标
  • cancleBubble():停止事件冒泡
  • returnValue = false: 阻止事件的默认行为

为此,可以编写一个小组件处理兼容问题:

function showMes(event){
  //非IE用event,IE8以下用window.event;
  event = event || window.event;  
  //事件目标兼容;
  var ele = event.target || event.srcElement;
  //兼容阻止事件冒泡;
  if(event.stopPropagation){
    event.stopPropagation();
  }else{
    event.cancleBubble();
  };
  //兼容取消事件默认行为;
  if(event.preventDefault){
    event.preventDefault();
  }else{
    event.returnValue = false;
  }
}

由于不同的浏览器绑定事件的代码都不太一样,所以用jQuery来写代码,就屏蔽了不同浏览器的差异,我们总是编写相同的代码。

2 jQuery 对象事件

2.1 绑定事件

2.1.1 on()方法

与原装的JavaScript直接使用事件属性绑定函数不同,jQuery对象使用的是on方法,on方法用来绑定一个事件,我们需要传入事件名称和对应的处理函数,如:

$a.on("click",function(){
    alert("Hello");
});

还有一种更为简便的方法:

$a.click(function(){
    alert("Hello");
});

2.1.2 one()方法

使用one()方法绑定的事件函数都只能运行一次

$a.one("click",function(){
    alert("Hello");
});

event.preventDefault()方法阻止元素发生默认的行为(常用于点击提交按钮时阻止对表单的提交),值得注意的是使用这个方法,请记得在定义事件函数的时候添加event参数(jQuery方法)

2.1.3 toggle()方法

$("#abc").toggle(fn1,fn2,fn3,fn4...)

toggle()方法用于模拟鼠标连续单击事件,当第一次点击时执行函数fn1,第二次执行函数fn2,第三次fn3,等等一次触发,直到最后循环。

2.2 比较常用的事件属性

2.2.1 鼠标事件

  • blur:失焦
  • focus:聚焦
  • click::鼠标单击时触发;
  • dblclick:鼠标双击时触发;
  • mouseover:鼠标进入匹配元素时触发,而且如果进入匹配元素的子元素,也会触发
  • mouseout:鼠标离开匹配元素时触发,而且如果离开匹配元素的子元素,也会触发
  • mouseenter:鼠标进入匹配元素时触发,如果进入匹配元素的子元素,不会触发
  • mouseleave:鼠标离开匹配元素时触发,如果离开匹配元素的子元素,不会触发
  • hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave

2.2.2 其它事件

  • change:当<input><select><textarea>的内容改变时触发;
  • submit:当<form>提交时触发;
  • ready:当页面被载入并且DOM树完成初始化后触发,相当于window.onload(),区别在于window.onload()会把所有的文档资源都下载好才执行,而ready只需准备好DOM文档就可以了

其中要说明的是ready仅仅作用于document对象,即要作用于$(document)ready事件除了上述那样的绑定方法外,还可以简化成这样绑定:

$(function () {
    // init...
});

重复的绑定ready事件,他们不会失效而是会依次进行,普通事件也一样

2.3 取消事件绑定

一个已被绑定的事件可以解除绑定,通过off('click', function)实现,要注意的是这方法并不能解除匿名函数,也就是说要建立取消事件绑定的jQuery对象其相应的事件函数一定要命名,当然为了实现移除效果,也可以使用off('click')一次性移除已绑定的click事件的所有处理函数。

function hello() {
    alert('hello!');
}

a.click(hello); // 绑定事件

// 10秒钟后解除绑定:
setTimeout(function () {
    a.off('click', hello);
}, 10000);

/* 或者这样 */
setTimeout(function () {
    a.off('click');
}, 10000);

如果直接调用a.off()的形式,即其所有的事件函数都会被删除

2.4 事件触发条件

一个需要注意的问题是,事件的触发总是由用户操作引发的。但如change事件,其实是可以使用代码直接触发的,这样一来可以少写点代码,如:

var input = $('#test-input');
input.change(function () {
    console.log('changed...');
});

input.change();//直接调用

2.5 triggerHanlder()

使用以上形式激活事件是会同时激活浏览器的默认操作的,如focus事件,触发事件函数的同时,也会是元素本身得到焦点
如果只想触发事件,而不想执行默认浏览器默认操作,就可以使用trigglerHanlder()方法:

$("input").triggleHandler("focus");

2.6 题目加深印象

<!DOCTYPE html>
<html>
<head>
    <title>test</title>
    <script type="text/javascript" src="jquery-3.2.1.js"></script>
    <script type="text/javascript">
        $(function(){
            var $allinput = $("input[name=lang]");
            var $selectall = $("label.selectAll input");
            var $selectalltxt = $("span.selectAll");
            var $deselectalltxt = $("span.deselectAll");
            var $a = $("a.invertSelect");
            $allinput.prop("checked",false);
            $deselectalltxt.hide();
            function tof () {
                for (var i=0;i<5;i++) {
                    if ($allinput[i].checked) {
                    } else {
                        return false;
                    } 
                }
                return true;
            }
            $selectall.click(function() {
                if (!tof()) {
                    $allinput.prop("checked",true);
                    $selectalltxt.hide();
                    $deselectalltxt.show();
                    $selectall.prop("checked",true);
                }else {
                    $allinput.prop("checked",false);
                    $deselectalltxt.hide();
                    $selectalltxt.show();
                    $selectall.prop("checked",false);
                }
                })
            /* change不是click */
            $allinput.change(function(){
                if (tof()) {
                    $deselectalltxt.show();
                    $selectalltxt.hide();
                    $selectall.prop("checked",true);
                }
                else {
                    $deselectalltxt.hide();
                    $selectalltxt.show();
                    $selectall.prop("checked",false);
                }
            })
            $a.click(function(){
                for (var j=0;j<5;j++) {
                    if ($allinput[j].checked) {
                        $allinput[j].checked=false;
                    } else {
                        $allinput[j].checked=true;
                    }
                }
                $allinput.change();//调用时间函数,注意如果上面写click时间,就无法调用了调用
            })
        })
    </script>
</head>
<body>
    <div id="test-div">
        <form id="test-form" action="test">
            <legend>请选择想要学习的编程语言:</legend>
            <fieldset>
                <p><label class="selectAll"><input type="checkbox"><span class="selectAll">全选</span><span class="deselectAll">全不选</span></label> <a href="#0" class="invertSelect">反选</a></p>
                <p><label><input type="checkbox" name="lang" value="javascript"> JavaScript</label></p>
                <p><label><input type="checkbox" name="lang" value="python"> Python</label></p>
                <p><label><input type="checkbox" name="lang" value="ruby"> Ruby</label></p>
                <p><label><input type="checkbox" name="lang" value="haskell"> Haskell</label></p>
                <p><label><input type="checkbox" name="lang" value="scheme"> Scheme</label></p>
                <p><button type="submit">Submit</button></p>
            </fieldset>
        </form>
    </div>
</body>
</html>

这里还有一个简化版

<!-- 布尔值的赋值很奇妙的,理解原由会让事情方便简洁许多 -->
<script type="text/javascript">
        $(function(){
            var $allinput = $("input[name=lang]");
            var $selectall = $("label.selectAll input");
            var $selectalltxt = $("span.selectAll");
            var $deselectalltxt = $("span.deselectAll");
            var $a = $("a.invertSelect");
            $allinput.prop("checked",false);
            $deselectalltxt.hide();

            /* 绑定单个选项的改变事件 */
            $allinput.change(function(){
                var $judge = ($("input[name=lang]:checked").length==5);
                $selectall.prop("checked",$judge);
                if ($judge) {
                    $selectalltxt.hide();
                    $deselectalltxt.show();
                } else {
                    $selectalltxt.show();
                    $deselectalltxt.hide();
                }
            })

            /* 全选事件 */
            $selectall.click(function () {
                let isAllSelected = $selectall.is(':checked');//使用全选选项的勾选与否判断是否全选
                $allinput.prop('checked', isAllSelected);
                // 手动调用
                $allinput.change();
            })

            /* 反选事件 */
            $a.click(function(){
                $allinput.map(function(){
                    var mid = this.checked;//对应的this指向dom对象,保存原始的选项
                    this.checked=!mid;//改变布尔值
                })
                $allinput.change();
            })
        })
    </script>

转载于:https://www.cnblogs.com/AB786883603/p/8325403.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值