前端面试题DOM

  1. 利用冒泡和不利用冒泡的差别
    答案:
  2. 绑定位置不同: 不利用冒泡绑定在目标元素上,利用冒泡绑定在父元素上
  3. 监听对象的个数不同: 不利用冒泡会反复创建多个监听,利用冒泡始终只有一个监听
  4. 动态生成的元素: 不利用冒泡无法自动获得事件处理函数,必须反复绑定
    利用冒泡可让动态添加的子元素自动获得父元素的处理函数,无需反复绑定
  5. 按HTML查找和按选择器查找的差别
    答案:
  6. 返回值不同: 按HTML查找返回动态集合,按选择器查找返回非动态集合
  7. 效率不同: 按HTML查找效率高,按选择器查找效率低
  8. 易用性不同: 当条件复杂时,按HTML查找繁琐,而按选择器查找简单
  9. 列举DOM中常用优化
    答案:
  10. 查找时,如果之用一个条件就可查询出结果时,优先选择按HTML查找。如果查找条件复杂,则优先选择易用的按选择器查找
  11. 添加时,尽量减少操作DOM树的次数,减少重排重绘。如果同时添加父元素和子元素,应先将子元素添加到到父元素,最后再将父元素添加到DOM树。如果添加多个平级子元素,则应先将子元素添加到文档片段,最后,再将文档片段添加到DOM树
  12. 修改时,尽量减少重排重绘。如果同时修改多个元素的内容或样式,应尽量使用innerHTML和cssText方式修改元素的内容和样式。应使用class批量修改样式
  13. 事件绑定时,应尽量利用冒泡减少事件监听的个数。
  14. 如何鉴别浏览器的名称和版本号
    答案:
var browser,version,ua=navigator.userAgent;
     if(ua.indexOf("IE")!=-1)       browser="IE"
else if(ua.indexOf("Edge")!=-1)     browser="Edge"  
else if(ua.indexOf("Firefox")!=-1)  browser="Firefox"  
else if(ua.indexOf("OPR")!=-1)      browser="OPR"  
else if(ua.indexOf("Chrome")!=-1)   browser="Chrome"  
else if(ua.indexOf("Safari")!=-1)   browser="Safari"  
else if(ua.indexOf("Trident")!=-1)  browser="IE",version=11;

document.write(`<h1>${browser}</h1>`);

if(version===undefined){
//截取: 从浏览器名称所在位置,再跳过浏览器名称长度+1 之后的3位
  var i=ua.indexOf(browser);
  i+=browser.length+1;
  version=parseFloat(ua.slice(i,i+3))
}
document.write(`<h1>${version}</h1>`);
  1. 为按钮绑定事件,实现事件节流:
    答案:
    //节流
