《Javascript核心DOM、BOM操作》笔记

Javascript核心DOM、BOM操作(pink老师),笔记

  • DOM学习目标:能获得页面元素、给元素注册事件、操作元素的属性、创建元素、操作DOM节点。

  • console.dir(input等元素对象),打印对象所有方法和属性。

  • 事件三要素:事件源、事件类型、事件处理程序

  • 事件执行步骤;

1.获取事件源 (如:下拉控件)
2.注册事件(绑定事件) (如:鼠标移到上事件)
3.添加事件处理程序(采取函数赋值形式) (如:显示下拉内容)
  • 通过event对象获得事件源信息
//button的click绑定的查询方法
function seachData() {
	let btnText=$(event.target).text();//获得事件源文本
}
  • Document 对象属性和方法
document.getElementsByClassName('')			返回文档中所有指定class的元素集合,作为 NodeList 对象。
document.getElementById('')				返回对拥有指定 id 的第一个对象的引用。
document.getElementsByName('name')			返回带有指定名称的对象集合。
document.getElementsByTagName('div') 			返回带有指定标签名的对象集合。
document.querySelector('#demo/.classDiv/div') 	        返回第一个div控件
document.querySelectorAll(同上)         		返回所有符合选择器的元素(数组)
document.body						返回html文档的body元素
document.documentElement				返回html文档的html根节点
  • vue通过ref为控件设置属性:this.$refs['refName'].$el.querySelectorAll('input')[0].style.cursor = 'not-allowed';//不允许操作

  • 给按钮注册事件

document.getElementById('btnStart').onclick=function(){ 
 document.getElementById('txt1').value++;//数字不断加1 
};
  • html中disabled和readonly区别:
  • disabled属性作用于所有表单元素。
  • readonly属性只对<input type="text/number/password">、<textarea>等可以输入的表单元素有效。
  • disabled属性元素值表单无法被提交。readonly不受影响。
  • 修改元素样式、元素属性值设置、移除与获得
document.getElementById('txt1').style.color='red';//该input文本颜色(行内样式,一次只能一个样式)
document.getElementById('txt1').className='样式类名1 类名2';//为input修改class属性(可一次性为控件添加大量样式)
list[i].removeAttribute("readOnly");//【移除属性】
list[i].setAttribute("readOnly", true);//【为属性赋值(支持自定义属性)】
document.querySelector('div').id;//【获得属性方法1(只能获得本身自带)】
document.querySelector('div').getAttribute('id');//【获得属性方法2(获得自带+自定义属性)】
  • 自定义属性,目的是保存一些数据,方便在页面者使用。只能用getAttribute方法获得内容。
  • H5规定,自定义属性都是data-开头并赋值。
<div id='a' data-index='1' data-list-name='abc'>内容</div>
var div=document.querySelector('#a');
console.log(div.dataset)//【返回div 所有`data-`开头的自定义属性。】
console.log(div.dataset.index)//【返回div data-index的自定义属性值。】
console.log(div.dataset.listName)//【属性是驼峰命名法,返回div data-list-name的自定义属性值。】

网页节点增删改查

  • DOM操作核心:对元素、属性进行创建和增删改查、事件操作。
  • 节点选取:通过DOM方法(get...ById/ByTagName等);通过节点“父子兄”关系获得(逻辑性强,但是兼容差)。
  • 节点,至少要有“nodeType类型、nodeName名称、nodeValue值”。
  • html中元素对象有3类:文本节点值是3(如:文字、空格、换行);属性节点是2(如href等),元素节点是1(如input、div等).
 var div1=document.querySelector('#a');
 div1.parentNode;//离元素最近的父亲节点(就近原则),找不到就null
 div1.childNodes;//所有的各类子节点(返回集合)
 div1.children;//所有的元素类子节点
 div1.first/lastElemnetChildren;//首尾元素类子节点
 div1.nextElementSibling;//下一个兄弟节点(支持那3类)
 div1.previousElementSibling;//上一个。。 
 div1.appendChild(document.createElement('li'));//指定节点后追加节点
 div1.insertBefore(创建的节点对象,A);//A对象前面插入元素
 div1.removeChild()//删除父内的子元素
 var copyObj=div1.cloneNode();//复制节点(false仅copy标签,true则copy标签+内容)
  • 练习:用上面知识点动态一个table并填入内容,最后一列是删除,有一个添加按钮可动态加到table下面。

  • 三种动态创建元素:(innerHTML比createElement高效)

