JavaScript知识点总结

事件

事件是由三部分组成:事件源、事件类型、事件处理程序,我们也称之为事件三要素。
1、事件源:事件被触发的对象,是指在哪个元素引发的事件。

<button id ="btn">程序猿</button>
var btn = document.getElementById('btn');

2、事件类型:如何触发、什么事件,比如鼠标点击(onclick)还是鼠标经过,还是键盘按下?

btn.onclick = function() {
    alert('写代码');
}

3、事件处理程序(事件驱动程序):通过一个函数赋值的方式完成,即执行的结果。

<button id ="btn">程序猿</button>
var btn = document.getElementById('btn');
btn.onclick = function() {
    alert('写代码');
}
一、事件冒泡:

事件的冒泡(Bubble):所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发(即开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点),在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡: event.cancelBubble=true.
事件源 =>根节点(由内到外)进行事件传播,事件冒泡本身的特性,会带来的坏处,也会带来的好处,需要我们灵活掌握。

<head>
    <title>事件冒泡</title>
    <style>
        #box1 {
            width: 200px;
            height: 200px;
            background: pink;
        }
        #box2 {
            width: 100px;
            height: 100px;
            background: blue;
        }
        #div1 {
            width: 200px;
            height: 200px;
            background: red;
        }
        #div2 {
            width: 100px;
            height: 100px;
            background: green;
        }
    </style>
</head>
<body>
    <div id="box1">
        我是父盒子
        <div id="box2">
            我是子盒子
        </div>
    </div>
    <br>
    <br>
    <div id="div1">
        我是父盒子
        <div id="div2">
            我是子盒子
        </div>
    </div>
    <br>
    <br>
    <a href="https://www.runoob.com/js/js-htmldom-eventlistener.html" id="a">菜鸟教程</a>
    <script>
        // 案例演示1:创建两个div,叠放在一起,分别绑定单击事件,点击最里边的div,会触发两个div的单击事件
        var box1 = document.getElementById("box1");
        var box2 = document.getElementById("box2");

        box1.onclick = function() {
            console.log("box1 的单击事件触发了!");
        };
        box2.onclick = function() {
            console.log("box2 的单击事件触发了!");
        };

        // 案例演示2:创建两个div,叠放在一起,分别绑定单击事件,点击最里边的div,不会触发两个div的单击事件,只会触发自己的单击事件,这时候我们可以取消事件冒泡
        var div1 = document.getElementById("div1");
        var div2 = document.getElementById("div2");
        div1.onclick = function() {
            console.log("div1 的单击事件触发了!");
            stopBubble();
        };
        div2.onclick = function() {
            console.log("div2 的单击事件出发了!");
            stopBubble();
        };
        function stopBubble(event) {
            if (event && evemt.stopPropagation) {
                event.stopPropagation();
            } else {
                window.event.cancelBubble = true;
            }
        }

        // 案例演示3:当点击a标签的时候,阻止a标签的默认跳转事件,采用事件阻止
        var a = document.getElementById("a");
        a.onclick = function() {
            stopDefault();
        };
        function stopDefault(event) {
            if (event && event.preventDefault) {
                event.preventDefault();
            } else {
                window.event.returnValue = false;
            }
            return false;
        }
    </script>
</body>

阻止事件冒泡的两种方法:

if(e && e.stopPropagation){
//标准写法:利用事件对象里面的 stopPropagation()方法
 e.stopPropagation();
}else{
//非标准写法:IE 6-8 利用事件对象 cancelBubble 属性
 window.event.cancelBubble = true;
}

点击子盒子,父盒子也执行点击事件;点击父盒子,子盒子不执行点击事件

二、事件绑定:

我们以前绑定事件代码只能一个事件绑定一个函数,那我们要是想一个事件对应多个函数,并且不存在兼容性的问题该如何解决呢?

//方式一:在DOM元素中直接绑定。but在DOM结构如果绑定两个 "onclick" 事件,只会执行第一个。
    <div id="btn" onclick="clickone()" onclick="clicktwo()"></div> 
    <script>
        function clickone(){ alert("hello"); } //执行这个
        function clicktwo(){ alert("world!"); }
    </script>
    
//方式二:在Javascript代码中绑定。这种绑定方式只能给一个事件绑定一个处理函数,在脚本通过匿名函数的方式绑定的只会执行最后一个事件。
    <div id="btn"></div>
    <script>
        document.getElementById("btn").onclick = function(){ alert("hello"); }
        document.getElementById("btn").onclick = function(){ alert("world"); } //执行这个
    </script>
    
//方式三:绑定事件监听函数。可以绑定多次同一个事件,且都会执行。
        <div id="btn"></div>
    <script>
        document.getElementById("btn").addeventlistener("click",clickone,false);
        function clickone(){ alert("hello"); } //先执行
        document.getElementById("btn").addeventlistener("click",clicktwo,false);
        function clicktwo(){ alert("world"); } //后执行
    </script>

解决事件绑定兼容问题:

/*为元素绑定事件兼容性代码*/
function addEventListener(element, type, fn) {
	if(element.addEventListener) {
		element.addEventListener(type, fn, false);
	} else if(element.attachEvent) {
		element.attachEvent("on" + type, fn);
	} else {
		element["on" + type] = fn;
	}
}

