BOM和DOM相关的复习题
-
页面加载事件有哪些,各自的触发时机是什么?
页面加载事件 触发时机 JavaScript window.onload 页面上所有DOM元素和外部文件(图片、css、js)加载完成后执行事件 DOMContentLoaded DOM元素加载完成后触发 jQuery $(document).ready() $(function(){ …}) 页面所有DOM元素加载完成执行事件,不需等外部文件加载完成 -
有哪些定时器,可否实现一个秒表功能
setTimeout() clearTimeout() 一次性调用函数并取消执行
setInterval() clearInterval() 重复性调用函数并取消执行
<span id="hour">00</span>: <span id="minute">00</span>: <span id="second">00</span> <button id="start">开始</button> <button id="end">结束</button> <script> window.onload=function(){ let oH = document.getElementById("hour") let oM = document.getElementById("minute") let oS = document.getElementById("second") let oStart = document.getElementById("start") let oEnd = document.getElementById("end") var timer = null var count = 0 oStart.onclick=function(){ timer = setInterval(function(){ count++ oS.innerText = (count%60+'').padStart(2,"0") oM.innerText = (parseInt(count/60%60)+'').padStart(2,"0") oH.innerText = (parseInt(count/60/60)+'').padStart(2,"0") },1000) } oEnd.onclick=function(){ clearInterval(timer) } } </script>
-
location对象,常见的属性和方法有哪些
属性/方法 描述 hash 从#开始的URL(锚) host 主机名和当前URL端口号 hostname 主机名 href 完整URL pathname 当前URL路径部分 port URL端口号 protocol 当前URL协议 search 从?开始的URL(查询) assign() 加载新的文档 reload() 重新加载当前文档 replace() 新文档替换当前文档 -
history对象,常见的属性和方法有哪些
属性/方法 描述 length 历史列表中网址数 back() 后退,加载历史列表中前一个URL forward() 前进,加载历史列表中下一个URL go() 加载历史列表中某一个页面 -
如何区分chrome,safari,firefox等不同的浏览器
window子对象navigator对象获取浏览器类型 window.navigator.userAgent
-
常见的DOM的增删查改操作,对应的方法有哪些
-
创建DOM元素:createElement(“元素名”) 创建元素节点
createTextNode(“文本内容”) 创建文本节点
-
插入DOM元素:A.appendChild(B) 插入到父元素内部子元素的末尾 A-父元素 B-新元素
A.inserBefore(B,ref) 插入到父元素某一个子元素之前
-
删除DOM元素: A.removeChild(B) 删除父元素下某子元素
-
复制DOM元素:obj.cloneNode(bool) obj 被赋值的元素 1/true-复制元素本身和其下所有子元素 0-本身
-
替换DOM元素: A.replaceChild(new,old)
-
查找DOM元素:以当前所选元素为基点
-
查找父元素:obj.parentNode
-
查找子元素:childNodes 所有子节点(包括元素 文本节点)
children 所有元素节点,不包括文本节点
firstChild lastChild 包括文本节点
firstElementChild lastElementChild 元素节点
-
查找兄弟元素:previousSibling nextSibling 包括文本节点
previousElementSibling nextElementSibling 元素节点
-
-
-
常见的DOM元素,有哪些事件,如何绑定和解绑,如何理解事件捕获和冒泡
-
常见DOM元素:div img forms
-
事件:
-
鼠标事件:
单击 移入 移出 按下 松开 移动 右键 onclick onmouseover onmouseout onmousedown onmouseup onmousemove oncontextmenu -
键盘事件:按下 – onkeydown 松开 – onkeyup 按下并松开 – onkeypress
-
表单事件:获得焦点 – onfocus 失去焦点 – onblur 选中单行、多行文本框 – onselect 选中某一项单选、复选、下拉列表 – onchange
-
编辑事件:页面复制 – oncopy 防止页面内容被选取 – onselectstart
-
页面事件:文档加载完成后 – onload 离开页面之前 – onbeforeunloaded
-
移动端事件:
- 触摸事件:手指触摸屏幕 – touchstart 手指在屏幕上移动 – touchmove 手指离开屏幕 – touchend 触摸被系统事件中断 – touchcancel
-
-
绑定事件和解绑:
-
obj.事件名=function(){}; obj.事件名=null;
-
事件监听器:
obj.addEventListener(type,fn,false);
type – 事件类型(click mouseover) fn – 函数名/匿名函数 false – 事件冒泡阶段调用
obj.removeEventListener(type,fn,false); fn – 必须是函数名,不能是函数
-
-
事件捕获和冒泡:
事件流是指从页面中接收事件的顺序,事件发生时在元素节点之间按特定的顺序传播;
事件捕获的顺序为DOM最顶层开始逐级向下传到具体元素接收;
事件冒泡的顺序为由最具体的元素接收逐级向上。
-
写一个小demo,实现鼠标和手指都可以移动小方块。
<style type="text/css"> #box{ position: absolute; width: 100px; height: 100px; background-color: skyblue; } </style> <body> <div id="box"></div> <script> window.onload=function(){ let oBox = document.getElementById("box") oBox.onmousedown = function(e1){ //鼠标按下获取方块距离鼠标的相对位置 //console.log(e1.clientX,oBox.offsetLeft) let left = e1.clientX - oBox.offsetLeft let top = e1.clientY - oBox.offsetTop document.onmousemove = function (e2) { //鼠标拖动改变方块位置 oBox.style.left = e2.clientX - left + 'px' oBox.style.top = e2.clientY - top + 'px' } document.onmouseup = function(){//鼠标松开解绑事件 document.onmousemove = null } } } </script>
在手机上无法运行
修改:
window.onload=function(){ let oBox = document.getElementById("box") let left = 0, top = 0 //方块相对鼠标/手指距离 let flag = false //是否按下/触摸 function down(){ //按下/触摸坐标 flag = true if(event.touches){ left = event.touches[0].clientX - oBox.offsetLeft top = event.touches[0].clientY - oBox.offsetTop }else{ left = event.clientX - oBox.offsetLeft top = event.clientY - oBox.offsetTop } } function move(){ if(flag){ if(event.touches){ oBox.style.left = event.touches[0].clientX - left + 'px' oBox.style.top = event.touches[0].clientY - left + 'px' }else{ oBox.style.left = event.clientX - left + 'px' oBox.style.top = event.clientY - top + 'px' } } } function end(){ flag = false } oBox.addEventListener("mousedown",function(){ down() }) oBox.addEventListener("mousemove",function(){ move() }) document.addEventListener("mouseup",function(){ end() }) oBox.addEventListener("touchstart",function(){ down() }) oBox.addEventListener("touchmove",function(){ move() }) oBox.addEventListener("touchend",function(){ end() })
-
手动实现一个继承
//父类 function Animal(name){ this.name = name this.sayName=function(){ alert(this.name) } } Animal.prototype.eat = function(){ alert(`${this.name} is eating`) } // 1.原型链继承:父类实例作为子类原型 // 不能向构造函数传参 function Cat(){} Cat.prototype = new Animal() Cat.prototype.name='cat' let cat = new Cat() cat.sayName() //cat cat.eat() //cat is eating // 2.构造继承:父类的构造函数复制给子类 // 可以向构造函数传参,可以实现多继承;不能继承父类的原型 function Dog(name){ Animal.call(this) this.name = name } let dog = new Dog('dog') dog.sayName() //dog //dog.eat() //不是函数 // 3.实例继承:为父类实例添加新属性,作为子类实例返回 // 无法实现多继承 function Fox(name){ let animal = new Animal() animal.name = name return animal } let fox = new Fox('fox') fox.sayName() //fox fox.eat() //fox is eating // 4.拷贝继承:用for in循环拷贝父类属性/方法 // 支持多继承,不可枚举的方法不能拷贝 function Bear(name){ let animal = new Animal() for(let attr in animal){ Bear.prototype[attr] = animal[attr] } this.name = name } let bear = new Bear('bear') bear.sayName() //bear bear.eat() //bear is eating // 5.组合继承:构造继承(可传参)+父类实例作为子类原型 // 继承父类属性方法原型 可传参 调用两次父类构造函数 function Lion(name){ Animal.call(this,name) //Animal.apply(this,[name]) } Lion.prototype = new Animal() let lion = new Lion('lion') lion.sayName() lion.eat() // 6.寄生组合继承:去掉父类的实例属性 function Pony(name){ Animal.call(this,name) } Pony.prototype = Object.create(Animal.prototype) let pony = new Pony('pony') pony.sayName() //pony pony.eat() //pony is eating // 7.class继承 class Animal2{ constructor(name){ this.name = name } sayName(){ alert(this.name) } } class Person extends Animal2{ constructor(name){ super(name) } } let person = new Person('person') person.sayName() //person
-
手动实现一个深拷贝
let object1 = {
name:{
first:"y",
last:'ym'
},
age:21
}
// 1.JSON对象的parse和stringify
function deepClone1(obj){
let obj1 = JSON.parse(JSON.stringify(obj))
return obj1
}
let object2 = deepClone1(object1)
object2.name.first = "l"
console.log(object1.name.first) //y
// 2.递归复制
function deepClone2(obj){
let obj1 = {}
if(obj && typeof(obj) === "object"){
for(key in obj){
if(obj[key] && typeof(obj[key])==="object"){
obj1[key] = deepClone2(obj[key])
}else{
obj1[key] = obj[key]
}
}
}
return obj1
}
let object3 = deepClone2(object1)
object3.name.first = "w"
console.log(object1.name.first) //y
递归复制中递归函数可能参数为数组或对象
修改:
let object1 = {
name:{
first:"y",
last:'ym'
},
age:21,
hobby:["sleep","eat"]
}
function deepClone2(obj){
let obj1 = Array.isArray(obj) ? [] : {}
if(obj && typeof(obj) === "object"){
for(let key in obj){
if(obj[key] && typeof(obj[key])==="object"){
obj1[key] = deepClone2(obj[key])
}else{
obj1[key] = obj[key]
}
}
}
return obj1
}
let object3 = deepClone2(object1)
object3.name.first = "w"
object3.hobby[0] = "play"
console.log(object1)
console.log(object3)