var canClick=true;
btn.onclick=function(){
  if(canClick){
    canClick=false;
    console.log("发送ajax请求,加载更多...");
    setTimeout(function(){
      console.log("请求完成!");
      canClick=true;
    },3000);
  }
}
  1. 为页面绑定滚动事件,实现事件防抖:
    答案:
    //防抖
    var timer1;
    window.onscroll=function(){
      if(timer1!==undefined){
        clearTimeout(timer1);
      }
      timer1=setTimeout(function(){
        console.log("发送ajax请求,加载更多");
        timer1=undefined;
      },200)
}
  1. DOM 元素 e 的 e.getAttribute(propName)和 e.propName 有什么区别和联系
    答案:
  • e.getAttribute(),是标准 DOM 操作文档元素属性的方法,具有通用性可在任意文档上使用,返回元素在源文件中设置的属性
  • e.propName 通常是在 HTML 文档中访问特定元素的特性,浏览器解析元素后生成对应对象(如 a 标签生成 HTMLAnchorElement),这些对象的特性会根据特定规则结合属性设置得到,对于没有对应特性的属性,只能使用 getAttribute 进行访问
  • e.getAttribute()返回值是源文件中设置的值,类型是字符串或者 null(有的实现返回"")
  • e.propName 返回值可能是字符串、布尔值、对象、undefined 等
  • 大部分 attribute 与 property 是一一对应关系,修改其中一个会影响另一个,如 id,title 等属性
  • 一些布尔属性<input hidden/>的检测设置需要 hasAttribute 和 removeAttribute 来完成,或者设置对应 property
  • <a href="../index.html">link</a>中 href 属性,转换成 property 的时候需要通过转换得到完整 URL
  • 一些 attribute 和 property 不是一一对应如:form 控件中<input value="hello"/>对应的是 defaultValue,修改或设置 value property 修改的是控件当前值,setAttribute 修改 value 属性不会改变 value property
  1. 如何最小化重绘(repaint)和回流(reflow)?
    答案:
  • 需要要对元素进行复杂的操作时,可以先隐藏(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
  1. 描述一下DOM事件模型:
    答案:
    捕获、目标触发、冒泡
    捕获阶段: 由外向内,依次记录各级父元素上的事件处理函数。只记录,暂不触发。
    目标触发:优先触发目标元素上的事件处理函数。
    冒泡: 由内向外,依次触发各级父元素上的事件处理函数。

  2. 谈谈事件委托/代理:
    答案:
    事件委托是指将事件绑定目标元素的到父元素上,利用冒泡机制触发该事件
    优点:

  • 可以减少事件注册,节省大量内存占用
  • 可以将事件应用于动态添加的子元素上
    缺点: 使用不当会造成事件在不应该触发时触发
    示例:
    js
ulEl.addEventListener('click', function(e){
    var target = event.target || event.srcElement;
    if(!!target && target.nodeName.toUpperCase() === "LI"){
        console.log(target.innerHTML);
    }
}, false);
  1. IE 的事件处理和 W3C 的事件处理有哪些区别?
    答案:
    绑定事件
  • W3C: targetEl.addEventListener(‘click’, handler, false);
  • IE: targetEl.attachEvent(‘onclick’, handler);
    删除事件
  • W3C: targetEl.removeEventListener(‘click’, handler, false);
  • IE: targetEl.detachEvent(event, handler);
    事件对象
  • W3C: var e = arguments.callee.caller.arguments[0]
  • IE: window.event
    事件目标
  • W3C: e.target
  • IE: window.event.srcElement
    阻止事件默认行为
  • W3C: e.preventDefault()
  • IE: window.event.returnValue = false’
    阻止事件传播
  • W3C: e.stopPropagation()
  • IE: window.event.cancelBubble = true
  1. 解释一下这段代码的意思吗?
	```js
  [].forEach.call($$("*"), function(el){
      el.style.outline = "1px solid #" + (~~(Math.random()*(1<<24))).toString(16);
  })

	答案:
	获取页面所有的元素,遍历这些元素,为它们添加 1 像素随机颜色的轮廓(outline)
-   $$(sel) // $$函数被许多现代浏览器命令行支持,等价于 document.querySelectorAll(sel)
-   [].forEach.call(NodeLists) // 使用 call 函数将数组遍历函数 forEach 应到节点元素列表
-   el.style.outline = "1px solid #333" // 样式 outline 位于盒模型之外,不影响元素布局位置
-   (1<<24) // parseInt("ffffff", 16) == 16777215 == 2^24 - 1 // 1<<24 == 2^24 == 16777216
-   Math.random()\*(1<<24) // 表示一个位于 0 到 16777216 之间的随机浮点数
-   ~~Math.random()\*(1<<24) // ~~ 作用相当于 parseInt 取整
-   (~~(Math.random()\*(1<<24))).toString(16) // 转换为一个十六进制-

13. 前端优化的方法:
	答案:
1.减少dom操作
    2.部署前,图片压缩,代码压缩
    3.优化js代码结构,减少冗余代码
    4.减少http请求,合理设置 HTTP缓存
    5.使用内容分发cdn加速
    6.静态资源缓存
    7.图片延迟加载




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值