zoukankan      html  css  js  c++  java
  • 《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等。
    • 框架和插件区别
    框架:大而全,一整套解决方案
    插件:小而专一,某个功能的解决方案
    
  • 相关阅读:
    跃迁方法论 Continuous practice
    EPI online zoom session 面试算法基础知识直播分享
    台州 OJ 2648 小希的迷宫
    洛谷 P1074 靶形数独
    洛谷 P1433 DP 状态压缩
    台州 OJ FatMouse and Cheese 深搜 记忆化搜索
    台州 OJ 2676 Tree of Tree 树状 DP
    台州 OJ 2537 Charlie's Change 多重背包 二进制优化 路径记录
    台州 OJ 2378 Tug of War
    台州 OJ 2850 Key Task BFS
  • 原文地址:https://www.cnblogs.com/anjun-xy/p/14384903.html
Copyright © 2011-2022 走看看