document.write('<div>123</div>');//写入页面内容流,但是文档流执行完毕,则它会导致页面全部重绘(write的内容覆盖旧的)
element.innerHTML;//技巧--放到数组最后join赋值则1000次循环只会几毫秒。如果循环内拼接字符串,会非常耗时(1000个耗时3s)。结构复杂
document.createElement();//(循环创建1000个耗时20ms),结构清晰

事件

  • 目录:
出元素注册事件的两种方式
删除事件的两种方式
DOM事件流的三个阶段
利用事件对象完成跟随鼠标案例
阻止冒泡的兼容性函数
事件委托的原理
常用的鼠标和键盘事件
  • 传统注册方式:(注册事件唯一性 —— 同一个元素同一个事件只能一个设置一个函数,后注册覆盖前面的)
<button onclick='alert(1)'/> 
或
btn.onclick=function(){}
  • 方法监听注册方式:w3c推荐eventTarget.addEventListener(事件类型字符串,函数,bool可选参数)(仅IE9+)。同一个元素同一个事件可以注册多个监听器,按注册顺序依次执行。
  • 在目标对象上指定监听器,当该事件触发时执行处理函数。
  • 事件类型串:click、mouseover等不带on。
  • 注册事件有两种方式:传统方式和方法监听注册方式。
  • 监听方式注册事件
