前端学习总结
09_DOM
DOM
-
什么是DOM
-
Document Object Model
-
专门操作网页内容的API标准
- W3C
-
为什么
- 统一不同浏览器操作网页内容的API
-
用DOM操作网页内容,几乎所有浏览器100%兼容
-
-
DOM Tree
-
网页中一切内容都是节点(Node)对象
-
一切节点对象都存储在一个树型结构中
-
根节点
- document
-
节点对象三大属性
-
nodeType
-
节点的类型
- 返回 Number 类型数据
-
何时
- 判断节点类型
-
document 9 elem 1 attr 2 text 3
-
问题:
- 无法进一步判断元素的名称
-
解决
-
-
nodeName
-
表示节点的名称,为节点的只读属性
-
何时
- 只要进一步判断元素的名称
-
document #document elem 全大写标签名 attr 属性名 text #text
-
-
nodeValue
- 表示节点的值,返回 String 类型数据
- document null elem null attr 属性值 text 文本内容
-
-
-
DOM操作
-
构建DOM树
-
查找触发事件的元素
-
绑定事件
-
查找要操作的元素
- 修改
- 增加
- 删除
-
事件处理函数中的this
- 自动获得触发事件的当前元素
-
-
-
-
-
查找
-
不需要查找可直接获得的节点
-
document
-
document.documentElement
- html
-
document.head
-
document.body
-
-
按节点间关系查找
-
何时
- 已经获得一个节点,要找周围的相关节点时
-
节点树
-
包含所有网页内容(节点)的树结构
-
2大类关系
-
-
父子
-
elem.parentNode
- 最靠谱
-
elem.childNodes
- 直接子节点
-
elem.firstChild
-
elem.lastChild
-
-
-
兄弟
- elem.previousSibling
- elem.nextSibling
-
-
-
优: 完整
-
问题:
- 受看不见的空字符的干扰
-
解决
-
-
元素树
-
仅包含元素节点的树结构
- 不是一棵新树,仅是节点树的子集
-
何时
- 只关心元素,不关心文本时
-
2大类关系
-
-
父子
-
elem.parentElement
- 没有node结尾
-
elem.children
- IE8+
-
elem.firstElementChild
-
elem.lastElementChild
-
-
-
兄弟
- elem.previousElementSibling
- elem.nextElementSibling
-
-
-
优: 不受看不见的空字符的干扰
-
缺: 不包含一切文本节点
- 可用.innerHTML
-
兼容性问题: IE9+
-
-
childNodes和children
-
都返回动态集合(live collection)
-
不实际存储数据,每次访问集合,都重新查找DOM树
-
优:
- 首次查找返回速度快
-
缺:
- 反复访问集合,会导致反复查找DOM树
-
遍历
- for(var i=0,len=children.length;i<len;i++)
-
-
-
-
递归遍历
-
何时
- 只要遍历一个父节点下所有后代节点
-
如何
- //Step1: 仅遍历parent的直接子节点 function getChildren1(parent){ console.log(parent.nodeType!=3?parent.nodeName:parent.nodeValue); var children=parent.childNodes; for(var i=0,len=children.length;i<len;i++){ //Step2: 为每个子节点调用和父节点完全相同的函数 arguments.callee(children[i]); } }
-
深度优先遍历
- 当同时有子节点和兄弟节点时,优先遍历子节点。所有子节点遍历完,才遍历兄弟节点
-
问题: 递归的效率是极低
-
解决: 可用循环代替递归
- function getChilddren2(parent){ //Step1: 创建迭代器对象 var iterator=document.createNodeIterator( parent, NodeFilter.SHOW_ALL , null, false .SHOW_ELEMENT ); var node; while((node=iterator.nextNode())!=null){ //node获得当前正在遍历的节点 console.log(node.nodeType!=3?node.nodeName:node.nodeValue); } }
-
问题:
- 只能遍历所有,如需筛选,得自己写判断
-
解决:
- 如何按条件查询
-
-
按HTML查找
-
按id
- var elem=document.getElementById("id")
- 强调: 只能用在document上
-
按标签名
-
var elems=parent.getElementsByTagName("标签名")
-
强调:
- 可用在任意父节点上
- 返回动态集合
- 不仅查找直接子节点,且查找所有后代节点
-
-
按name
-
var elems=document.getElementsByName("name")
-
强调:
- 只能在document上调用
-
-
按class
-
var elems=parent.getElementsByClassName("class")
-
强调:
-
可用在任意父节点上
-
返回动态集合
-
不仅查找直接子节点,且查找所有后代节点
-
只要class中包含指定的类名,就选择
-
兼容性问题
- IE9+
-
-
-
问题:
- 一次只能用一个条件查找,如果查找条件复杂时,会步骤繁琐
-
-
按选择器查找
-
Selector API
-
只找一个
- var elem=parent.querySelector("selector")
-
找所有符合条件的多个
- var elems=parent.querySelectorAll("selector")
-
强调:
- 可在任意父元素上调用
- 返回非动态集合
- 受制于浏览器对选择器的兼容性
-
-
按HTML vs 按选择器
-
-
返回值:
-
按HTML
- 返回动态集合
-
selector API
-
返回非动态集合
- 直接存储所有数据,反复访问集合,不需要反复查找DOM树
-
-
-
-
首次查询效率
-
按HTML更高
- 仅返回需要的内容,不需要准备完整数据
-
selector API低
- 第一次要返回完整数据
-
-
-
易用性:
- 按HTML繁琐
- selector API简单
-
-
何时
- 如果只凭一个条件即可获得想要的元素时,首选按HTML查找
- 如果需要多级复杂条件查找才能获得想要的元素时,用selector API
-
-
-
修改
-
内容
-
.innerHTML
- 获取或设置开始标签到结束标签之间的html代码片段
-
.textContent
-
获取或设置开始标签到结束标签之间的纯文本内容
- 去掉所有标签
- 翻译转义字符为正文
-
IE8:
- .innerText
-
-
表单元素的内容
- .value
-
-
属性
-
标准属性
-
核心DOM
-
操作一切结构化文档的通用API
- 即可操作HTML,又可操作XML
-
获取
-
了解
- var attrNode=elem.attributes[i/属性名] .getAttributeNode("属性名")
- var value=attrNode.value
-
var value=elem.getAttribute("属性名")
-
-
修改
-
elem.setAttribute("属性名",属性值)
- 如果属性不存在,也可set
-
-
判断是否包含
- var bool=elem.hasAttribute("属性名")
-
移除
-
elem.removeAttribute("属性名")
- 只移除开始标签中的attribute,不删除内存中对象的property
-
-
特点
-
优
- 万能
-
缺
- 繁琐
-
-
解决
-
-
HTML DOM
-
专门操作HTML文档的简化版API
- 只对部分常用API进行简化
-
如何
-
elem.属性名
- 所有HTML标准属性都被封装在HTML DOM对象中,可直接用.访问。用法普通对象的属性完全一样
-
-
特点:
-
优
- 简单
-
缺
-
不是万能
- 需要核心DOM的补充
-
-
-
-
-
状态属性
-
disabled, checked, selected
-
问题:
- 核心DOM不能操作:
-
解决:
-
HTML DOM
-
elem.状态
- .checked .selected .disabled
-
-
-
-
扩展(自定义)属性
-
何时
- 代替id,元素,class选择器,选择多个元素
-
HTML DOM无法访问扩展属性
-
核心DOM
-
HTML5
-
定义:
- data-属性名="值"
-
访问:
- elem.dataset.属性名
-
-
查找
-
CSS属性选择器
- [data-属性名=值]
-
-
-
-
样式
-
内联样式:
-
elem.style.css属性名
-
强调:
- css属性名要去横线变驼峰
-
何时
-
专门用于修改内联样式
- 不影响其他元素的样式
- 优先级最高
-
-
问题:
-
获取时,只能获得内联样式
- 无法访问从样式表层叠或继承来的完整样式
-
-
解决
-
获取一个元素计算后的完整样式:
-
计算后的样式:
-
最终应用到元素上的完整样式
- 包括所有内联,内部,外部样式
- 将相对单位的值,计算为绝对单位
-
-
何时
- 只要获取样式,就要获取计算后的样式
-
var style=getComputedStyle(elem对象)
-
var value=style.样式属性名
-
强调:
- 通过getComputedStyle获得的样式对象是只读
-
-
-
-
内部/外部样式表
-
修改样式表中的样式
-
var sheet=document.styleSheets[i]
-
var rule=sheet.cssRules[i]
- 如果获得的是keyframes,就需要继续找子rule
-
rule.style.样式属性=值
-
-
-
最好的修改样式的做法
- 修改class属性,批量应用样式
-
-
-
添加和删除
-
3步
-
创建新元素对象
- var elem=document.createElement("标签名")
-
设置关键属性
-
将元素添加到DOM树
- parent.appendChild(child)
- parent.insertBefore(child,oldChild)
- parent.replaceChild(child,oldChild)
-
-
问题:
- 每操作一次DOM树,都会导致重新layout
-
解决
-
优化
-
尽量少的操作DOM树
-
如果同时添加父元素和子元素
- 先在内存中将子元素添加到父元素
- 再将父元素一次性添加到DOM树上
-
如果同时添加多个平级子元素
-
使用文档片段
-
什么是
- 内存中临时存储多个子元素的虚拟父元素
-
3步:
-
创建文档片段
- var frag=document.createDocumentFragment();
-
将子元素临时添加到frag中
- frag.appendChild(child)
-
将frag添加到DOM树
-
parent.appendChild(frag)
-
强调:
- frag不会成为页面元素,添加子元素后,frag自动释放
-
-
-
-
-
-
-
-
删除
- parent.removeChild(child)
-
-
HTML DOM常用对象
-
Image
- var img=new Image();
-
Select/Option
-
属性
-
value
-
当前选中项的value
- 如果选中项没有value,则使用内容
-
-
selectedIndex
- 当前选中项的下标
-
options
- 获得当前select下所有option的集合
-
length
-
相当于.options.length
-
获得option的个数
-
清空option
- .length=0
-
-
-
-
事件
-
onchange
- 当选中项发生改变时
-
-
方法
-
sel.add(option)
- 不支持文档片段
-
sel.remove(i)
-
-
Option
-
创建
- var opt=new Option(text,value)
-
属性
- text,value,index
-
-
-
Table/...
-
创建
- var thead=.createTHead()
- var tbody=.createTBody()
- var tfoot=.createTFoot()
-
删除
- .deleteTHead()
- .deleteTFoot()
-
获取
- .tHead
- .tBodies[i]
- .tFoot
-
行分组
-
创建
-
var tr=.insertRow(i)
-
固定套路
-
- 末尾追加一行: insertRow()
-
- 开头插入一行: insertRow(0)
-
-
-
-
删除
-
.deleteRow(i)
-
问题
- i无法自动获得
-
解决
-
首选
- table.deleteRow(tr.rowIndex)
-
-
-
-
获取
- .rows
-
-
tr
-
创建
- var td=.insertCell(i)
-
删除
- .deleteCell(i)
-
获取
- .cells
-
-
删除行
-
行分组.deleteRow(i)
- i是相对于当前行分组内的位置
-
table.deleteRow(tr.rowIndex)
- rowIndex是相对于整个表中的位置
-
-
-
Form
-
获取:
- var form=document.forms[i/id]
-
属性:
-
.elements
-
获得所有表单元素的集合
- input textarea select button
-
-
.length
-
.elements.length
- 获得所有表单元素的个数
-
-
-
方法:
-
form.submit()
- 代替submit按钮,在程序中手动提交表单
-
-
Element
-
获得表单中的元素
-
获得任意表单元素:
- form.elements[i/id/name]
-
如果表单元素有name属性
- form.name
-
-
方法
- .focus()
- .blur()
-
-
事件
-
onsubmit
- 在最终提交表单之前触发
-
-
-
BOM
-
window
-
2个角色
-
- 代替global充当全局作用域对象
-
- 封装BOM和DOM API
-
-
打开和关闭窗口
-
打开
-
/window./open("url","name")
-
name
-
自定义名称
- 在新窗口打开,只能打开一个
-
_blank
-
不指定窗口名,每次都让浏览器生成随机不重复的窗口名
- 在新窗口打开,可打开多个
-
-
_self
-
用当前窗口自己的name,打开新连接
-
新窗口会替换当前窗口
- 在当前窗口打开,可后退
-
-
-
-
-
关闭
- /window./close()
-
-
窗口大小
-
窗口大小
-
属性
-
完整大小:
- .outerWidth
- .outerHeight
-
文档显示区大小
- .innerWidth
- .innerHeight
-
-
-
-
定时器
-
周期性定时器
-
让程序每隔一段时间间隔,反复执行一项任务
-
3件事
-
-
任务函数
- function task(){...}
-
-
-
启动定时器
- timer=setInterval(task, interval)
-
-
-
停止定时器
- clearInterval(timer); timer=null
-
-
-
停止定时器
-
- 让用户手动停止
-
-
让定时器自动停止
- 在任务函数中判断临界值,一旦达到临界值,就自动调用clearInterval
-
-
-
-
一次性定时器
-
让程序先等待一段时间后,自动执行一次任务
- 执行后,自动停止
-
3件事
-
-
任务函数
- function task(){...}
-
-
-
启动定时器
- timer=setTimeout(task, wait)
-
-
-
停止定时器
- clearTimeout(timer); timer=null
-
-
-
-
定时器原理
-
定时器中的回调函数必须在主程序最后一句话执行完才能开始执行
-
回调函数中的this->window
-
解决
- 启动定时器时,用bind为任务函数永久绑定this
-
-
-
-
history
-
封装当前窗口打开后,成功访问过的url的历史记录栈
-
history.go(n)
-
history.go(1)
-
history.go(-1)
- history.go(-2)
-
history.go(0)
-
-
-
location
-
封装当前窗口正在打开的url的对象
-
属性
-
href
-
protocol
-
host
- hostname
- port
-
pathname
-
hash
-
search
- 将search转为对象
-
-
方法
-
在当前窗口打开,可后退
-
location.assign("新url")
-
location.href=“新url”
- location=“新url”
-
-
-
在当前窗口打开,禁止后退
-
location.replace("新url")
- 用新url代替history中当前url
-
-
刷新
-
普通
- 优先从浏览器缓存中获取文件
- location=url
- history.go(0)
- F5
- location.reload(/false/)
-
强制
-
location.reload(true)
-
参数force
- 跳过浏览器缓存,强制从服务器获取文件
-
-
-
-
-
-
screen
-
完整大小:
-
screen.width/height
-
鄙视
-
鉴别设备类型
-
lg
-
=1200
-
-
PC
-
md
-
=992
-
-
-
Pad
-
sm
-
=768
-
-
-
Phone
-
xs
- <768
-
-
-
-
-
去掉任务栏之后剩余的可用大小
- screen.availWidth/availHeight
-
-
navigator
-
封装浏览器配置信息的对象
-
包括
-
cookieEnabled
- 判断浏览器是否启用cookie
- bool
-
plugins
-
封装所有插件信息的集合
-
如何判断是否安装了插件
- navigator.plugins[“插件名”]!==undefined
-
-
userAgent
- 包含浏览器名称,版本号,内核的字符串
-
-
-
document
-
event
-
绑定
-
2种
-
-
在html中
-
html
- <any on事件名="函数(this)"
-
js
- function 函数(any){...}
-
问题:
-
不符合内容与行为分离的要求
- 不便于维护
-
-
-
-
在js中动态绑定
-
-
一个事件仅绑定一个处理函数
-
elem.on事件名=function(){ //this->elem }
-
问题:
-
- 一个事件只能绑定一个处理函数
-
-
不能被remove移除掉
-
只能onXXX=null
- 只能移除由onXXX绑定的事件处理函数
- 无法移除addEventListener绑定的事件处理函数
-
-
-
-
-
一个事件可绑定多个处理函数
-
elem.addEventListener("事件名",fn);
-
elem.removeEventListener("事件名",fn)
-
强调:
- 如果一个处理函数可能被移除,在绑定时不能使用匿名函数,必须使用有名的函数
-
-
-
-
-
-
事件模型
-
DOM
-
3个阶段
-
-
捕获
-
由外向内, 记录各级父元素绑定的事件处理函数
- 只记录,不执行
-
-
-
目标触发
- 优先触发目标元素上的事件处理函数
-
-
-
冒泡
- 由内向外, 反向依次触发捕获阶段记录的事件处理函数
-
-
-
-
IE8
-
2个阶段
- 没有捕获
-
-
-
事件对象
-
什么是
- 事件发生时自动创建
- 封装事件信息的
- 并提供操作事件的API的对象
-
获取
- 事件对象默认作为处理函数的第一个参数传入
-
操作
-
取消冒泡/停止蔓延
- function(e){ e. stopPropagation(); }
-
利用冒泡
-
问题
- 浏览器触发事件,采用的是遍历所有事件监听对象的方式
- 如果事件监听越多,遍历时间越长,响应事件就越慢
-
优化
- 尽量少的添加事件监听
-
如何
-
如果多个平级子元素绑定相同的事件监听,则只需在父元素绑定一次,所有子元素共用
-
2个难题:
-
-
如何获得目标元素
-
错误
-
this
- 父元素
-
-
正确
-
e.target
- 不随冒泡而改变
-
-
-
-
如何筛选目标元素
- 元素名nodeName
- 选择器
-
-
-
-
-
取消事件/阻止默认行为
-
e.preventDefault()
-
何时
- 阻止<a href="#xxx" 修改url
- 在表单的onsubmit事件结尾阻止表单提交
- 用H5拖拽API,需要先禁用浏览器默认的拖拽行为
-
-
事件坐标
-
相对于屏幕左上角
- e.screenX/screenY
-
相对于文档显示区左上角
- e.clientX/clientY
-
相对于触发事件元素的左上角
- e.offsetX/offsetY
-
-
-
-
页面滚动
-
事件
- window.onscroll
-
获得页面滚动过的高度
- document.body.scrollTop
- document.documentElement.scrollTop
-
方法
- window.scrollBy(left的增量,top的增量)
- window.scrollTo(left,top)
-
-
-
10_JQUERY
jQuery
-
什么是
- 第三方的极简化的DOM操作函数库
-
为什么
-
-
DOM操作的终极简化
-
核心DOM: 万能, 但繁琐
-
HTML DOM: 简单,但不是万能
-
jQuery: 对DOM操作的终极简化
-
-
DOM操作
- 增,删,改,查
-
-
- 事件
-
- 动画效果
-
- Ajax
-
-
-
-
屏蔽了浏览器兼容性问题
- 凡是jQuery允许使用的,都屏蔽了兼容性问题
-
-
-
如何:
-
版本
-
1.x
-
兼容旧浏览器
-
.js
-
未压缩过的代码
-
可读性好
- 学习/开发用
-
大
-
-
-
.min.js
-
压缩版本
-
小
-
毫无可读性
- 删除注释
- 去掉换行和空字符
- 极简化变量名
-
-
-
-
2.x 和 3.x
- 不再兼容旧浏览器
- 小
-
-
先引入jquery.js, 再编写自定义脚本
-
2种方法
-
- 将jquery.js下载到服务器本地,在script中使用服务器路径
-
-
使用CDN网络上共享的jquery.js
-
内容分发网络
- 可根据客户端到服务器的网络状况和访问量智能选择最优的服务器下载资源
-
生产环境中用的最多
-
-
-
-
原理
-
向全局添加了一种jQuery新类型
-
jQuery构造/工厂函数
-
创建jQuery类型的子对象
-
- 查找,并封装jQuery对象
-
- 将DOM元素封装为jQuery对象
-
-
其实可简写为:$("selector")
- window.jQuery=window.$=jQuery
-
-
jQuery.fn原型对象
- 是所有jQuery对象的父对象
- 封装了所有简化版API
-
-
-
jQuery对象
-
封装DOM对象的类数组对象,并提供对DOM对象执行操作的简化版API
-
为什么
-
DOM对象不包含,也不能使用jQuery简化版API
- 因为不是jQuery类型的子对象
-
只有将DOM对象封装进jQuery对象后,才能使用jQuery的简化版API
-
-
如何
-
2种
-
-
用$(“selector”)直接查找
-
返回包含找到的DOM对象的集合
- jQuery对象
-
-
-
如果已经获得一个DOM对象
-
先用$(DOM对象)封装DOM对象为jQuery对象
-
比如:
-
this, e.target
-
DOM对象
-
(e.target)
- jQuery对象
-
-
-
-
-
-
-
强调:
-
-
尽量减少使用$(...)的次数
- 每$(...)一次就新创建一个jQuery对象
-
-
-
尽量减少查找的次数
- 所有查找都是遍历,反复查找,效率低
-
-
解决
-
- 如果一个jQuery结果对象可能被反复使用,就临时保存在变量中
-
- 使用链式操作
-
-
-
-
-
API通用特点
-
-
自带遍历效果
- 对$("...")结果对象执行的操作,相当于自动应用到结果中每个元素上
-
-
-
API两用
- 没给新值,就读取属性值;给了新值,就是修改属性值
-
-
-
每个API都再次返回结果对象本身
-
$("...")之后可使用链式操作反复调动多个API
-
为什么链式操作
-
-
避免重复创建jq对象
- 每次调用$都会创建新的jq对象
-
-
- 减少查询次数
-
- 节省变量的使用
-
-
-
-
查找
-
按选择器查找
-
基本选择器
- 同CSS
- #id .class element * 选择器1,选择器2
-
层次选择器
- 同CSS
- 父级 后代 > + ~
-
过滤选择器
-
子元素过滤
-
同CSS
-
在父元素内编号
-
:first-child
-
:last-child
-
:nth-child(i/odd/even/2n/2n+1)
-
强调:
- 下标从1开始,且仅限于当前父元素内
-
-
:only-child
-
-
基本过滤(位置过滤)
-
先将符合条件的所有元素保存在一个集合中再统一编号
- 和元素在其父元素下的位置无关
-
:first/last
- 选择结果集合中第一个/最后一个元素
-
:even/odd
-
选择结果集合中下标为偶数或奇数的元素
-
强调:
- 下标从0开始
-
-
:eq/gt/lt(i)
- 选择结果集合中下标等于/大于/小于i位置的元素
-
-
否定选择器:
- :not(任意selector)
-
属性过滤
-
同CSS
-
[属性名]
-
[属性名=值]
-
[属性名!=值]
- :not([属性名=值])
-
[属性名^=开头]
-
[属性名$=结尾]
-
[属性名*=值]
-
selector1selector2...
- 而且
-
-
内容过滤
-
:contains(文本)
- 按元素的内容文本
-
:has('selector')
- 按子元素的特征来选择父元素
-
:empty
-
:parent
- :not(:empty)
-
-
可见性过滤
-
:visible
-
:hidden
- display:none
- input type="hidden"
-
-
表单过滤
-
:input
-
input, select, textarea, button
-
如果只想查找一种表单元素
- 可用元素选择器
-
-
:type属性
- :text :password :checkbox :radio :button :submit :reset :image :file :hidden
-
-
状态过滤
- 同CSS
- :disabled :enabled :checked :selected
- 四大状态属性
- Disabled:关闭
- Enabled:启用
-
-
-
节点间关系
-
父子关系
-
$("...").parent()
- 获得当前元素的父元素
-
$("...").children(["selector"])
- 仅找直接子元素中符合selector条件的
-
$("...").find("selector")
- 在所有后代中查找符合selector条件的
-
$(...).children().first()
- :first-child
-
$(...).children().last()
- :last-child
-
-
兄弟关系
-
$("...").next/prev(["selector"])
-
紧邻的前一个或后一个兄弟元素
- 必须紧邻
-
-
$("...").nextAll/prevAll(["selector"])
- 之后/之前所有符合条件的兄弟
-
$("...").siblings(["selector"])
- 除自己之外的所有兄弟
-
-
-
-
修改
-
内容
-
html内容
-
$("...").html(["html代码片段"])
- 两用
-
-
文本内容
-
$("...").text([“文本内容”])
- 两用
-
-
表单元素内容
-
$("...").val(["值"])
- 两用
-
-
清除内容
- $("...").empty()
-
-
属性
-
访问标准属性
-
获取
- var value=$("...").attr("属性名")
-
修改
-
只修改一个属性
- $("...").attr("属性名",值)
-
同时修改多个属性
- $("...").attr({ 属性名:值, 属性名:值, })
-
-
-
访问三大状态
-
包括: disabled checked selected
-
$("...").prop(...)
- 用法同attr()
-
-
移除属性
- $("...").removeAttr/removeProp("属性名")
-
自定义扩展属性
- $(...).data()
-
-
样式
-
直接修改css属性
-
获取css样式(计算后的样式)
-
$("...").css("css属性名")
- 相当于getComputedStyle
-
-
修改css样式
-
只修改一个css样式:
-
$("...").css("css属性名",值)
- 相当于elem.style
-
为每个元素的css属性动态生成不同的值
-
$("...").css("css属性名", function(i){return 值})
- i会依次获得每个元素的下标
- 返回值会被依次设置到每个元素的指定css属性
-
-
-
同时修改多个css样式:
- $("...").css({ css属性名:值, css属性名:值, ... })
-
-
强调:
- 所有CSS属性名都要去横线变驼峰
- 纯数字的属性值不必加单位
-
-
通过修改class批量修改样式
-
判断是否包含指定class
- $("...").hasClass("类名")
-
添加class
- $("...").addClass("类名")
-
移除class
- $("...").removeClass("类名")
-
切换class
-
$("...").toggleClass("类名")
- if(.hasClass(...)) .removeClass(...) else .addClass(...)
-
-
-
-
-
添加,删除,替换和复制
-
添加
-
-
创建新元素
- var ("html代码片段")
-
-
-
将新元素添加到DOM树
-
结尾/开头插入
- newElem)
-
在某个child前后插入
- newElem)
-
-
简写:
- $(parent).append("html代码片段")
-
-
删除
- $("...").remove()
-
替换
-
$("现有元素").replaceWith("新元素html代码")
- 用右替换左
-
$("新元素html代码").replaceAll("现有元素")
- 用左替换右
-
-
克隆
-
$("...").clone()
-
浅克隆
- 仅复制属性,不复制行为
-
-
$("...").clone(true)
-
深克隆
- 即复制属性,又复制行为
-
-
-
-
事件
-
鄙视
-
jQuery中共有几种事件绑定方式
-
.bind/unbind("事件名",fn)
- .unbind('事件名',fn)
- .unbind('事件名')
- .unbind()
-
.one("事件名",fn)
-
废弃
- $("selector").live/die("事件名",fn)
-
利用冒泡
-
$("parent").delegate("selector","事件名",fn)
-
简化了利用冒泡中:
-
- 用参数selector代替了if判断
-
- this->e.target
-
-
-
$(...).undelegate(...)
-
鄙视题:
-
bind vs delegate
-
-
bind直接帮在触发事件的目标元素(子元素)上
- delegate绑定在触发事件的元素的父元素上
-
-
-
事件监听个数不一样
- bind是每个子元素都添加事件监听
- delegate只为父元素添加一个事件监听
-
-
-
动态添加的元素
- bind绑定时,要求触发事件的元素必须已经存在
- delegate可为父元素下动态添加的子元素提供事件监听
-
-
-
-
-
简化
-
仅为一个元素绑定事件
-
$("...").on("事件名",fn)
- bind
-
-
利用冒泡/事件委托
-
$("parent").on("事件名","selector",fn)
- delegate
-
-
$(...).off(...)
- 同unbind/undelegate
-
-
终极简化版
- $("...").事件名(function(e){...})
-
-
this
-
普通事件绑定
- this->触发事件的当前元素
-
利用冒泡
- this->e.target
-
DOM对象
-
$(this)
- jq对象
-
-
-
模拟触发
-
$("...").trigger("事件名")
-
模拟触发所有选中元素的指定事件
-
可简写为
- $(...).事件名()
-
-
-
页面加载后触发
-
只要DOM内容加载完成就触发
-
DOMContentLoaded
- 只要等待HTML , js
-
$(document).ready(fn)
-
domcontentloaded
- 早
-
$().ready(fn)
- $(fn)
-
-
-
整个页面加载完才执行
-
等待HTML,CSS,JS,图片...
-
window.onload=function(){...}
- 晚
-
-
其实
- 只要将script代码放在body结尾就可以实现DOM加载后就执行
-
-
鼠标事件
-
mouseover vs mouseenter
-
mouseover
- 进出子元素,同样会触发父元素的mouseover
-
mouseenter
- 进出子元素,不会再触发父元素的mouseenter
-
mouseout vs mouseleave
-
-
.hover
-
等效于同时绑定两个事件: mouseenter和mouseleave
-
如何
-
.hover(fn_enter, fn_leave)
-
如果fn_enter和fn_leave的行为可统一成一样的
-
简写
-
.hover(fn)
- fn即响应enter,又响应leave
-
-
-
-
-
-
向事件处理函数中传入参数
-
$(...).on("事件名",data,fn)
-
其中data: {属性名: 值, ...}
-
读取
-
fn中
- e.data.属性名...
-
-
-
-
-
动画效果
-
简单:
-
显示隐藏
-
$("...").show/hide/toggle(speed,easing,callback)
-
如果没有参数
- 默认不带动画,用display控制瞬间显示和隐藏
-
-
上下滑动
- $("...").slideUp/slideDown/slideToggle(speed,easing,callback)
-
淡入淡出
- $("...").fadeIn/fadeOut/fadeToggle(speed,easing,callback)
-
问题:
- 不便于维护
- 使用程序的定时器实现,效率比css动画低
-
解决
-
其实都应该用
- class + transition
-
-
-
动画结束后执行
- 每个动画函数的最后一个参数都是一个回调函数,专门在动画结束后自动执行
- 回调函数中的this->指正在执行动画的DOM对象
-
万能
-
$("...").animate({ css属性: 目标值, css属性: 目标值, ... },speed,easing,callback)
- 多个css属性并发改变
-
问题
- 仅对单数值的属性有效
- 对颜色,字体,C3的变换...无效
-
排队和并发
-
并发
-
- 放在一个animate中的多个css属性
-
- 对不同元素同时执行animate时
-
-
排队
-
对一个元素先后调用animate
-
$("...").animate().animate()...
- 会创建动画队列,依次排队执行
-
-
-
-
停止:
-
$(...).stop()
-
仅停止当前正在执行的动画
- 队列中后续动画依然执行
-
-
$("...").stop(true)
-
停止当前正在执行的动画
- 清空动画队列
-
-
-
延迟执行
-
.delay(ms)
- 无法中途停止
-
setTimeout
- 中途停止
-
-
选择器:
-
:animated
- 匹配所有正在执行动画效果的元素
-
-
-
问题:
- 底层依然是定时器动画,效率低
-
解决:
- animate.css
-
-
类数组对象操作
-
$(...).size()
- .length
-
$(...).get(i)
-
[i]
- 取出DOM对象
-
-
$(...).each((i,elem)=>{ ... })
- forEach
-
$(...).index()
-
indexOf
-
用法
-
$(...).index()
- 自动仅在当前元素的父元素内查找自己的位置
-
)
- 在左边的结果集合中,查找右边的东西的位置
-
$(...).index(selector)
- 在右边的结果集合中,查找左边的东西的位置
-
-
-
-
封装自定义插件
-
添加jQuery对象函数
-
如果jQuery的简化版API不够用,可自定义API
-
如何:
-
-
判断是否引入jQuery
- if(typeof jQuery!="function") 就报错
-
-
-
向jQuery.fn原型对象中添加自定义函数
- jQuery.fn.自定义API=function(){ this->将来调用该API的jQuery对象,不用再用$()封装 }
-
-
-
-
封装自定义Widget
-
封装
-
前提:
- 使用html, css, js, jquery成功实现过部件的完整效果
-
Step1:
-
css拷贝到部件的css文件中
- 尽量不使用元素选择器和id选择器
- 应该用class和自定义扩展属性代替
-
-
Step2:
-
添加js文件
-
-
判断是否提前加载了jQuery
- if(typeof(window.jQuery) !=="function") throw new Error(...)
-
-
-
生成插件
-
-
jQueryUI方式: 侵入方式
-
为jQuery.fn添加实例方法
- 向当前元素及其子元素上侵入class或data-*扩展属性
- 为data-*的元素绑定事件
-
问题
- 封装太死,不便于维护
-
-
-
bootstrap方式: 手动添加class和data-*
- 在页面加载时,自动查找data-*的元素,绑定事件即可
-
-
-
-
-
-
使用
-
- 引入部件css
-
- 按部件要求编写HTML内容
-
-
引入jquery
- 再引入部件js
-
-
仅jQueryUI方式:
- 查找父元素,调用部件函数
-
-
-