版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2025年高频dom面试题及答案Q:DOM节点有哪些常见类型?如何区分元素节点与文本节点?A:DOM节点共有12种类型(由nodeType属性标识),开发中最常用的4类是:元素节点(nodeType=1,如div、p)、文本节点(nodeType=3,如标签内的文字内容)、注释节点(nodeType=8,如<!--注释-->)、文档节点(nodeType=9,即document对象)。元素节点与文本节点的核心区别在于:元素节点是HTML标签的抽象(如<div>对应元素节点),可包含子节点;文本节点是纯文本内容的载体(如"HelloWorld"),无嵌套结构。可通过nodeType直接判断:元素节点nodeType为1,文本节点为3;或通过nodeName属性——元素节点的nodeName是标签名大写(如DIV),文本节点的nodeName固定为"text"。Q:如何获取一个元素的所有子节点?子元素与子节点有何区别?A:获取子节点的常用方法:1.parentNode.childNodes:返回包含所有子节点的NodeList(包括元素节点、文本节点、注释节点等);2.parentElement.children:返回仅包含子元素节点的HTMLCollection(过滤了文本、注释等非元素节点)。子元素(子元素节点)是子节点的子集。例如,若父元素内有空格或换行符(会被解析为文本节点),childNodes会包含这些文本节点,而children仅保留元素节点。例如:```html<divid="parent"><p>文本</p><!--注释--></div>```此时parent.childNodes包含文本节点(换行)、p元素节点、文本节点(换行)、注释节点;而parent.children仅包含p元素节点。Q:动态创建DOM元素有哪些方式?各自的优缺点是什么?A:常见方式及对比:1.document.createElement('tagName'):优点:直接创建元素节点,可通过属性/方法精确设置(如setAttribute、textContent),安全性高(避免XSS风险);缺点:复杂结构需多层嵌套时代码量较大(如创建包含多个子元素的结构需多次appendChild)。2.innerHTML赋值:优点:通过字符串快速提供复杂结构(如`div.innerHTML='<p>内容</p>'`),适合动态渲染大量重复元素;缺点:存在XSS风险(若内容包含用户输入需严格转义);会破坏原有DOM结构(重新解析时原元素的事件监听器、子节点会被清除)。3.insertAdjacentHTML(position,htmlString):优点:在指定位置插入HTML字符串(position可选'beforebegin'/'afterbegin'/'beforeend'/'afterend'),避免覆盖原内容;性能优于多次appendChild(一次性解析);缺点:同样存在XSS风险,需谨慎处理用户输入。4.cloneNode(deep):优点:复制现有元素(deep为true时复制子节点),适合快速复用结构;缺点:复制后的元素需重新绑定事件(原事件监听器不会自动复制)。实际开发中,创建简单元素推荐createElement;复杂结构且需高性能时用insertAdjacentHTML;需复用现有结构时用cloneNode。Q:setAttribute与直接设置DOM属性(如element.className)有何区别?A:核心区别在于操作的对象不同:setAttribute操作的是HTML属性(即标签上的属性),设置的属性值始终是字符串类型。例如:`input.setAttribute('value','123')`会修改HTML中的value属性,但不会改变input元素当前的输入值(若用户已手动修改过输入框内容)。直接设置DOM属性操作的是JS对象的属性,可能与HTML属性不同步。例如:`input.value='456'`会直接修改元素的当前值(即input框显示的内容),但此时HTML中的value属性仍为初始值(除非通过getAttribute获取,否则不会更新)。典型场景:input的value属性。HTML中的value是初始值(通过getAttribute('value')获取),而DOM的value属性是当前输入值(通过element.value获取)。设置setAttribute('value','x')仅修改初始值,不影响用户当前输入;设置element.value则直接改变当前显示值。Q:DOM事件流分为几个阶段?如何阻止事件传播?A:DOM事件流包含3个阶段:1.捕获阶段(CapturePhase):事件从window开始,沿DOM树向下传播到目标元素的父级(不包括目标元素自身);2.目标阶段(TargetPhase):事件到达目标元素;3.冒泡阶段(BubblePhase):事件从目标元素开始,沿DOM树向上传播到window。阻止事件传播的方法:阻止冒泡:在事件处理函数中调用event.stopPropagation(),但不会阻止捕获阶段的传播;完全阻止事件流:调用event.stopImmediatePropagation(),不仅阻止冒泡/捕获,还会阻止当前元素上后续同类型事件监听器的执行(如同一元素绑定了多个click监听器,调用后后续监听器不再触发)。注意:默认情况下,事件监听器在冒泡阶段触发(addEventListener的第三个参数useCapture默认为false)。若需在捕获阶段触发,需将useCapture设为true。Q:事件委托(事件代理)的原理是什么?适用场景及实现方式?A:原理:利用事件冒泡机制,将子元素的事件监听器绑定到父元素上。当子元素触发事件时,事件会冒泡到父元素,父元素通过event.target判断实际触发事件的子元素,从而执行相应逻辑。适用场景:子元素数量多(如列表项),减少监听器数量以提升性能;子元素动态添加(如异步加载的列表项),无需为新元素重复绑定事件;统一处理同类型元素的事件(如多个按钮的点击事件)。实现示例(列表项点击委托到ul):```javascriptconstul=document.querySelector('ul');ul.addEventListener('click',(e)=>{consttarget=e.target;if(target.tagName==='LI'){//确保目标是li元素console.log('点击了列表项:',target.textContent);}});//动态添加li时无需重新绑定事件ul.innerHTML+='<li>新项</li>';```优势:减少内存占用(一个父级监听器替代多个子监听器),自动处理动态元素,代码更简洁。Q:什么是重排(Reflow)和重绘(Repaint)?如何优化以减少其发生?A:重排(回流):浏览器重新计算元素的几何属性(位置、尺寸)并重新布局的过程。触发场景包括:修改元素尺寸(width/height)、位置(margin/padding)、显示状态(display)、查询布局属性(offsetWidth/scrollTop)等。重绘:元素外观变化(如颜色、背景、透明度)但不影响布局时,浏览器重新绘制的过程。重绘代价低于重排,但频繁重绘仍会影响性能。优化策略:1.合并样式修改:将多次样式修改合并为一次(如通过class添加多个样式,或设置cssText)。反例:```javascriptelement.style.width='100px';element.style.height='200px';//两次重排```正例:```javascriptelement.style.cssText='width:100px;height:200px;';//一次重排```2.避免频繁读取会触发重排的属性:如offsetWidth、scrollTop等。若需多次读取,可先缓存值。反例:```javascriptfor(leti=0;i<100;i++){console.log(element.offsetWidth);//每次读取触发重排}```正例:```javascriptconstwidth=element.offsetWidth;for(leti=0;i<100;i++){console.log(width);//仅一次重排}```3.使用脱离文档流的元素:将频繁变动的元素设为position:absolute或fixed,使其不影响其他元素布局(重排仅发生在自身)。4.使用requestAnimationFrame:将DOM操作放入动画帧中,浏览器会合并多个操作,减少重排次数。5.批量操作DOM:如需要添加多个子元素,先创建文档片段(documentFragment),在片段中完成所有操作后再一次性添加到DOM树。Q:虚拟DOM(VirtualDOM)的作用是什么?与直接操作真实DOM相比有何优势?A:虚拟DOM是真实DOM的轻量级JS对象表示(如React中的fiber节点),通过记录DOM的结构和状态,在状态变更时提供新的虚拟DOM,与旧虚拟DOM进行diff算法对比,仅将变化的部分同步到真实DOM。优势:1.减少真实DOM操作次数:直接操作真实DOM(如频繁appendChild、修改样式)会触发多次重排/重绘,虚拟DOM通过diff计算最小更新集,仅更新变化的节点。2.跨平台支持:虚拟DOM的JS对象结构可映射到不同平台(如ReactNative将虚拟DOM转换为原生组件),而真实DOM仅适用于浏览器。3.性能可预测:diff算法的时间复杂度为O(n)(n为节点数),相比直接操作真实DOM的不可控性能消耗更稳定。注意:虚拟DOM并非在所有场景下都更快。对于简单的DOM操作(如单个元素修改),直接操作真实DOM可能更高效;但在复杂应用(如大量状态变更的列表)中,虚拟DOM的批量更新优势显著。Q:MutationObserver的作用是什么?与旧版MutationEvents有何区别?A:MutationObserver是用于监听DOM树变化的API,可观察元素的子节点增减、属性修改、文本内容变更等。与旧版MutationEvents(如DOMNodeInserted、DOMAttrModified)的区别:1.异步触发:MutationObserver在所有DOM变更完成后异步触发回调(通过微任务队列),避免阻塞渲染;而MutationEvents是同步触发(变更时立即触发),可能导致性能问题。2.可配置性:MutationObserver支持细粒度配置(如只监听子节点变化、只监听属性变化等);MutationEvents固定监听所有类型的变更。3.兼容性与弃用:MutationEvents已被W3C弃用(部分浏览器已停止支持),MutationObserver是现代标准方案。使用步骤:```javascript//1.创建观察者实例,定义回调(接收mutationRecords数组)constobserver=newMutationObserver((mutations)=>{mutations.forEach(mutation=>{console.log('变更类型:',mutation.type);//'childList'/'attributes'等console.log('变更目标:',mutation.target);});});//2.配置观察选项(需指定要观察的变更类型)constconfig={childList:true,//监听子节点增减attributes:true,//监听属性变更attributeFilter:['class'],//仅监听class属性(可选)subtree:true,//监听目标的所有后代节点(可选)characterData:true//监听文本内容变更(可选)};//3.开始观察目标元素consttarget=document.querySelector('container');observer.observe(target,config);//4.停止观察(如组件卸载时)//observer.disconnect();```典型场景:实现自动保存(监听文本框内容变更)、响应式布局(监听容器尺寸变化触发重排)、第三方组件的DOM变更监听(如富文本编辑器)。Q:自定义元素(CustomElements)的实现步骤是什么?生命周期钩子有哪些?A:自定义元素是WebComponents标准的一部分,允许开发者创建可复用的自定义HTML标签。实现步骤:1.定义类并继承HTMLElement(或其扩展类如HTMLButtonElement);2.在类中定义生命周期钩子(如connectedCallback);3.使用customElements.define('标签名',类)注册元素(标签名必须包含连字符,如my-component)。生命周期钩子:connectedCallback:元素被插入DOM树时触发(可在此初始化事件监听、渲染内容);disconnectedCallback:元素被移除DOM树时触发(可在此清理事件监听、定时器);attributeChangedCallback(attrName,oldVal,newVal):元素属性被修改时触发(需通过staticgetobservedAttributes()指定要监听的属性);adoptedCallback():元素被移动到新文档(如通过document.adoptNode)时触发(较少使用)。示例(计数器组件):```javascriptclassCounterElementextendsHTMLElement{staticgetobservedAttributes(){return['count'];}constructor(){super();this.attachShadow({mode:'open'});//可选:使用ShadowDOM封装样式this.shadowRoot.innerHTML=`<style>.counter{padding:8px;}</style><divclass="counter"><button>减</button><span>${this.count}</span><button>加</button></div>`;}getcount(){returnparseInt(this.getAttribute('count'))||0;}setcount(val){this.setAttribute('count',val);}connectedCallback(){this.shadowRoot.querySelectorAll('button').forEach((btn,index)=>{btn.addEventListener('click',()=>{this.count+=index===0?-1:1;});});}attributeChangedCallback(attr,oldVal,newVal){if(attr==='count'){this.shadowRoot.querySelector('span').textContent=newVal;}}disconnectedCallback(){//清理事件监听(若未使用ShadowDOM,需手动移除)}}customElements.define('my-counter',CounterElement);```使用:`<my-countercount="0"></my-counter>`Q:ShadowDOM的作用是什么?如何实现样式封装?A:ShadowDOM是WebComponents的核心特性之一,用于将组件的内部结构和样式与外部隔离,避免样式冲突。其作用:样式封装:组件内部的CSS仅作用于ShadowDOM内的元素,外部CSS无法穿透(除非使用::part()或::slotted());结构隔离:ShadowDOM内的元素不会被外部选择器(如document.querySelector)直接访问,需通过element.shadowRoot获取;内容分发:通过<slot>元素允许外部内容插入到组件内部指定位置。实现样式封装的关键:1.在自定义元素的构造函数中调用attachShadow({mode:'open'})(mode为'closed'时外部无法访问shadowRoot);2.内部样式写在shadowRoot的<style>标签中,不会影响外部DOM;3.外部样式若需影响ShadowDOM内的元素,需使用穿透选择器(如:host()匹配自定义元素本身,::slotted()匹配slot中的外部元素)。示例(按钮组件的ShadowDOM):```javascriptclassCustomButtonextendsHTMLElement{constructor(){super();this.attachShadow({mode:'open'});this.shadowRoot.innerHTML=`<style>/仅作用于ShadowDOM内的button/button{padding:8px16px;background:007bff;color:white;border:none;}/匹配自定义元素本身(:host)/:host(:hover)button{background:0056b3;}/匹配外部传入slot的内容/::slotted(span){font-weight:bold;}</style><button><slot>默认按钮</slot><!-外部内容插入位置--></button>`;}}customElements.define('custom-button',CustomButton);```使用:```html<custom-button><span>点击我</span><!-会被插入到slot位置,受::slotted样式影响--></custom-button>```此时,外部CSS`.button{color:red;}`不会影响custom-button内部的按钮样式。Q:IntersectionObserver的作用是什么?如何实现元素的视口可见性监听?A:IntersectionObserver用于异步监听目标元素与其祖先元素或视口(viewport)的交叉状态(即是否进入可视区域)。传统实现需监听scroll事件并计算元素位置,性能较差;IntersectionObserver通过浏览器底层优化,高效触发回调。核心配置参数:root:监听的祖先元素(默认是视口);rootMargin:根元素的边距(类似CSS的margin,用于扩展/收缩监听区域,如'100px0'表示提前100px触发);threshold:交叉比例阈值(0-1之间的数组,如[0,0.5,1]表示当目标元素与根元素交叉比例达到0%、50%、100%时触发回调)。实现步骤(图片懒加载):```javascript//1.创建观察者实例constobserver=newIntersectionObserver((entries)=>{entries.forEach(entry=>{if(entry.isIntersecting){//元素进入视口constimg=entry.target;img.src=img.dataset.src;//将data-src赋值给src触发加载observer.unobserve(img);//加载后停止监听}});},{rootMargin:'0px0px200px0px',//提前200px加载threshold:0.1});//2.观察所有懒加载图片document.querySelectorAll('img.lazy').forEach(img=>{observer.observe(img);});```适用场景:图片/视频懒加载、无限滚动加载更多内容、广告曝光统计、动画触发(如元素进入视口时播放动画)。Q:DOM树与渲染树(RenderTree)的区别是什么?A:DOM树是HTML文档的节点层次结构(包含所有元素、文本、注释节点);渲染树是浏览器用于绘制页面的结构,仅包含可见节点(排除display:none、script、meta等不可见节点)。两者的核心区别:1.节点范围:DOM树包含所有节点;渲染树仅包含需要渲染的节点(visibility:hidden的节点会被包含,因为仍占据空间)。2.结构关联:渲染树的节点与DOM树节点并非一一对应。例如,文本节点被分割成多个盒(textspan)时,渲
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 甘肃省天水市清水县多校联考2025-2026学年高一上学期1月期末考试地理试卷(含答案)
- 2026届高三生物二轮复习课件:选择题强化练 4.遗传的基本规律与伴性遗传
- 化工企业冬季培训课件
- 钢结构绿色制造技术应用
- 飞机结构专业知识课件
- 2026安徽合肥工业大学管理学院管理学院医疗机器人与智慧医疗健康管理团队科研助理招聘3人备考考试试题及答案解析
- 2026新疆前海集团有限责任公司招聘1人备考考试试题及答案解析
- 2026年上半年黑龙江事业单位联考哈尔滨市招聘592人参考考试题库及答案解析
- 2026江苏苏州人才发展有限公司招聘2人(一)备考考试题库及答案解析
- 2026四川通发广进人力资源管理咨询有限公司AI数据标注员(第三批)招聘备考考试题库及答案解析
- 安全生产考试点管理制度(3篇)
- 孕妇尿液捐献协议书
- 2025年立体仓库维护服务合同
- BIM技术在建筑施工环境管理中的应用
- 2025全国高考Ⅰ卷第16题说题比赛课件-2026届高三数学二轮复习
- 快消品市场调研分析报告模板
- 装修保护电梯施工技术交底
- 社保专员工作述职报告
- DB15∕T 2385-2021 草原退化评价技术规程
- 焦化厂仪表工岗位考试试卷及答案
- 餐厅充值服务合同范本
评论
0/150
提交评论