/*为元素解绑事件兼容性代码*/
function removeEventListener(element, type, fnName) {
	if(element.removeEventListener) {
		element.removeEventListener(type, fnName, false);
	} else if(element.detachEvent) {
		element.detachEvent("on" + type, fnName);
	} else {
		element["on" + type] = null;
	}
}
三、事件委派:

事件委派,就拿我之前看过的一个例子来说,同公司的小明,小红,小蓝三个人预计在下周一有快递要签收,但是呢三个人都等在公司楼下签收快递不太好,于是就委托公司前台小美代为签收一下。
这个例子中,三人共同事件统一绑定给同一人前台小美,这样当三人快递到达时触发了取快递的事件,事件会一直冒泡传递,召唤前台小美代签快递。

<head>
    <title>67.事件委派</title>
</head>
<body>
    <ul id="ul">
        <li><a href="#" class="link">小明快递</a></li>
        <li><a href="#" class="link">小红快递</a></li>
        <li><a href="#" class="link">小蓝快递</a></li>
    </ul>

    <script>
        // 案例演示:为ul列表中的所有a标签都绑定单击事件
        var ul = document.getElementById("ul");
        ul.onclick = function(event) {
            event = event || window.event;
            if (event.target.className == "link") {
                console.log("快递到了,召唤小美!");
            }
        };
    </script>
</body>

在这里插入图片描述

四、事件传播:

事件的传播:关于事件的传播网景公司和微软公司有不同的理解。
— 微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。
— 网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后在向内传播给后代元素。
— W3C综合了两个公司的方案,将事件传播分成了三个阶段:

  • 捕获阶段:在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件。
  • 目标阶段:事件捕获到目标元素,捕获结束开始在目标元素上触发事件。
  • 冒泡阶段:事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件。
    在这里插入图片描述

注意:如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true,一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false,并且注意,IE8及以下的浏览器中没有捕获阶段,我们可以使用event.stopPropagation();取消事件传播。

五、事件捕获:

网景提出了另一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件捕获的事件流是从最外层开始发生,直到被触发的具体元素。当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点=>事件源(由外到内)进行事件传播。

代码如下:

<head>
    <title>事件捕获</title>
    <style>
        .red{
            width: 300px;
            height: 300px;
            background-color: red;
        }
        .yellow{
            width: 200px;
            height: 200px;
            margin-left: 300px;
            background-color: yellow;
        }
        .green{
            width: 100px;
            height: 100px;
            margin-left: 200px;
            background-color: green;
        }
    </style>
</head>
<body>
    <div class="red">
        <div class="yellow">
            <div class="green"></div>
        </div>
    </div>

    <script>
        var red = document.getElementsByClassName('red')[0],
            yellow = document.getElementsByClassName('yellow')[0],
            green = document.getElementsByClassName('green')[0];

        red.addEventListener('click',function(){
            console.log('red')
        },true)
        yellow.addEventListener('click',function(){
            console.log('yellow')
        },true)
        green.addEventListener('click',function(){
            console.log('green')
        },true)
    </script>
</body>
</html>

上述代码中,如果在事件捕获的情况下,触发green的click事件的顺序应该是:document->html->body->red->yellow->green

this指向

  • 以函数形式调用时,this永远都是window
  • 以方法的形式调用时,this是调用方法的对象
  • 以构造函数的形式调用时,this是新创建的那个对象
  • 使用call和apply调用时,this是传入的那个指定对象
1、函数调用

当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的。在此种模式下,this被绑定为全局对象,在浏览器环境下就是window对象。

    <script>
        function people() {
            var name = '小明';
            console.log(this.name);
            console.log(this);
        }
        people();
    </script>

在这里插入图片描述

2、方法调用

当函数被保存为一个对象的属性时,它就可称为这个对象的方法。当一个方法被调用时,this被绑定到这个对象上。如果调用表达式包含一个提取属性的动作(.或 []),那么它被称为方法调用。

    <script>
        var people = {
            name:'小明',
            sayName:function() {
                console.log(this.name);
            }
        }
        people.sayName();
    </script>

在这里插入图片描述

3、构造函数调用

在构造函数new出一个对象时,this指向这个构造函数,new关键字会改变this的指向。

    <script>
        function People() {
            console.log(this);
        }
        var xm = new People();
    </script>

在这里插入图片描述

    <script>
        function People() {
            this.name = '小明';
        }
        var xm = new People();
        console.log(xm.name);
    </script>

在这里插入图片描述

4、call和apply调用

JS中,函数也是对象,所有函数对象都有两个方法:apply和call,这两个方法可以让我们构建一个参数数组传递给调用函数,也允许我们改变this的值。

    <script>
        let obj1={
            name:"xm",
            fn(){
                console.log(this.name)
            }
        }
        let obj2={
            name:"xh",
            fn(){
                console.log(this.name)
            }
        }
        obj1.fn.call(obj2)
    </script>

在这里插入图片描述

数组和字符串互相转换

1、数组转字符串
    <script>
        var a,b;
        a = new Array(0,1,2,3,4);
        b = a.join("-");
        console.log("a:"+a);
        console.log("b:"+b);
    </script>

在这里插入图片描述

2、字符串转数组
    <script>
        var s = "abc,abcd,aaa";
        ss = s.split(",");// 在每个逗号(,)处进行分解  ["abc", "abcd", "aaa"]
        console.log("ss:"+ss);
        var s1 = "helloworld";
        ss1 = s1.split('');  //["h", "e", "l", "l", "o", "w", "o", "r", "l", "d"]
        console.log("s1:"+s1);
    </script>

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值