什么是 dom?(必会)
什么是 dom
- DOM 是 W3C(万维网联盟)的标准
- DOM 定义了访问 HTML 和 XML 文档的标准
什么是 W3C
-
“W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。”
-
W3C DOM 标准被分为 3 个不同的部分
- 核心 DOM - 针对任何结构化文档的标准模型
- XML DOM - 针对 XML 文档的标准模型
- HTML DOM - 针对 HTML 文档的标准模型
备注:DOM 是 Document Object Model(文档对象模型)的缩写
dom 节点的 Attribute 和 Property 有何区别?(必会)
什么是 Property
每 个 DOM 节点都是一个 object 对象,有自己的 property 和 method
原 则 上 property 应 该 仅 供 js 操 作 , 不 会 出 现 在 html 中 ( 默 认 属 性 除 外 :id/src/href/className/dir/title/lang 等),和其他 js object 一样,自定义的 property 也会出现在 object的 for…in 遍历中
什么是 Attribute
attribute 出现 在 dom 中,js 提供了 getAttribute/setAttribute 等方法来获取和改变它的值,最后作用于 html 中,可以影响 innerHTML 获取的值。可以通过访问 dom 节点的 attributes 属性来获取 改节点的所有的 attribute。(在 IE<9 中,attribute 获取和改变的实际上是 property。)
两者之间的区别是
- 自定义的 Property 与 Attribute 不同步,不相等
- 非自定义的 DOM property 与 attributes 是有条件同步的
- 非自定义的属性(id/src/href/name/value 等),通过 setAttribute 修改其特性值可以同步作用到 property 上,而通过.property 修改属性值有的(value)时候不会同步到 attribute 上,即不会反应到 html 上(除以下几种情况,非自定义属性 在二者之间是同步的)。
dom 结构操作怎样添加、移除、移动、复制、创建和查找节点?(必会)
创建新节点
createDocumentFragment() //创建一个 DOM 片段
createElement() //创建一个具体的元素
createTextnode() //创建一个文本节点
添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //并没有 insertAfter()
查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的 Name 属性的值(IE 容错能力较强,会得到一个数组,其中包括 id 等于 name 值的)
getElementById() //通过元素 Id,唯一性
dom 事件模型?(必会)
DOM 事件模型。
DOM 事件模型分为两种:事件捕获和事件冒泡。
事件捕获以点击事件为例,同类型事件会由 根—>目标的祖先素—>目标的父元素—>目标元素事件冒泡和事件捕获截然相反。从内到外依次触发:目标元素—>目标元素的父元素—>父元素的父元素—>根事件传播
事件捕获和事件冒泡都有事件传播阶段,传播阶段就是事件从触发开始到结束的过程。
优先级:先捕获,再冒泡。
两种传播方式的来源:W3C 推行 DOM2 级事件之前网景和 IE 在打架,网景用的事件传播方式是捕获,IE 用的事件传播方式是冒泡
什么是事件冒泡,它是如何工作的?如何阻止事件冒泡、默认行为?(必会)
-
什么是事件冒泡,他是如何工作的
在一个对象上触发某类事件(比如单击 onclick 事件),这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层,即 document 对象(有些浏览器是 window)
-
阻止事件冒泡的方法
-
w3c 方法是:event.stopPropagation(); 事件处理过程中,阻止冒泡事件,但不会阻止默认行为(跳转至超链接)
-
IE 则是使用 event.cancelBubble = true 阻止事件冒泡
-
return false; jq 里面事件处理过程中,阻止冒泡事件,也阻止默认行为(不跳转超链接)封装方法:
function bubbles(e){ var ev = e || window.event; if(ev && ev.stopPropagation) { //非 IE 浏览器 ev.stopPropagation(); } else { //IE 浏览器(IE11 以下) ev.cancelBubble = true; } console.log("最底层盒子被点击了") } 阻止默认行为: w3c 的方法是 e.preventDefault(), IE 则是使用 e.returnValue = false; 封装: //假定有链接<a href="http://caibaojian.com/" id="testA" >caibaojian.com</a> var a = document.getElementById("testA"); a.onclick =function(e){ if(e.preventDefault){ e.preventDefault(); }else{ window.event.returnValue == false; } }
-
JavaScript 动画和 CSS3 动画有什么区别?(必会)
CSS 动画
优点:
-
浏览器可以对动画进行优化。
-
浏览器使用 requestAnimationFrame 比起 setTimeout,setInterval 设置动画的优势主要是:
-
requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒 60 帧。
-
在隐藏或不可见的元素中 requestAnimationFrame 不会进行重绘或回流,这当然就意味着更少的的 cpu,gpu 和内存使用量。
- 强制使用硬件加速(通过 GPU 来提高动画性能)
-
-
代码相对简单,性能调优方向固定
-
于帧速表现不好的低版本浏览器,CSS3 可以做到自然降级,而 JS 则需要撰写额外代码
缺点:
- 运行过程控制较弱,无法附加事件绑定回调函数。CSS 动画只能暂停,不能在动画中寻找一个特定的时间点,不能在半路反转动画,不能变换时间尺度,不能在特定的位置添加回调函数或是绑定回放事件,无进度报告。
- 代码冗长。想用 CSS 实现稍微复杂一点动画,最后 CSS 代码都会变得非常笨重。
JS 动画
优点:
- JavaScript 动画控制能力很强, 可以在动画播放过程中对动画进行控制:开始、暂停、回放、终止、取消都是可以做到的。
- 动画效果比 css3 动画丰富,有些动画效果,比如曲线运动,冲击闪烁,视差滚动效果,只有 JavaScript 动画才能完成。
- CSS3 有兼容性问题,而 JS 大多时候没有兼容性问题。
缺点:
- avaScript 在浏览器的主线程中运行,而主线程中还有其它需要运行的 JavaScript脚本、样式计算、布局、绘制任务等,对其干扰导致线程可能出现阻塞,从而造成丢帧的情况。
- 代码的复杂度高于 CSS 动画
css 动画和 js 动画的差异
- 代码复杂度,js 动画代码相对复杂一些 。
- 动画运行时,对动画的控制程度上,js 能够让动画,暂停,取消,终止,css 动画不能添加事件。
- 动画性能看,js 动画多了一个 js 解析的过程,性能不如 css 动画好。
总结:
简单的状态切换,不需要中间过程控制,css 动画是优选方案。
复杂的状态的 APP。应该使用 js 动画
event 对象的常见应用?(必会)
- event.preventDefault(); // 阻止默认行为,阻止 a 链接默认的跳转行为
- event.stopPropagation(); // 阻止冒泡
- event.stopImmediatePropagation(); // 按钮绑定了 2 个响应函数,依次注册 a,b 两个事件,点击按钮,a 事件中加event.stopImmediatePropagation()就能阻止 b 事件
- event.currentTarget // 早期的 ie 不支持,当前绑定的事件
- event.target
通用事件绑定/ 编写一个通用的事件监听函数?(必会)
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector; selector = null;
}
elem.addEventListner(type, function(e) {
var target; if (selector) {
target = e.target;
if (target.matches(selector)) {
fn.call(target, e); }
} else {
fn(e);
}
})
}
// 使用代理
var div1 = document.getElementById('div1');
bindEvent(div1, 'click', 'a', function(e) {
console.log(this.innerHTML);
});
// 不使用代理
var a = document.getElementById('a1');
bindEvent(div1, 'click', function(e) {
console.log(a.innerHTML);
})
DOM 和 BOM 的区别(必会)
-
BOM
- BOM 是 Browser Object Model 的缩写,即浏览器对象模型。
- BOM 没有相关标准。
- BOM 的最根本对象是 window
-
DOM
- DOM是 Document Object Model 的缩写,即文档对象模型。
- DOM是 W3C 的标准。
- DOM最根本对象是 document(实际上是 window.document)
事件三要素(必会)
- 事件源、就是你点的那个 div,触发的对象
- 事件类型、表示动作,比如点击、滑过等
- 事件处理函数(事件处理程序)、表示结果,比如点开关跳转到另一个页面
事件执行过程(必会)
事件捕获过程:当我们点击 TEXT 时,首先是 window->document->body->div->text.这个过程称为事件捕获,W3C 浏览器的标准执行流程。
事件冒泡过程:text->div->body->document->window.这个过程称为事件冒泡。IE 浏览器只支持冒泡,不支持捕获。W3C 浏览器先执行捕获,后执行冒泡
获取元素位置(必会)
-
通过元素的 offsetLeft 和 offsetTop
dom 元素的 offsetLeft、offsetTop 指的是元素相对于其 offseParent 指定的坐标来说的。
offsetParent:是指当前元素最近的经过定位的父级元素,如果没有则一直向上直至 body。
注意当前元素为 fixed 时,其 offsetParent 的值为 null
拓展:
offsetWidth/offsetHeight: width+padding+border clientLeft/clientTop:表示内容区域的左上角相对于整个元素左上角的位置(包括边框)// border 值 clientWidth/clientHeight: width+padding scrollWidth:获取对象的滚动宽度 scrollHeight: 获取对象的滚动高度。 scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离 scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 window.screen.availHeight/window.screen.availWidth: 浏览器去除上方工具栏和下放菜单栏可用宽高 window.screen.height/window.screen.width: 屏幕宽高
-
event.clientX 和 event.clientY
事件相对于浏览器窗口的水平和垂直距离
-
getBoundingClientRect
方法返回一个一个矩形对象,包含四个属性:left、top、right 和 bottom。分别表示元素各边与页面上边和左边的距离
封装运动函数(必会)
/* obj 指的是 DOM 对象
- json 指的是 CSS 样式
例 startMove(oDiv,{width:100,height:100},function(){})
*/
function startMove(obj,json,fnEnd){
clearInterval(obj.timer);//先清除之前的定时器
obj.timer = setInterval(function(){
var bStop = true; // 假设所有的值都到了
for( var attr in json ){
//遍历 json 属性
var cur = (attr == 'opacity') ? Math.round(parseFloat(getStyle(obj,attr))*100) : parseInt(getStyle(obj,attr)); //对 opacity 特殊处理
var speed = (json[attr] - cur)/6;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //speed 数字转化,防止不能到达目标的 bug
if( cur != json[attr]) bStop = false; //如果没有达到目标值,则 bStop 设为 false;
if(attr == 'opacity'){
obj.style.filter = 'alpha(opacity='+ (cur + speed) +')';
obj.style.opacity = (cur + speed)/100;
}else{
obj.style[attr] = cur + speed + 'px';
}
}
if(bStop){
clearInterval(obj.timer);
if(fnEnd) fnEnd(); //执行回调函数
}
},30);
}
function getStyle(obj,name){
return obj.currentStyle ? obj.currentStyle[name] : window.getComputedStyle(obj,null)[name]; // 浏 览 器兼容性处理,注意 getComputedStyle 为只读属性
}
function getByClass(oParent,sClass){
var aEle = oParent.getElementsByTagName('*');
var aResult =[];
var re = new RegExp('\b' + sClass + '\b','i');
for(var i=0; i<aEle.length;i++ ){
if(re.test(aEle[i].className)) aResult.push(aEle[i]);
}
return aResult;
}
绑定事件和解除事件的区别(必会)
事件绑定
定义:一个事件可以加多次,且不会覆盖
绑定方法
-
attachEvent ('on+事件名',函数名) 这个只兼容 ie 6-8
-
addEventListener (事件名,函数名,false) 支持 ie9+ chrom firfox
绑定事件的封装
function addEvent(obj,sEv,fn){ if(obj.addEventListener){ obj.addEventListener(sEv,fn,false); }else{ obj.attachEvent('on'+sEv,fn); } };
解除绑定事件的封装
function removeEvent(obj,sEv,fn){ if(obj.removeEventListener){ obj.removeEventListener(sEv,fn,false); }else{ obj.detachEvent('on'+sEv,fn); } }
谈谈事件委托的理解?(必会)
JavaScript 事件代理则是一种简单的技巧,把事件处理器添加到一个上级元素上,这样就避免了把事件处理器添加到多个子级元素上。这主要得益于浏览器的事件冒泡机制。
优点:
- 减少事件注册,节省内存。
- 在 table 上代理所有 td 的 click 事件。
- 在 ul 上代理所有 li 的 click 事件。
- 简化了 dom 节点更新时,相应事件的更新。
- 不用在新添加的 li 上绑定 click 事件。
- 当删除某个 li 时,不用移解绑上面的 click 事件。
缺点:
- 事件委托基于冒泡,对于不冒泡的事件不支持
- 层级过多,冒泡过程中,可能会被某层阻止掉。
- 理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。所以建议就近委托,比如在 table 上代理 td,而不是在 document 上代理 td。
- 把所有事件都用代理就可能会出现事件误判。比如,在 document 中代理了所有 button 的 click 事件,另外的人在引用改 js 时,可能不知道,造成单击 button 触发了两个 click 事件
JavaScript 中的定时器有哪些?他们的区别及用法是什么?(必会)
JavaScript 中的定时器有以下几种
- setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
- setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。
setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。
setTimeout 也叫定时器
setInterval 也叫计时器
比较 attachEvent 和 addEventListener?(必会)
attachEvent 只能在 IE 浏览器给标签绑定事件, 可以多次绑定
语法:Element.attachEvent(Etype,EventName)
参数 Element:要为该元素动态添加一个事件
Etype:指定事件类型.比如:onclick,onkeyup,onmousemove 等
EventName:指定事件名称.也就是你写好的函数
addEventListenerW3C 标准, 除 IE 浏览器使用, 它给标签绑定事件
语法:Element.addEventListener(Etype,EventName,boole)
Etype:事件类型.比如:click,keyup,mousemove.注意使用 addEventListener 绑定事件时,设置参数事
件类型时不必写 on.否则会出错
EventName:要绑定事件的名称.也就是你写好的函数
boole:该参数是一个布尔值:默认 false.false 代表冒泡阶段执行, true 代表捕获阶段执行
document.write 和 innerHTML 的区别?(必会)
document.write 是直接写入到页面的内容流,如果在写之前没有调用 document.open, 浏览器会自动调用 open。每次写完关闭之后重新调用该函数,会导致页面被重写
innerHTML 则是 DOM 页面元素的一个属性,代表该元素的 html 内容。
innerHTML 将内容写入某个 DOM 节点,不会导致页面全部重绘
innerHTML 很多情况下都优于 document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分
什么是 window 对象?什么是 document 对象?(必会)
什么是 window 对象
简单来说,document 是 window 的一个对象属性。
Window 对象表示浏览器中打开的窗口。
如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个
window 对象,并为每个框架创建一个额外的 window 对象。
所有的全局函数和对象都属于 Window 对象的属性和方法。
它是一个顶层对象,而不是另一个对象的属性,即浏览器的窗口。
属性:
defaultStatus 缺省的状态条消息
document 当前显示的文档(该属性本身也是一个对象)
frame 窗口里的一个框架((FRAME>)(该属性本身也是一个对象)
frames array 列举窗口的框架对象的数组,按照这些对象在文档中出现的顺序列出(该属性本身也是一个对象)
history 窗口的历史列表(该属性本身也是一个对象)
length 窗口内的框架数
location 窗口所显示文档的完整(绝对)URL(该属性本身也是一个对象)不要把它与如
document.location 混淆,后者是当前显示文档的 URL。用户可以改变 window.location(用另一个文档
取代当前文档),但却不能改变 document.location (因为这是当前显示文档的位置)
name 窗口打开时,赋予该窗口的名字
opener 代表使用 window.open 打开当前窗口的脚本所在的窗口(这是 Netscape
Navigator 3.0beta 3 所引入的一个新属性)
parent 包含当前框架的窗口的同义词。frame 和 window 对象的一个属性
self 当前窗口或框架的同义词
status 状态条中的消息
top 包含当前框架的最顶层浏览器窗口的同义词
window 当前窗口或框架的同义词,与 self 相同
方法:
alert() 打开一个 Alert 消息框
clearTimeout() 用来终止 setTimeout 方法的工作
close() 关闭窗口
confirm() 打开一个 Confirm 消息框,用户可以选择 OK 或 Cancel,如果用户单击 OK,该方法返回 true,单击 Cancel 返回 false
blur() 把焦点从指定窗口移开(这是 Netscape Navigator 3.0 beta 3 引入的新方法)
focus() 把指定的窗口带到前台(另一个新方法)
open() 打开一个新窗口
prompt() 打开一个 Prompt 对话框,用户可向该框键入文本,并把键入的文本返回到脚本
setTimeout() 等待一段指定的毫秒数时间,然后运行指令事件处理程序事件处理程序
onload() 页面载入时触发
onunload() 页面关闭时触发
什么是 document 对象
该对象是 window 和 frames 对象的一个属性,是显示于窗口或框架内的一个文档
属性:
alinkColor 活动链接的颜色(ALINK)
anchor 一个 HTMI 锚点,使用<A NAME=>标记创建(该属性本身也是一个对象)
anchors array 列出文档锚点对象的数组(<A NAME=>)(该属性本身也是一个对象)
bgColor 文档的背景颜色(BGCOLOR)
cookie 存储于 cookie.txt 文件内的一段信息,它是该文档对象的一个属性
fgColor 文档的文本颜色(标记里的 TEXT 特性)
form 文档中的一个窗体(
)(该属性本身也是一个对象)forms anay 按照其出现在文档中的顺序列出窗体对象的一个数组(该属性本身也是一个对象)
lastModified 文档最后的修改日期
linkColor 文档的链接的颜色,即标记中的 LINK 特性(链接到用户没有观察到的文档)
link 文档中的一个<A HREF=>标记(该属性本身也是一个对象)
links array 文档中 link 对象的一个数组,按照它们出现在文档中的顺序排列(该属性本身也是一个对象)
location 当前显示文档的 URL。用户不能改变 document.location(因为这是当前显示文档的位置)。但是,可以改变 window.location (用其它文档取代当前文档)window.location 本身也是一个对象,而 document.location 不是对象
referrer 包含链接的文档的 URL,用户单击该链接可到达当前文档
title 文档的标题((TITLE>)
vlinkColor 指向用户已观察过的文档的链接文本颜色,即标记的 VLINK 特性
方法:
clear 清除指定文档的内容
close 关闭文档流
open 打开文档流
write 把文本写入文档
writeln 把文本写入文档,并以换行符结尾
区别:
- window 指窗体。document 指页面。document 是 window 的一个子对象。
- 用 户 不 能 改 变 document.location( 因 为 这 是 当 前 显 示 文 档 的 位 置 ) 。 但 是 , 可 以 改 变 window.location ( 用 其 它 文 档 取 代 当 前 文 档 )window.location 本 身 也 是 一 个 对 象 , 而document.location 不是对象
Js 拖动的原理?(必会)
js 的拖拽效果主要用到以下三个事件:
mousedown 鼠标按下事件
mousemove 鼠标移动事件
mouseup 鼠标抬起事件
当点击 dom 的时候,记录当前鼠标的坐标值,也就是 x、y 值,以及被拖拽的 dom 的 top、left 值,而且还要在鼠标按下的回调函数里添加鼠标移动的事件:
document.addEventListener("mousemove", moving, false)
和添加鼠标抬起的事件
document.addEventListener("mouseup",function() {
document.removeEventListener("mousemove", moving, false);}, false);
这个抬起的事件是为了解除鼠标移动的监听,因为只有在鼠标按下才可以拖拽,抬起就停止不会移动了。
当鼠标按下鼠标移动的时候,记录移动中的 x、y 值,那么这个被拖拽的 dom 的 top 和left 值就是:
top=鼠标按下时记录的 dom 的 top 值+(移动中的 y 值 - 鼠标按下时的 y 值)
left=鼠标按下时记录的 dom 的 left 值+(移动中的 x 值 - 鼠标按下时的 x 值);
<div id="draggle"></div>
<script>
window.onlond = function(){
var dom = document.getElementById("draggle")
dom.addEventListener(
"mousedown",
function(event){
var x = event.clientX
var y = event.clientY
var marginLeft = parseInt(dom.offsetLeft)
var marginTop = parseInt(dom.offsetTop)
function margin(e){
var marginX = e.clientX = x
var marginY = e.clientY = y
dom.style.marginLeft = marginLeft + marginX + "px"
dom.style.marginTop = marginTop + marginY + "px"
}
document.addEventListener("mousemove",margin,false)
document.addEventListener("mousemove", function(){
document.removeEventListener("mousemove", margin, false)
},false)
},
false
)
}
</script>
描述浏览器的渲染过程,DOM 树和渲染树的区别(必会)
-
浏览器的渲染过程:
解析 HTML 构建 DOM(DOM 树),并行请求 css/image/js
CSS 文件下载完成,开始构建 CSSOM(CSS 树)
CSSOM 构建结束后,和 DOM 一起生成 Render Tree(渲染树)
布局(Layout):计算出每个节点在屏幕中的位置
显示(Painting):通过显卡把页面画到屏幕上
-
DOM 树 和 渲染树 的区别
DOM 树与 HTML 标签一一对应,包括 head 和隐藏元素
渲染树不包括 head 和隐藏元素,大段文本的每一个行都是独立节点,每一个节点都有对应的 css 属性
如何最小化重绘(repaint)和回流(reflow)(必会)
什么是重绘 Repaint 和重排 (回流 reflow)
重绘:当元素的一部分属性发生改变,如外观、背景、颜色等不会引起布局变化,只需要浏览器根据元素的新属性重新绘制,使元素呈现新的外观叫做重绘。
重排(回流):当 render 树中的一部分或者全部因为大小边距等问题发生改变而需要 DOM 树重新计算的过程
重绘不一定需要重排(比如颜色的改变),重排必然导致重绘(比如改变网页位置)
方法:
- 需要要对元素进行复杂的操作时,可以先隐藏(display:"none"),操作完成后再显示
- 需要创建多个 DOM 节点时,使用 DocumentFragment 创建完后一次性的加入 document缓存 Layout 属性值,如:var left = elem.offsetLeft; 这样,多次使用 left 只产生一次回流
- 尽量避免用 table 布局(table 元素一旦触发回流就会导致 table 里所有的其它元素回流)
- 避免使用 css 表达式(expression),因为每次调用都会重新计算值(包括加载页面)
- 尽量使用 css 属性简写,如:用 border 代替 border-width, border-style, border-color
- 批量修改元素样式:elem.className 和 elem.style.cssText 代替 elem.style.xxx
IE 与标准事件模型有哪些差别?(了解)
-
添加事件
DOM 事件模型 – addEventListener
addEventListener(eventType, handler, useCapture)
eventType 不带有 on 字符串;
handler 参数是一个事件句柄,这个函数或方法带有一个事件对象参数;
useCapture 参数决定了事件句柄触发在哪种事件传播阶段,如果 useCapture 为 true 则为捕获阶段,反之则为冒泡阶段。
IE 事件模型 – attachEvent
attachEvent(eventType, handler)
eventType 带 on 字符串;
handler 参数是一个事件句柄,这个函数或方法带有一个事件对象参数;
-
事件过程
DOM 事件模型包含捕获阶段和冒泡阶段,IE 事件模型只包含冒泡阶段;
DOM 事件模型可使用 e.stopPropagation()来阻止事件流
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3天,点击查看活动详情