js是单线程的
任务会一个接一个执行
- 同步 :前一个任务结束后再去执行另一个任务,程序的执行顺序与任务的排列顺序一致 同步任务都在主线程上执行,形成执行栈
- 异步:在做这件事的同时,可以去做其他事
js的异步是通过回调函数实现的
一般异步任务三种类型
- 两个定时器(
setInterval,setTimeout
) - 普通事件(
click,resize
) - 资源加载(
load,error
)
执行过程
- 把除去异步任务之外的就是同步任务,先把同步任务放在执行栈,异步任务放到任务队列
- 依次执行任务栈中任务,执行完再将任务队列的处于等待的异步任务拿过来执行
循环往复就是event loop
事件循环
事件流
- 事件完整执行过程中的流动路径捕获阶段然后到冒泡阶段
- 捕获阶段是从文档
document
一级一级往下,捕获事件触发的那个标签,然后到冒泡阶段,在一级一级原路返回
事件冒泡
- 当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这一过程称之为事件冒泡
- 事件冒泡是默认存在的
简单理解
- 当一个元素事件被触发时,会依次向上调用所有祖先元素的同名事件(比如子元素事件是点击,如果祖先元素有单击事件,则会依次向上触发)
- 这里的事件理解为系统的事件,单纯写个
span
文本,没有绑定事件以及调用的函数,仅仅在浏览器进行点击该标签区域,鼠标移入移出,都会有冒泡过程,当我点击该标签区域,鼠标移入移出,如果祖先元素有绑定相关事件,则会依次向上调用出来
事件委托
- 提高性能
- 把原本需要绑定在子元素上的事件,委托绑定在父元素上,当事件发生在子元素上,依据事件冒泡的原理,会从该子元素依次向上触发所有祖先元素与之的相同的事件,从而来操作子元素,,,事件对象
e.target 属性
存储的数据就是 触发事件的对象
事件捕获
DOM.addEventListener
(事件类型,事件处理函数,是否使用捕获机制)addEventListener
第三个参数传入true伐表是捕获阶段触发(很少使用)- 若传入false代表冒泡阶段触发,默认就是false
- 若是用LO事件监听,则只有冒泡阶段,没有捕获 //
L0事件 : btn.onclick = function(){}
阻止事件冒泡
- 要用到事件对象e
e.stopPropagation()
添加这代码到事件里 即可 将事件限制在当前元素,有一个事件加一个这代码
注意:
mouseover
和mouseout
会有冒泡效果mouseenter
和mouseleave
没有冒泡效果(推荐)
阻止默认行为
例如链接的跳转,表单的跳转
<a href=“www.baidu.com”>跳转<a>
let a = document.querySelector('a')
a.addEventListener('click',function(e){
e.preventDefault()
})
回调函数
- 如果将
函数A
做为参数传递给函数B时,我们称函数A
为回调函数 - 简单理解:当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数常见的使用场景:
function fn (){
console.log('我是回调函数')
}
setInterval(fn,1000)
fn传递给了setInterval,fn就是回调函数;;;;
btn.addEventListener('click',function(){
console.log('我也是回调函数')
})
当我点击了,才回来调用这个函数
关于节点
DOM节点
DOM树
里的每一个内容都称之为节点
节点类型
- 元素节点:所有的html标签,如
body div,。。。。。html
是根节点; - 属性节点:所有的属性 如
type href src
; - 文本节点:所有的文本
增加节点
- 创建一个新的节点
let li = document.createElement('标签名div 或li ')
- 把创建的新的节点放入的指定的元素内部
1)追加到父元素内容的最后绑定的父元素.appendElement(li)
2)插入到父元素中某个子元素的前面父元素.insertBefore(要插入的元素,在哪个元素前面)
<body>
<ul>
<li>我是第1个</li>
<li>我是第2个</li>
<li>我是第3个</li>
<li>我是第4个</li>
<li>我是第5个</li>
</ul>
<script>
let ul = document.querySelector('ul')
let li1 = document.createElement('li')
li1.innerHTML = '我是创建的第一个li'
let li2 = document.createElement('li')
li2.innerHTML = '我是创建的第二个li'
ul.appendChild(li1)
ul.insertBefore(li2, ul.children[1])
</script>
显示结果:
<ul>
<li>我是第1个</li>
<li>我是创建的第二个li</li>
<li>我是第2个</li>
<li>我是第3个</li>
<li>我是第4个</li>
<li>我是第5个</li>
<li>我是创建的第一个li</li>
</ul>
</body>
特殊情况下通过克隆节点然后追加节点,原有的节点发生变化,克隆的也发生变化,灵活性强 克隆一个已有的元素节点
let ul = document.querySelector('ul')
let newUl = ul.cloneNode(布尔值),默认为false // 克隆了ul
当布尔值为false时,则表示克隆时不包含后代节点
当布尔值为true时,则表示克隆时会包含后代节点一起克隆
删除节点
在JavaScript 原生DOM操作中,要删除元素必须通过父元素删除
语法:父元素.removeChild(要删除的元素)
node
节点parentNode 属性
找到父节点children 属性
仅仅返回元素节点nextElementSibling
下一个元素节点previousElementSibling
上一个元素节点
- 在tab切换时,一般思想是先循环干掉所有人再复活我自己,但是,循环一遍只为干掉其中一个有点浪费
- 所以可以找到那唯一一个并且把他的类删了即可,不用使用遍历
- 但是先要默认有一个人有 pink这个类,否则报错
例如:document.querySelector( ' .pink ' ).classList.remove( 'pink ')
,然后再给自己加
访问对象属性获取值的两种方法
对象.属性
对象['属性']
删除对象某属性
delete 对象.属性