笔试题
HTML:超文本标记语言,专门编写网页内容的语言
XHTML:严格的HTML标准
DHTML:动态HTML技术,是HTML+CSS+JS的统称
XML:可扩展的编辑语言,标签名和属性名可自定义--!---json
<student>
<name id="fbb"></name>
<math></math>
</student>
JSON:javaScritpt Object Notation
{"name":范冰冰,"math":91}
BOM和DOM
window对象:2个角色
1、代替了ES标准中的GLobal,充当全局对象
2、封装当前浏览器窗口的功能和属性--BOM
BOM:Browser Object Model--专门操作浏览器窗口的API
包括:浏览器窗口的属性和功能
缺点:没标准---兼容性差
DOM:Document Object Model--专门操作网页内容的APi
包括:html网页中编写的一切内容和属性
优点:有国际标准,所有浏览器几乎100%兼容
Document其实不仅指网页,而是指一切自描述的结构化文档
DOM API 2大类
1、核心DOM:通用API,既可以操作HTML文档,也可以操作XML文档
优点:可以对文档内容做任何操作
缺点:API操作繁琐
2、HTML DOM:DOM Level2,提供了专门操作网页内容的简化版API
但仅对复杂HTML元素进行简化
优点:API简单
缺点:不能完成所有操作,都需要和谐DOM补充
开发:有限使用HTML DOM,再用核心DOM API补充
DOM tree
网页的加载过程:
Browser Server
1、浏览器send request:=====>查找请求的.html页面
2、创建Document对象<----.html<----返回response
3、读取HTml内容在 document对象下搭建搭建DOM Tree
JQuery
4、请求外部css文件:-->查找请求的.css文件
<--.css<--返回response
5、将样式设置到DOM Tree
的节点对象上
*同时,计算对象间的大小和位置:layout(reflow)*
生产Render Tree---加载完样式后的树
6、浏览器绘制页面
window.onload
根节点:document对象
Node类型:所有节点对象的父类型
三大通用属性:
1、nodeType:当前节点的类型-返回的是数字
DOCUMENT_NODE:9;
ELEMENT_NODE:1;
ATTRIBUTE_NODE:2;
TEXT_NODE:3;
何时使用:判断获得的节点的类型时
2、nodeName:节点名称
document:"#document"
ELEMENT:"全大写标签名"
ATTRIBUTE:"属性名"
TEXT:"#text"
何时使用:判断获得的元素节点的标签名时
if(obj.nodeName=="INPUT")
3、nodeValue:节点值--对元素节点无效
ATTRIBUTE:"属性值"
TEXT:"文本内容"
DOM Tree 节点间关系
1、父子关系:parentNode childNodes firstChild lastChild
2、兄弟关系:previousSibling nextSibling
问题1:除了parentNode外,其余都会受到看不见的空字符的影响
空字符也是文本节点
问题2:childNodes:返回NodeList类型的类数组对象
包含了父节点下的所有直接子节点对象
***动态集合***仅包含节点对象的引用,不包含实际属性值!
每次访问结合的属性时,都要重新查询DOM树
遍历childNodes:
效率低:for(var i=0;i<obj.childNodes.length;i++)
后果:每循环一次,都要重新查询length的个数
解决:for循环的第一部分缓存length的值
for(var i=0,len=obj.childNodes.length;i<len;i++)
***递归遍历节点树
递归调用:函数内部又调用了自己
何时使用递归:遍历不确定层级深度的上下级机构时
原理:在函数内部,调用任何函数,都会为新的函数调用创建
新的EC,可实现一个函数,反复执行多项任务。
深度优先遍历:优先遍历下级节点
arguments.callee引用的是当前调用的函数对象
何时使用:递归内部必须用callee属性调用当前函数
不能直接用函数名。
节点树:由所有节点组成的树结构
元素树:仅由元素节点组成的树结构
节点树 元素树
父节点: parentNode parentElementNode
子节点集合: childNodes children
第一个孩子: firstChild firstElementChild
最后一个孩子: lastChild lastElementChild
前一个兄弟: previousSibling previousElementSibling
后一个兄弟: nextSibling nextElementSlibling
children :IE8+
其余:IE9+
遍历API:2个
NodeIterator:安装深度优先的原则向上或向下遍历节点
每次只引用一个节点对象
如何使用:2步
1、创建迭代器对象:
var iterator =document.createNodeIterator(
开始的节点对象,
遍历节点的类型//NodeFilter.SHOW_ALL
//NodeFilter.SHOW_ELEMENT
null,false
}
2、跳到下一个节点对象:var next=iterator.nextNode();
如果没有下一个节点,就返回null
退一步,返回上一个节点:
var pre =iterator.previousNode();
获得正在站的节点:iterator.refereceNode
TreeWalker:自有遍历:保证基本深度优先功能的基础上
添加了向任意方向跳转的额外方法
如何使用:和NodeIterator基本功能完全一样
额外方法:parentNode(),firstChild(),lastChild()
nextSibling(),previousSibling()
查找:2大类
1、getXXX:4个
按id查找1个元素对象
var elem=document.getElementById("id值")
按标签名查找多个子元素对象
var nodeList=parent.getElementsByTagName("标签名")
何时使用:获取某个父对象下指定子元素时使用
屏蔽空文本的干扰
按name属性查找多个子元素对象
var nodeList=parent.getElementsByName("name属性名")
按类名查找多个子元素对象:HTML5新增 IE9+
var nodeList=parent.getElemntsByClassName("样式类名");
何时使用:只查找一次时
当前元素.innerHTML:获得当前对象的值
2、Selector API 用CSS选择器选择元素---Jquery的核心
2个:
如果使用document调用Selector API,选择器作用范围是整个页面
如果使用父元素对象调用selector API,选择器作用范围是父元素
下所有子节点
仅选择第一个符合条件的元素:
var elem=parent.querySelector("选择器");
选择所要符合条件的元素
var elems=parent.querySelectorAll("选择器")
强调:elems非动态集合:包含了完整Dom对象和属性
何时使用:通过多级查找才能获得想要的元素时
笔试题
getXXX vs Selector API
返回值:getXXX返回动态集合
Selector API返回非动态集合
效率:getXXX效率高
Selector API效率低
修改元素的内容:3个
1、innerHTML:获取或设置元素开始标签到结束
标签之间的HTML内容
何时使用:只要获取或设置元素的内容时
固定套路:2个
1、清空子元素:parent.innerHTML="";
2、批量替换子元素:
和单独删除元素对象的效率差异:
DOM Tree--->Render Tree
↑
layout(reflow)最耗时
尽量少触发layout:增加和删除元素节点
课堂练习中:option元素,selected属性表示是否被选中
可当做bool类型用
遍历过程中可能减少元素个数时,都要从后向前遍历
回顾:var arr=[1,2,3];
var deleted=arr.splice(1.1);
deleted数组,包含被删除的元素
deleted[0]获得被删除的元素
textContent:获取或设置开始标签到结束标签之间的文本内容
剔除了子标签,自动转换特殊符号为原文
IE8:innerText
修改属性:
核心DOM:凡是来自不带HTML开头的父类型中的属性和方法
HTML DOM:凡是仅继承HTML开头的父类型中的属性和方法
body--->HTMLBodyElement
-->HTMLElement
***********↑HTML DOM***
*******↓核心DOM********
---->Element
-->Node
获得元素属性值:3种---所有属性的值都是字符串
1、var strValue=elem.getAttribute("属性名");
何时使用:只要获取元素的指定属性的值
2、var strValue=elem.attributes[i/"属性名"].value
// 属性集合 属性节点 属性值
何时使用:遍历一个元素的所有属性时
3、var StrValue=elem.getAttributeNode("属性名").value
//属性节点对象 属性值
修改元素属性值:2种--所有属性的值都是字符串
elem.setAttribute("属性名","属性值")
elem.setAttributeNode(属性节点对象)
移除元素的属性 2种
1、elem.removeAttribute("属性名");
2、elem.removeAttributeNode(属性节点对象);
判断是否包含指定属性
1、elem.hasAttribute("属性名")--->true,有;false ,没有
5个词:attributes get/set/remove/hasAttribute
HTML DOM
获取/修改属性:elem.属性名
删除属性:elem.属性名=""
判断:if(elem.属性名)
***Property vs Attribute
Attribute是出现在html元素开始标签中的特性
只能通过get/setAttriburte访问
比如:a.getAttribute("href")
Property是内存中对象的属性,专门通过.访问
a.href
HTML标准属性:即是HTML元素的特性,同时又是内存中元素对象
的属性
自定义属性:html也可自定义属性
li.setAttribute("age","25")===><li age="25"></li>
只能用getAttribute("age");--->25
li.age=25;==>仅存储在内存中,无法出现页面元素上
只能用.获取
elem.dataset.自定义属性名
自定义属性,核心DOM和HTML DOM不通用
HTML5中自定义属性标准:
1、所有自定义属性都要加data-前缀
2、elem.dataset.自定义属性名//获取
//不用加data-
修改元素的样式:2处可改
1、内联样式:都定义在元素的style属性中
elem.style-->CSSStyleDeclaration类型的对象
获取/设置元素的内联样式属性
elem.style.属性名
属性名:将css属性名去横线变驼峰
问题:获取:只能获得内联样式中的属性,无法获取样式
表中级联或继承来到外部属性
修改样式:放在内联样式中的属性,优先级最高
覆盖所有外部的
何时使用style:修改一个元素的样式时。
2、样式表中的样式:
1、获取计算后的样式:最终层叠应用到一个元素上的所有
样式列表
var style=getComputedStyle(elem)
IE8:var style = elem.currentStyle
if(elem.currentStyle){
var style = elem.currentStyle
}else{
var style=getComputedStyle(elem)
}
何时使用:只要获取一个元素的属性时都要获取计算后的
样式
修改样式表中的样式
1、样式表对象:<style></style>
<link rel="stylesheet".../>
获得样式表对象
var sheet=document.styleSheets[i]
sheet是CSSStyleSheet类型的对象
2、css规则对象
var rule=sheet.cssRules[i]
rule是CSSStyleRule类型的对象
rule对下还可继续包含cssRules集合
3、获取/设置规则中的属性
rule.style.属性名="属性值"
HTML DOM的Form元素
找到表单对象:var form = document.forms[i/name]
找到表单中的元素:var elem = form.elements[i/name]
如果找到name属性的元素可简写为:form.name
form对象的onsubmit事件,在提交之前自动触发,多用于验证所有
form对象都有submit()方法:专用于手动提交表单
创建和删除节点
HTML DOM常用对象:Table Select Form
创建和删除节点:----核心DOM
1、创建单个节点:3步
1、创建指定名称的空节点对象
var newElem=document.createElement("标签名")
比如:var a = document.createElement("a");
<a></a>
2、设置新对象的关键属性
比如:a.innerHTML="go to tmoooc";
a.href="http://tmooc.cn";
<a a.href="http://tmooc.cn">go to tmoooc</a>
3、将a加入指定父元素下:3种方式
1、追加:parent.appendChild(newElem)
2、在之前插入:parent.insertBefore(newElem,已有元素)
3、替换:parent.replaceChild(newElem,被替换的元素)
性能问题:单个创建或删除节点都会导致重新layout
解决:如果同时创建父元素和子元素,都要先创建父元素,再将所有
子元素加入父元素中。最后将父元素整体加入页面
如果父元素已经在页面上,就要将创建的平级元素加入到
文档片段对象中
创建多个平级节点:3步
1、先创建文档片段对象
文档片段:内存中临时存储多个子元素的存储空间
充当临时虚拟的父元素
var frag=document.createDocumentFragment("XXX");
2、创建多个子元素对象,暂时先加入到文档片段中
var child1=document.createElement("XXX");
frag.appendChild(child1);
var child2=document.createElement("XXX");
frag.appendChild(child2);
3、将文档片段整体加入页面父元素中
parent.appendChild(frag);
强调:frag不会出现在页面。
尽量少的使用layout 3种:display:none 批量操作、文档片段
删除节点:var deletedNode=parent.removeChild(子节点)
只有父元素才有权删除子节点
子节点删除自己:child.parentNode.removeChild(child);
HTML DOM常用对象: Table Select Form
select:
事件:onchange:选中项(值)改变时触发
属性:select.selectedIndex:获得当前选中项的位置
select.options:获得select下所有option对象
将select.options.length=0,等效于清空所有的option
方法:select.add(option)
select.remove(index)
Option:创建option,同时设置内容和value属性值
var opt=new Option(innerHTML,value);
固定套路:向select中增加一个option
select.add(new Option(innerHTML[,value]));
可以new的目前只学到,Option和img
课堂练习:
问题:html绑定事件 vs js动态绑定事件
1、html绑定的其实是字符串:
<select onchange="createSelct()"></select>
function createSelct(){
this-->select
}
select.change=function(){
eval("绑定字符串");=>createSelect();
}
html绑定this只能通过在html中显示传入
如果不写,处理函数内部的this--》window
2、js中动态绑定
select.onchange=createSelect;
执行select.onchange();
处理函数内的this就指当前触发事件的元素对象本身。
Table对象
属性:table.rows:获得所有tr对象
方法:
table.insertRow([index]);
index不省略,会再index位置插入一行
省略index,在table结尾追加一个新行
table.deleteRow(index);删除index位置的行
强调:删除行只能用行下标
TableRow对象
属性:tr.cells获取当前行中所有td
方法:
var td = tr.insertCell(index);
tr.deleteCell(index);
删除格,必须用下标
Tablecell对象
属性:td.cellIndex:获得td在当前行中的位置下标。
Form
找到Form:var form=document.forms[i/name];
找到元素 var elem=form.elements[i/name]
form.name
方法:form.submit() form reset()
事件;onsubmit:提交表单前都会自动触发
主要用于验证或取消提交(2个return)
表单中的元素:elem.focus()使用代码让元素获得焦点
elem.blur()
课堂练习:闭包的问题:
1、在绑定事件处理函数的内部,尽量不要使用外部的变量
一旦使用,就会形成闭包,后果被闭包保护的DOM对象无法
从内存中真正删除---内存泄漏
解决:在事件处理函数内部随找随用,用完自动释放
BOM:操作浏览器窗口的API
window对象:2个角色
1、替代ECMAScript中的Global对象,充当全局对象
2、封装浏览器软件/窗口的属性和功能-----BOM
1、打开新链接的方式:4种
1、在当前窗口打开,可后退
html:<a href="url">xxx</a>
js:[window.]open("url","窗口名"[,"窗口配置"]);
open("url","_self")
2、在当前窗口打开,不可后退
js:javascript:location.replace("新URL")
替换history中当前url,不新增history记录;
3、在新窗口打开,可打开多个
html:<a href="url" target="_blank">xxx</a>
js: open("url","_blank")
4、在新窗口打开,只能打开一个
html:<a href="url" target="自定义窗口名">xxx</a>
window.name
浏览器规定:内存中同名窗口对象只能出现一次
后出现的同名窗口会覆盖前一个
js:open("url","自定义窗口名")
窗口大小和窗口的位置:
1、窗口大小:不带单位
window.width/height窗口的宽和高
window.innerWidth/innerHeight文档显示区的宽高
修改窗口大小:2个方法:
window.resizeTo(width,height);
window.resizeBy(width的增量,height的增量);
2、窗口位置:窗口左上角距离显示器左上角的位置top和left
移动窗口的位置:2个方法
window.moveTo(left ,top)
window.moveBy(left的增量,top的增量);
3、打开窗口时,设定新窗口的大小和位置
窗口左上角距显示器左上角的位置top和left
窗口宽度和高度width和height
定时器:按指定时间间隔反复执行同一任务
何时使用:只要按时间间隔反复执行任务
2种
周期性定时器:按指定时间间隔反复执行同一任务
如何定义定时器:3步
1***每一次要执行的任务函数对象:
任务函数的结尾,一般都要考虑临界条件和停止定时器
2、启动定时器:timer=setInterval(taskFun,interval);
强调:只要有可能定制定时器是,必须在启动时就保存定时器序号
3、停止定时器:clearInterval(timer);timer=null;
call apply:调用时临时修改原函数的this,不创建新函数,且调用后this
回复为window
bind:基于现有函数,复制一个新函数的副本,提前为新函数永久绑定this
引用的对象
文本框 textarea中style属性resize:none表示页面的文本框不能拖动改变
navigator:保存浏览器软件属性和配置的对象
判断cookie:cookieEnabled启用了,返回true;否则返回false
cookie:在客户端硬盘持久存储某个网站当前用户个人信息的文件
访问网站时,由网站或客户端浏览器创建,都保存在客户端硬盘
请求该网站时,随request一起自动发到服务器
服务器接到cookie,取出其中的值进行验证
一个网站创建的cookie,只能访问自己网站时使用
优点:持久存储个人数据,提高用户体验
缺点:泄漏个人信息。
判断或查找插件:plugins,返回所有插件对象的集合
判断是否包含:遍历插件集合,判断每个插件的name属性
userAgent:获得浏览器基本信息(名字、版本)的字符串
BOM常用对象:history location
history:当前窗口的历史记录栈
保存了当前窗口本次打开后的url记录
一个方法:history.go(n)
history.go(-1):后退
history.go(1):前进
history.go(0):刷新
history.go(-2):后退两步
location:当前窗口正在访问的url地址对象
修改当前窗口的url地址:只要修改,立刻跳转
location="url";
location.href="url";
location.assign("url");
location.reload(ture/false);重新加载页面;
true:无论页面请求后是否被更改,都重
新向服务器请求新页面
false:只有页面请求后被修改过,才重新
请求服务器,如果未改变,就直接从缓存
中获取
***事件:浏览器自动触发的或用户手动触发的元素状态的改变
DOM Level2 Event标准:
IE8自成体系
事件处理函数:当事件发生时,自动调用的函数
事件处理函数其实是对象的一个特殊属性,只能引用函数对象
其实:on事件名
如何绑定事件处理函数:3种
1、在html元素开始标签中绑定:
<elem on事件名="js语句"...
比如:html: <button onclick="fun(this)"...
其实:button.onclick=function(){
eval("fun(this)");--->fun()
}
js:fun(btn){btn-->button}
当事件发生时:button.onclick();
扩展:所有回调函数:事件处理函数和定时器都可以传入字符串的js
语句作为参数
但是强烈建议:自己使用匿名函数封装要执行的js语句
2、js中动态绑定事件处理函数:2种做法
1、一个事件处理函数只能绑定一个函数对象
elem.on事件名=function(){this-->elem
}
事件触发时:elem.on事件名()
问题:2个
1、一个事件处理函数,只能绑定一个函数对象
2、无法修改事件的触发顺序
***事件周期:从事件触发到各级时间执行完的全过程
DOM标准:3个阶段
1、事件捕获:从window开始,由内向外,到目标元素结束
记录每层元素的时间处理函数
2、目标触发:触发目标元素的事件处理函数
3、冒泡触发:由内向外,从目标元素的上级开始,到window结束
IE:2个阶段
1、目标触发
2、冒泡触发
其中:目标元素:最初实际触发事件的元素
2、js动态绑定,可为一个事件处理函数绑定多个函数对象
还可控制事件触发的顺序
DOM标准:
elem.addEventListener("事件名",函数对象,true/false);
其中:1、事件名不带on
2、壳反复为统一事件绑定多个函数对象
3、最后一个参数表示:是否在捕获阶段就提前触发
默认为false,不会提前触发
改为true,在捕获阶段提前触发
IE8:elem.attachEvent("on事件名",函数对象)
获取事件对象:
什么是事件对象:事件触发时自动创建,封装了事件发生的元素
和属性信息
1、html中绑定的事件处理函数
html中<elem on事件名="fun(event)"
2、js中动态绑定事件时:
DOM标准:事件对象会自动作为处理函数的第一个参数
默认传入
js中:elem.onclick=function(){
arguments[0]-->event
}
事件触发时:elem.onclick()
IE:event属性保存在window全局下
事件触发时:全局window下的even属性自动获得事件对象
兼容写法:var e=window.event || arguments[0];
//ie 8 DOM
强调:不支持以html绑定的事件处理函数
何时获得:只要希望获取事件的属性和触发事件的元素时,都要
先获得事件对象,再从事件对象中读取需要的属性
取消和利用冒泡:
取消冒泡:
DOM标准:e.stopPropagation();
IE8:e.cancelBubble=true;
兼容:if(e.stopPropagation){//DOM
e.stopPropagation();
}else{//Ie8
e.cancelBubble=true;
}
利用冒泡:
***优化:如果多个子元素定义了相同的事件处理函数
建议仅在父元素定义一次事件处理函数,所有子元素共用
为什么:每个事件绑定,在底层都是一个事件的链接对象
绑定事件越多,链接对象消耗资源越大
所以,尽量减少事件绑定的次数
如何利用冒泡:核心:获取目标对象
this的问题:随冒泡不断变化!事件在那个对象上触发 this
就指代哪个对象
解决:获取目标对象,始终指代最初触发事件的目标对象
不随冒泡而改变
如何获得目标对象:
DOM标准:e.target
IE8:e.srcElement
兼容:var target=e.srcElement||e.target;
取消事件:
1、在html中绑定事件处理函数:2个return
2、DOM标准:e.preventDefault()
IE:e.returnValue=false
兼容 if(e.preventDefault){
e.preventDefault()
}else{
e.returnValue=false
}
建议:尽量使用js动态绑定事件处理函数