javascript进阶
一、DOM(文档对象模型)
DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
DOM 是 w3c 推荐的HTML的标准编程接口。
所有 HTML 元素被定义为对象,而编程接口则是对象方法和对象属性。
- 方法是您能够执行的动作(比如添加或修改元素)。
- 属性是您能够获取或设置的值(比如节点的名称或内容)。
通过DOM可改变网页的内容、结构和样式。返回的都是对象
文档(document)、元素(element)、节点(node)
-
方法
getElementById():返回带有指定 ID 的元素。
getElementsByTagName():返回包含指定 标签名称 的所有元素的节点列表(集合/节点数组)。
getElementsByClassName():返回包含带有指定 类名 的所有元素的节点列表。
querySelector(‘选择器’):返回指定选择器的第一个元素对象。
querySelectorAll(‘选择器’)
appendChild():把新的子节点添加到指定节点。
removeChild():删除子节点。
replaceChild():替换子节点。
insertBefore():在指定的子节点前面插入新的子节点。
createAttribute():创建属性节点。
createElement():创建元素节点。
createTextNode():创建文本节点。
getAttribute():返回指定的属性值。
setAttribute():把指定属性设置或修改为指定的值。
… … -
属性(先获取元素再事件绑定赋值属性)
(1) innerText和innerHTML的区别:
innerText 不识别HTML标签,去除空格和换行,不标准
innerHTML 识别HTML标签,保留空格和换行,w3c标准 (普通盒子,比如div标签里的内容)
(2)表单属性:type、value、disabled(禁用)、checked、selected
(3)样式属性:JS修改style样式操作,产生的是行内样式;className类名样式会直接改变元素的类名,覆盖原先的类名; -
操作属性
(1)获取元素值:element. 属性(获取的是内置的属性值) 或者 element.getAttribute(‘属性’)(自定义属性值)
(2)设置属性值:element.属性=“值” 或者 element.setAttribute(“属性”,“修改后的属性值” )
- H5自定义属性:自定义属性目的:为了保存并使用数据。有些数据可以保存到页面而不用保存到数据库。H5规定自定义属性 data- 开头作为属性名并赋值。
如<div data-index='1'>
,除了可以 element.getAttribute( ‘data-index’ )外,还可以通过element.dataset.index
或者element.dataset['index'];
如果我们自定义属性里面有多个 – 链接的单词,我们获取的时候应采取驼峰命名法。
注:可以用于懒加载
懒加载 和 预加载:详细介绍
- 节点操作(注意节点和元素节点区别)
获取元素方法:利用DOM方法获取; 利用节点层级关系获取。
(1)节点:
nodeType:节点类型,元素节点为1,属性节点为2,文本节点为3
parentNode 父节点(最近的一个父节点);
childNodes 子节点(得到的所有字节点包含 元素节点 和 文本节点,一般需要和nodeType一起辨别)
children 获取所有子元素节点
firstChild 第一个子节点;(lastChild最后一个子节点)
firstElementChild 返回第一个子元素节点
nextSibling 下一个兄弟节点 (previousSibling上一个兄弟节点)
nextElementSibling 下一个兄弟元素节点
createElement(‘元素’) 创建节点
node.appendChild(child) 添加节点(首先要先创建节点)
node.insertBefore(child,指定元素) 添加到指定元素的前面
node.removeChild(child) 删除节点
node.cloneNode() 克隆节点,若括号参数为空或false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
(2)三种创建元素方式区别(面试必会):
- document.write() :是直接将内容写入页面的内容流。如果文档流执行完毕,再调用这句话会导致页面全部重绘。
- element.innerHTML :将内容写入某个DOM节点,不会导致页面全部重绘。创建多个元素效率更高(不要拼接字符串,采用数组形式拼接
arr.push('<a href='#' ></a>') //得到用逗号隔开的数组形式
arr.join(' '); //数组转换成字符串
)结构稍微复杂。 - document.createElement(‘a’) 创建多个元素效率稍低一点,但结构更清晰
- 一些巧妙运用:赋值操作、for循环变量乘(设置位置) 、排他思想、直接更换类名className赋予新的类属性
- 百度换肤:通过querySelectorAll()获取所有数组对象后,for循环,this.src就是路径,把路径给body:document.body.style.backgroundImage=‘url(’ + this.src + ‘)’ ;
- 表单全选:(html里input设置了属性type=“checkbox”,进行全选的其内还设置了id)通过getElementByTagName(“input”)获取元素,事件内使用for循环,a[i].checked= this.checked;
- tab栏切换布局:自定义属性及属性值来获取对应索引号(使用setAttribute()和getAttribute())。
- 下拉菜单:html中嵌套使用ul和li,第一层li中的第二个子元素是需要隐藏的ul。
- 删除留言:添加删除链接,阻止链接跳转使用 href=” javascript:; “
- 动态生成表格: 清晰结构,元素间的父子关系
二、事件
- 事件:触发—->响应机制。分为三部分:事件源(被触发对象)、事件类型(如何触发)、事件处理程序(通过一个函数赋值的方式)。
- 注册事件(绑定事件):传统方式 和 方法监听注册方式
(1)传统方式:利用on开头的onclick,注册事件的唯一性,后面的函数覆盖前面的。
(2)方法监听注册方式:addEventListener( ),IE9前不支持此方法,可使用attachEvent( )代替。同一个元素同一个事件可注册多个监听器。
(该特性非标准,尽量不要在生产环境中使用。)
目标对象.addEventListener(type, listener[ , useCapture] )
type:事件类型字符串,如click、mouseover,要加引号,注意不要带on (旧版本addEvent( )方式要加on)
listener:事件处理函数,事件发生时,会调用该函数。
useCapture:可选参数,布尔值,默认为false,表示处于冒泡阶段,为true表示处于捕获阶段。
如: btns[0].addEventListener('click',function(){
alert('victory!');
});
注册事件兼容性处理方法:判断element.addEventListener( )是否为true 以及element.addEvent( )是否为true
- 删除事件(解绑事件):
(1)传统方式:divs[0].οnclick=null;
(2)监听方式:目标对象.removeEventListener( )
divs[0].addEventListener('click',fn); //fn不需要加括号
function fn(){
alert('成功');
divs[1].removeEventListener('click', fn); //旧版本使用detachEvent('onclick', fn)
}
-
事件流:
传播过程就是DOM事件流(捕获阶段—>当前目标阶段—>冒泡阶段)
旧版本的监听方式只能得到冒泡阶段, -
事件对象
(1)event 就是一个事件对象,写到我们监听函数的小括号里,当形参来看;
事件对象只有有了事件才会存在,它是系统自动给我们创建的,不需要我们进行传递参数;
事件对象是我们事件的一系列相关数据的集合,比如判断用户按下了哪一个键。
事件对象可自己命名
事件对象也有兼容性问题 ie678通过window.event,兼容性写法e= e ||window.event;
(2)事件对象常见属性方法
e.target:(标准)返回的是触发事件的对象(即点击的对象),而this指向的是绑定事件的对象
e.srcElement:(非标准 ie6-8)返回的是触发事件的对象
e.type:返回事件类型
e.preventDefault:(标准)阻止默认行为(事件)让链接不跳转,或者让提交按钮不提交
e.returnValue:(非标准)阻止默认行为(事件)
e.stopPropagation:(标准)阻止冒泡
e.cancelBubble:(非标准)阻止冒泡 -
事件委托
(1)原理:不是给每一个子节点单独设置事件监听器,而是将事件监听器设置在父节点上,利用冒泡原理影响设置每个子结点,这样只操作了一次DOM,提高了程序性能。<ul> <li>1</li> <li>2</li> <li>3</li> </ul> <script> var ul= document.querySelector('ul'); ul.addEventListener('click',function(e){ e.target.style.backgroundColor='pink'; }) </script>
-
禁止选中文字(selectstart)和禁止右键菜单(contextmenu):
document.addEventListener( 'selectstart' ,function(e){ e.preventDefault( ); })
- 鼠标事件对象(MouseEvent)
e.clientX 和 e.clientY:鼠标可视区的距离(与滚动无关)
e.pageX 和 e.pageY:鼠标在页面文档的距离
e.screenX 和 e.sreenY:鼠标在电脑屏幕的距离
-
鼠标移动样式
<img src=' images/a.jpg'> <script> var pic=document.querySelector('img'); document.addEventListener('mousemove', function(e){ var x= e.pageX; var y= e.pageY; pic.style.top= y + 'px'; pic.style.left= x + 'px'; }) </script>
-
键盘事件
‘keyup’:某键盘松开时触发
‘keydown’:某键盘按下时触发
‘keypress’:某键盘按下时触发,但不识别功能键(如shift 、ctrl、上下箭头等)
注:三个事件的执行顺序:keydown——keypress——-keyupe.keyCode:键盘事件对象(每个键对应不同的ASCII码值)
注:keyup 和 keydown事件不区分字母大小写,a和A得到的值一样; keypress则区分大小写
- 京东快递单号:
设置文本框元素监听,若文本框为空,盒子的display=‘none’,若文本框输入了内容,在 keyup 触发时,盒子的display=‘block’ 且盒子的innerHTML= this.value 。
除此,失去焦点时隐藏盒子,获得焦点时显示盒子。
(注意是使用keydown、keypress还是keyup)
三、BOM
BOM的顶级对象是 window,包含DOM。
- 它是JS 访问浏览器的一个接口。
- 是一个全局对象。定义在全局作用域的变量、函数都会变成window对象的属性和方法。
-
窗口加载事件:window. load ,页面元素(包括图片样式等)全部加载完毕,才执行处理函数。
(1)window. load传统注册方式只能出现一次,出现多个以后一个为准。
(2)window.addEventListener( ‘load’ ,function(){ }) 则没有限制
(3)window.addEventListener( ‘DOMContentLoaded’ ,function(){ }) 该事件触发时,仅当DOM加载完成(不包括样式、图片、flash等)ie9以上才支持。适合用于图片之类的多的情况。 -
调整窗口大小事件(窗口变化):window.addEventListener( ’ resize ’ ,function(){ })
可以搭配window.innerWidth:屏幕 宽度 -
定时器
(1)var settime= window. setTimeout( 调用函数, [延迟毫秒数] ); 也叫回调函数
间隔时间到了,就去调用这个回调函数,只调用一次就结束。
window在调用中可以省略。如setTimeout( function(){ } , 2000);
调用函数可以直接写函数:setTimeout( callback , 2000)
或者setTimeout('callback()',2000)
–>这个方法不提倡
(2)clearTimeout(settime); 停止计时器
(3)setInterval :每隔这个延迟时间,就去调用这个回调函数,会调用很多次,重复调用(如倒计时、轮播图)
注:记得某些场景下一定要清除定时器 -
this 指向问题
(1)全局作用域或普通函数中 this 指向全局对象 window(注意定时器里面的this指向window)
(2)方法调用中,谁调用this指向谁
(3)构造函数中this指向构造函数的实例 -
同步和异步
js是单线程,同一时间只能做一件事。
JS的执行机制:
(1)同步任务:放在主线程执行栈中执行。
(2)异步任务:通过回调函数实现的。异步任务相关回调函数放在任务队列(消息队列)中。异步任务有三种:
普通事件,如 click、resize;
资源加载,如 load、error;
定时器,包括 setInterval 、setTimeout。
(3)过程:先执行执行栈中的同步任务。异步任务回调函数提交给异步进程处理,满足条件会将其放在任务队列。一旦同步任务执行完毕,系统会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈中开始执行。
由于主线程不断重复获取任务、执行任务,所以这种机制被称为事件循环。 -
location 对象
(1)里面有很多属性,可获取 href(URL)、host(主机域名)、port、pathname(返回路径)、search(返回参数)、hash(#内容 常见于链接 锚点)
(2)location对象方法:
location.assign( ):重定向页面。记录浏览历史,可以实现后退。
location.replace( ):跳转页面。不能记录浏览历史
location.reload( ):刷新页面。(ctrl+F5:强制刷新) -
navigator 对象
navigator.userAgent.match(’ ‘) 可以看是哪种浏览器打开的 -
history 对象
与浏览器历史进行交互(前进或后退)
history.forward();前进
history.back();后退
history.go(1):前进1 , history.go(-1):后退1 -
本地存储 sessionStorage 和 localStorage
- sessionStorage:数据存储在用户浏览器中,刷新页面也不会丢失,容量较大,只能存储字符串,可将对象JSON. stringify( ) 编码后存储。
- 生命周期:关闭浏览器窗口
- 在同一窗口(页面)下数据是共享的
- 以键值对形式存储 sessionStorage.setItem(key, value);
获取数据:sessionStorage.getItem(key);
删除数据:sessionStorage.removeItem(key);
删除所有数据:sessionStorage.clear( );
- localStorage:
- 生命周期永久生效,除非手动删除
- 多个窗口(页面)共享(同一浏览器共享)
- 以键值对形式存储