var btns = document.querySelectorAl1( ' button');
btns[1].addEventListener('click',function(){
	alert('1');
});//监听方式加事件1
btns[1].addEventListener('click',ff);//监听方式加事件2
function ff(){ alert(22);}
btns[1].removeEventListener('click',ff)//删除事件(要移除的事件必须指明方法名称)
 
  • 删除事件方式:传统方式注册事件的删除——控件对象.onclick=null;

  • DOM事件流

  • 事件流描述的是从页面中接收事件的顺序。
  • 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
  • 事件流:当为div加click事件,实际是按document -> html -> body -> div依次触发click事件,叫“捕获阶段”,逆过程叫“冒泡阶段”。像极了往水里丢石头,先下沉到底后冒泡。
  • addEventListener(type, listener[,usecapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(默认值),表示在事件冒泡阶段调用事件处理程序。
  • 验证捕获阶段传递顺序办法:分别为body和div注册click事件,设为true,点击后依次按父子顺序弹提醒。
  • 无冒泡的事件onblur、onfocus、onmouseenter、onmouseleave

事件对象

  • 事件对象只有发生了事件才会存在,系统给我们创建,不需要我们传递参数。
  • 事件对象是一系列跟事件相关的数据集合,比如鼠标坐标或可以判断用户按下了哪个键。
  • 常见事件对象属性:
event.target 触发事件的对象。this返回的是绑定事件的对象(如给ul绑定click事件,点了li元素`console.log(this)`返回ul对象)。
event.currentTarget 类似this返回值(低浏览器不兼容)。
event.type 	 返回事件的类型比如click、mouseover不带on
event.preventDefault()  该方法阻止默认事件(默认行为),比如不让链接跳转
event.stopPropagation() 阻止冒泡标准
  • 引子:给每个li加click事件。
  • 事件委托的原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响每个子节点。
  • 案例:给ul注册点击事件,然后利用事件对象的target 找到点击的li,因为事件会冒泡到ul上,就会触发事件监听器。
  • 事件委托作用:我们只操作了一次DOM,提高了程序的性能。
document.querySelector('ul').addEventListener('click',function(e){
	e.target.style.backgroundColor='gray';//点击的li置灰
})

contextmenu主要控制是否显示上下文菜单,selectstart阻止选中文字

document.addEventListener('contextmenu', function(e){//
	e.preventDefault() ;
})
  • MouseEvent对象
e.clientX/Y   获得鼠标点击时距离浏览器边缘x/y坐标(忽略滚动条) 
e.pageX    鼠标相对浏览器内衬x坐标(考虑滚动条)
e.pageY    。。。
e.screenX/Y  获得鼠标点击时距离屏幕边缘x/y坐标 
  • element.getBoundingClientRect()用于获得页面中某个元素的左右上下值(类似上面screenX/Y和clientX/Y)分别相对浏览器视窗的位置(不包含文档卷起的部分)。
  • 键盘事件
  • onkeydown和keypress都是鼠标按下事件,但是后者对shift、箭头键等不能识别。
  • 3个事件有顺序keydown → keypress → keyup。keyup和keydown不分字母大小写。keypress区分大小写。只有keyup时文字才进入文本框。
  • 键盘事件对象,keyCode返回按键ASCII值(可以通过如下代码在chrome贴到控制台回车后,在页面里按按键即可查看)
document.addEventListener('keydown', function(e){
	console.log(e.keyCode );
})

BOM

  • BOM(浏览器对象模型),提供了与浏览器窗口进行交互的东西,核心对象是window。BOM缺乏标准。js标准是ECMA制定,DOM是W3C制定,而BOM最初是Netscape浏览器标准一部分。
  • DOM顶级对象的document。BOM则是window。BOM包含了DOM。window = document+location+navigation+screen+history
  • window对象是浏览器的顶级对象,它具有双重角色。
  • 1.它是JS访问浏览器窗口的一个接口。
  • 2.它是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法。
  • console.dir(window);——可以查看window对象都有什么。
  • js写在html尾部。写在顶部则可借用window.onload(页面全部(dom元素、图片、flash、css等)加载完)一个页面只能有一个,添加侦听事件可以多个。IE9+有DOMContentLoaded仅DOM加载完就触发,不含样式表,图片,flash等。比load事件先执行。
  • window.onresize页面大小调整时触发。
  • window.innerWith浏览器窗口大小
  • 两种定时器函数并说出区别
  • var aa = window.setTimeout(函数,延迟毫秒数);定时器,到时候执行函数(也叫执行回调函数)。时间可省略,没有则默认0即立刻执行。
  • window.clearTimeout(定时器别名)清除定时器。
  • window.setInterval(函数,间隔毫秒数),每间隔这个时间,就调用一次回调函数。window.clearInerval(定时器别名)清除定时器。
  • 为什么要用 setTimeout 模拟 setInterval?定时器指定的时间间隔,表示的是何时将代码加到消息队列,而不是何时执行代码。所以真正何时执行代码的时间是不能保证的,取决于何时被主线程的事件循环取到,并执行。setInterval 缺点是很明显的,为了解决这些弊端,可以使用 setTimeout() 代替。在前一个定时器执行完前,不会向队列插入新的定时器(解决缺点一),保证定时器间隔(解决缺点二)
  • 一般情况下this最终指向的是那个调用它的对象。
  • 全局作用域或普通函数中this指向全局对象window。
  • console.log(this)可通过这样查看this是什么。
  • JS执行机制
  • js是单线程的。所有任务都要排队。
  • h5提出web worker标准,允许js脚本创建多个线程,于是js出现了同步和异步。
  • js把同步任务放到主线程执行栈,异步任务(回调函数:定时器,普通事件,资源加载)放到任务队列(消息队列)中执行。
  • 先执行完同步任务,最后把异步任务放到主线程去执行。
console.log(1);
setTimeout(function() {
	console.log(3);
},0); 
document.onclick=fun;
console.log(2);
//最终打印:1,2,3。只有点击后才会把fun放入异步任务中,然后放入主线程中执行。
  • 由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)
  • location对象完成页面之间的跳转(可F12输入location回车查看)
location.href 获取或者设置整个URL
location.search 返回参数
location.host 返回主机(域名)www.itheima.com
location.port 返回端口号,如果未写返回空字符串
location.pathname 返回路径
location.hash 返回片段 #后面内容常见于链接锚点
location.assign()  跟href一样,可以跳转页面(也称为重定向页面,可后退)
location.replace() 替换当前页面,因为不记录历史,所以不能后退页面。
location.reload()  重新加载页面,相当于刷新按钮或者f5,如果参数为true,强制刷新(ctrl+f5)。
  • navigator对象包含浏览器信息,最常用的是userAgent(客户端发送到服务器的user-agent头部信息,判断是手机还是pc浏览器)
    history提供的方法实现页面刷新
//JS通过UA(userAgent)判断加载手端或pc端页面
if(navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
	window.location.href='http://m.ke361.com';//手机
}else {
	window.location.href = "http://www.ke361.com";//电脑
}
  • history对象
back()    可以后退功能
forward() 前进功能
go(参数)  前进后退功能。参数如果是1前进1个页面,如果是-1后退1个页面
  • 存储容量:sessionStorage约5MB(同一个页面)、localStorage约20MB(同一域名所有页面)。
  • offset(元素偏移量)和style区别:
  • offset可以得到任意样式表中的样式值
  • offset系列获得的数值是没有单位的
  • offsetWidth包含padding+ border+width
  • offsetWidth等属性是只读属性
  • 所以,我们想要获取元素大小位置,用offset更合适
  • style只能得到行内样式表中的样式值
  • style.width获得的是带有单位的字符串
  • style.width获得不包含padding和border的值
  • style.width是可读写属性
  • 所以,我们想要给元素更改值,则需要用style改变
  • 元素可视区client系列:使用client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。返回数值不含边框含padding和内容区的宽和高,其他都与offset一样。
  • 立即执行函数:不需要调用,立马能够自己执行的函数。主要作用:创建一个独立的作用域。避免了命名冲突问题。

写法:(function(){})()(function(){}())。内部变量都是局部变量。

  • 移动端项目,考虑到兼容性,现在使用比较多的是用rem。flexible.js是淘宝为了适配移动端开发的一个插件。
  • rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。
  • onpageshow 事件在用户浏览网页时触发。onpageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, onpageshow 事件在每次加载页面时触发,即 onload 事件在页面从浏览器缓存中读取时不触发。
  • 元素滚动scroll系列:
element.scrollTop 返回被卷去的上侧距离,返回数值不带单位
element.scrollLeft 返习被卷去的左侧距离,返回数值不带单位
element.scrollWidth 返回自身实际的宽度,不含边框,返回数值不带单位
element.scrollHeight 返回自身实际的高度,不含边框,返回数值不带单位
element.offsetWidth 返回自身包括padding、【边框】、内容区的宽度,返回数值不带单位
element.clientWidth 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位
element.scrollWidth 返回自身实际的宽度,不含边框,返回数值不带单位。
offset系列经常用于获得元素位置offsetLeft offsetTop
client经常用于获取元素大小clientwidth clientHeight
scroll经常用于获取滚动距离scrollTop scrollLeft
注意页面滚动的距离通过window.pagexoffset获得。
  • 获得div标签坐标和宽高信息
let h = divObj.offsetHeight;//div高度
let w = divObj.offsetWidth; //div宽度
let y = divObj.offsetTop;   //div左上点的y坐标
let x = divObj.offsetLeft;  //div左上点的x坐标 
  • js获得电脑屏幕分辨率的宽*高:window.screen.width, window.screen.height
  • mouseover鼠标经过自身盒子和子盒子都会触发(有冒泡)。mouseenter只会经过自身盒子触发(无冒泡)。
  • 动画核心原理:通过定时器setInterval()不断移动盒子位置。
  • 缓动动画就是让元素运动速度有所变化,最常见的是慢慢停下来。
  • 缓动动画核心算法:(目标值 - 现在的位置) / 10做为每次移动的距离步长。
//封装动画函数(参数:元素对象,目标位置,回调函数)
function animate(obj, target,fun) { 
	clearInerval(obj.timer);//先清除以前的定时器,只保留当前的一个定时器执行
	obj.timer = setInterval(function() {
		var step=(target-obj.offsetLeft)/10;//缓动动画步长
		step>0?Math.Ceil(step):Math.floor(step);//(不出现小数)
		if (obj.offsetLeft >= target) { 
			clearInterval(obj.timer);//停止动画本质是停止定时器
			if(fun){fun();}//执行回调函数  或高级版:fun&&fun(); —— 短路运算
		}
		obj.style.left = obj.offsetLeft + step + 'px';
	},15);
} 
var span = document.queryselector('span');
var btn = document.queryselector('button');
btn.addEventListener('click', function() { 
	animate(span,500, function(){alert('你好')} );//调用函数
})
  • 点击左右滚动显示图片,在点击过快时图片无法显示完就到下一张了。解决办法—— 节流阀if(flag){flag = false; do something ;flag =true;}关闭和打开水龙头。结合上面动画函数,则flag=true放到回调函数中最合适,这样在一张图片结束后才执行下一个次动画。
  • 滚动窗口至文档中的特定位置window.scroll(x, window.pageYOffset)
  • 移动端特有的touch事件
touchstart 手指触摸DOM事件
touchmove 手指移动事件
touchend  手指离开事件
  • 上述三个事件对象常见属性
touches 正在触摸屏幕的所有手指的一个列表
targetTouches (最常用)正在触摸当前DOM元素上的手指的一个列表
changedTouches 手指状态发生了改变的列表,从无到有,从有到无变化
  • 移动端拖动的原理:手指移动中,计算出手指移动的距离。然后用盒子原来的位置+手指移动的距离
  • 手指移动的距离:手指滑动中的位置减去 手指刚开始触摸的位置
  • 拖动元素三步曲:
  • (1)触摸元素touchstart:获取手指初始坐标,同时获得盒子原来的位置
  • (2)移动手指touchmove : 计算手指的滑动距离,并且移动盒子
  • (3)离开手指touchend:
  • 手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动e.preventDefaultO;
  • H5新属性:classList返回元素的类名集合。也可以添加或移除及切换css类。
var div = document.querySelector('div');
console.log(div.classList);//classList返回元素的类名
div.classList.add('不带点的类名');//追加类名
div.classList.remove('不带点的类名');//移除指定类名
div.classList.toggle('不带点的类名');//切换类名(有则移除,没有则追加上)
  • 移动端click事件会议300ms的延迟,原因是移动端屏幕双击缩放页面,300ms内点了两下就会缩放。
  • 解决方案
  • 1.禁用浏览器默认的双击缩放行为且去掉300ms点击延迟 —— <meta name="viewport" content="user-scalable=no">
  • 2.利用touch事件自己封装事件解决300ms延迟。原理就是:1.当手指触摸屏幕,记录触摸时间。2.当手指离开屏幕,用离开的时间减去触摸时间,小于150ms且没滑动屏幕就视为点击。
  • fastclick插件。插件就是js文件,为解决一个专门问题而封装的功能单一的方法。
  • Swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端。
  • 常用的“焦点图/幻灯片”“Tab标签切换”“图片滚动”“无缝滚动”等只需要一个SuperSlide即可解决!
  • iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件。
  • 移动端视频插件zy.media.js,实现所有浏览器播放器风格统一。
<video src='a.mp4' controls></video>
  • 框架,顾名思义就是一套架构,它会基于自身的特点向用户提供一套较为完整的解决方案。框架的控制权在框架本身,使用者要按照框架所规定的某种规范进行开发。前端常用框架Vue、Angular、React等。
  • 框架和插件区别
框架:大而全,一整套解决方案
插件:小而专一,某个功能的解决方案
原文地址:https://www.cnblogs.com/anjun-xy/p/14384903.html