原生js深入理解系列(三)--- 事件冒泡的分析以及如何防止事件冒泡

583 阅读5分钟

任务目的

在上一任务基础上继续JavaScript的体验 接触一下JavaScript中的高级选择器 学习JavaScript中的数组对象遍历、读写、排序等操作 学习简单的字符串处理操作 任务描述 参考以下示例代码,读取页面上已有的source列表,从中提取出城市以及对应的空气质量 将数据按照某种顺序排序后,在resort列表中按照顺序显示出来

一、总结

实现效果使用到的技术: 一、

 // document.getElementsByTagName
 // document.getElementsByClassName
 // document.querySelectorAll,

这些方法获取到的结果是个集合,并不是数组,而map,forEach这些方法只有在数组原型里面才有,所以可以先将它们转化Array.from
二、 // innerText会忽略标签只取标签里的内容,注意子标签也会被忽略
三、普通的IE浏览器的判断

// event=event?event:window.event; 
// event.stopPropagation(); 
// Event对象:
// 在IE浏览器中,event对象是window对象的一个属性。

四、冒泡的防止与event.preventDefault() 方法阻止元素发生默认的行为。

//event.preventDefault() 方法阻止元素发生默认的行为。是jQuery的
 event.preventDefault();js原生也有这个方法
 该Event接口的preventDefault()方法告诉用户代理,
 如果该事件没有得到明确处理,则不应该像通常那样采用默认操作。
 事件继续像往常一样传播,除非它的一个事件监听器调用stopPropagation()或者
 stopImmediatePropagation()其中一个立即终止传播。
V8浏览器 event.stopPropagation、preventDefault()在事件流的任何阶段进行调用都会取消事件,
这意味着实现通常由事件执行的任何默认操作都不会发生。

从Gecko 6.0开始,调用preventDefault()会导致Event.defaultPrevented()属性的值变为true。

您可以使用Event.cancelable来检查事件是否可以取消。调用preventDefault()不可取消的事件不起作用。
cancelable和preventDefault()合用可以取消可取消事件
该Event.cancelBubble是一个历史的别名Event.stopPropagation()。
true在从事件处理程序返回之前将其值设置为阻止事件的传播。
在稍后的实现中,将其设置为false将不起作用。

伍、原生实现创建新的dom并加载在目标dom里面

    let liDom = document.createElement('li')
    liDom.innerHTML =`第${sortIndex[index]}名:${item[0]}空气质量:<b>${item[1]}</b>`
    apppendDom.appendChild(liDom)

这里还用到了es6的模板字符串的一些基本用法

六、较少重载的操作将整个待插入数据进行字符串处理再统一给通过innerHTML赋给目标dom

data.forEach((item,index) => {
     newstring +=`<li>第${sortIndex[index]}名:${item[0]}空气质量:<b>${item[1]}</b></li>`
  })

七、sort处理排序问题,还有浅拷贝和深拷贝要区分下。下次专题分析

let newArr=data.sort((a,b)=>{
  return a[1]-b[1] //取的是true
}) //这里是浅拷贝原数组data也会发生改变
console.log(newArr,111111)

二、源码 // 源码---start

<html>
<head>
<meta charset="utf-8">
<title>IFE JavaScript Task 01</title>
</head>
<body>
 
<ul id="source">
<li>北京空气质量:<b>90</b></li>
<li>上海空气质量:<b>70</b></li>
<li>天津空气质量:<b>80</b></li>
<li>广州空气质量:<b>50</b></li>
<li>深圳空气质量:<b>40</b></li>
<li>福州空气质量:<b>32</b></li>
<li>成都空气质量:<b>90</b></li>
</ul>
 
<ul id="resort">
<!--
<li>第一名:北京空气质量:<b>90</b></li>
<li>第二名:北京空气质量:<b>90</b></li>
<li>第三名:北京空气质量:<b>90</b></li>
-->
 
</ul>
 
<button id="sort-btn">排序</button>
 
<script type="text/javascript">
 
/**
* getData方法
* 读取id为source的列表,获取其中城市名字及城市对应的空气质量
* 返回一个数组,格式见函数中示例
* data = [
["北京", 90],
["北京", 90]
……
]
 
*/
function getData() {
/*
coding here
*/
const targetDom = document.getElementById('source')
// document.getElementsByTagName
// document.getElementsByClassName
// document.querySelectorAll,这些方法获取到的结果是个集合,并不是数组,而map,forEach这些方法只有在数组原型里面才有,所以可以先将它们转化Array.from
let targetLiDom = Array.from(targetDom.getElementsByTagName('li')); // 转化为数组
console.log(targetLiDom)
let data = targetLiDom.map((itemDom) => {
let item = [];
// innerText会忽略标签只取标签里的内容,注意子标签也会被忽略
let middle = itemDom.innerText;
//注意console。log的变化
console.log(middle,1)
let middleArr = middle.split(':');
console.log(middleArr,2)
let arrOne = middleArr[0].replace('空气质量', '');
item.push(arrOne);
let arrTwo = middleArr[1]
/*let arrTwo = itemDom.querySelector('b').innerText;*/
item.push(arrTwo)
return item
})
console.log(data,3)
return data;
 
}
 
/**
* sortAqiData
* 按空气质量对data进行从小到大的排序
* 返回一个排序后的数组
*/
function sortAqiData(data) {
// let targetLiDom = Array.from(targetDom.getElementsByTagName('li')); // 转化为数组
/*targetLiDom.filter(val=>{
val.querySelector('b').innerText
})*/
let newArr=data.sort((a,b)=>{
return a[1]-b[1] //取的是true
}) //这里是浅拷贝原数组data也会发生改变
console.log(newArr,111111)
render(newArr)
}
 
/**
* render
* 将排好序的城市及空气质量指数,输出显示到id位resort的列表中
* 格式见ul中的注释的部分
*/
function render(data) {
const apppendDom = document.getElementById('resort');
const sortIndex = ['一','二','三','四','伍','六','七','八','九','十']
let newstring=''
data.forEach((item,index) => {
let liDom = document.createElement('li')
liDom.innerHTML =`第${sortIndex[index]}名:${item[0]}空气质量:<b>${item[1]}</b>`
apppendDom.appendChild(liDom)
})
//较优方法多js字符串处理只操作一次dom赋值
/*data.forEach((item,index) => {
newstring +=`<li>第${sortIndex[index]}名:${item[0]}空气质量:<b>${item[1]}</b></li>`
})
apppendDom.innerHTML = newstring*/
}
 
function btnHandle() {
var aqiData = getData();
aqiData = sortAqiData(aqiData);
render(aqiData);
}
 
function init() {
// 在这下面给sort-btn绑定一个点击事件,点击时触发btnHandle函数
let targetDom = document.getElementById('sort-btn');
// event=event?event:window.event;
// event.stopPropagation();
// Event对象:
// 在IE浏览器中,event对象是window对象的一个属性。
if(window.event){
console.log(window.event,4)
alert(4)
targetDom.attchEvent('click', function(e){
btnHandle();
e.cancleBubble()
})
}else{
targetDom.addEventListener('click', function(e){
btnHandle();
e.stopPropagation()
})
}
}
 
init();
 
</script>
</body>
</html>
// 源码---end

欢迎一起交流学习