利用DevTools Elements工具来调试页面DOM
Elements工具是Chrome DevTools界面的第一个标签,如今很多网页都通过JavaScript来动态的修改DOM以及CSS,传统的查看HTML和CSS源代码来调试页面,无法看到那些动态的内容,一遍一遍的刷新页面查看修改HTML和CSS的效果对于开发来说效率也很低下。Elements工具就是一个可以帮助我们实时的查看和编辑DOM树以及CSS样式的工具。
打开DevTools切换到Elements标签就可以看到Elements工具,左半边视图是当前页面的HTML代码,右半边视图是当前选中的DOM的CSS样式,显示的内容是当前Web页面实时的,通过JavaScript对页面的修改都会即时的反映在Elements工具中。为了更好的利用屏幕空间,可以拖动左右两块视图区域调节大小,以及通过点击三角形小图标收缩一些暂时不需要的内容。
我们会发现在Elements工具左边的DOM视图中看到的HTML代码和原始的网页源代码的内容是有点不一样的,有很多原因:
- 可能是页面上引用的JavaScript代码修改了DOM树,像jQuery等JavaScript库提供了大量的修改DOM树的方法,例如append()、remove()、html()等。这些JavaScript代码来改变的DOM,在源代码中是看不到的。
- 浏览器会纠正一些HTML书写的错误。很多人在写HTML代码的时候,会漏掉<html><head><body>这些标签,但是从调试中可以看到浏览器在解析的时候自动地帮我们加上了<html><head><body>这几个标签。
也就是说,我们从Elements工具中看到的HTML代码是当前浏览器所实际解析的。在遇到一些bug需要调试页面HTML代码的时候,通过Elements工具查看,能够让我们以浏览器的角度来看HTML代码,比直接阅读源代码要更直接有效。
曾经在做一个项目的时候,需要对整个网站的样式进行重新设计,通过修改CSS然后在原有的标签上加上class属性来做的,当页面运行的时候,发现有些页面上的元素的显示效果不正常,看源代码class属性已经被加上了似乎没有问题,一打开Elements工具,很快就发现了问题的所在:HTML中每个标签的class属性只能被定义一次,多次定义的class不会被浏览器所解析。如图,第一个class=class1在被浏览器成功的解析了,而class=class2则直接被浏览器所忽略了。
类似的事情还有很多,例如不小心在HTML标签中加入了全角空格导致部分属性没有被解析(大家应该都被输入法坑过)等等,这些问题,可能我们光看源代码的话,很难发现问题出在哪里。而在DevTools的Elements工具下面,那些我们看代码百思不得其解的诡异bug一下子就现了原形。
选中HTML元素
在Elements工具中定位到我们需要查看的HTML元素,有几种方法:
- 和我们在编辑器里看代码一样,通过ctrl+f查找,或者鼠标一层层的点击,定位到需要查看的HTML元素
- 在HTML页面上需要查看的元素上面右键,选择审查元素。
- 按下Ctrl+Shift+C(MAC下面Cmd+Shift+C),或者点击DevTools左上角切换设备模式左边的放大镜按钮,进入审查元素模式,再点击需要查看的HTML元素。
- 在DevTools的Console命令行工具中执行inspect()方法,例如inspect(document.body),关于inspect()以及Console命令行工具具体的使用可以参照学习笔记相关的内容(先留着等写到那里会补上链接的:))。
通过键盘的上下左右按钮,可以快速的选中、折叠和展开HTML节点。在Elements工具的底部,会显示当前查看HTML元素的层级,可以点击上面的元素快速切换层级。
被选中的HTML元素,在页面上会高亮显示并有一个浮动的tooltip跟随。当被选中的HTML元素不在当前显示的范围内时候,会通过tooltip提示使用者当前HTML元素不在显示范围内,此时可以右键Elements工具内被选中的节点,选择「Scroll into view」来让被选中的HTML元素显示出来。
编辑HTML节点和属性
可以通过双击HTML节点对其进行修改,会根据双击的位置自动选中相应的标签、属性名或属性值。也可以通过右键菜单里的功能进行属性的增加和修改,还可以选择「Edit as HTML」对整个选中的节点进行修改。
在修改的过程中,按下ESC可以放弃当前的修改内容,在空白地方单击鼠标左键,可以让当前的修改在页面中实时生效。
我们也可以通过拖动HTML节点来调整元素在页面中的位置。
选中节点按下键盘上的Delete按钮,则会删除当前HTML节点,也可以在右键菜单中通过「Delete Node」完成这一操作,Ctrl+Z(MAC下面Cmd+Z)可以撤销删除操作。
需要特别注意的是,刚才提到的所有的HTML修改,都是临时的,不会影响到任何源代码文件,一旦刷新页面,所有的修改都会被还原。当我们通过Elements工具调试好页面HTML代码后,需要手动的去修改源代码文件以保存修改。
强制设置元素状态
在网页开发中,我们经常使用hover或者visited等状态来实现一些效果,例如鼠标悬停的导航菜单,我们在Elements工具中,可以右键HTML节点来强制设置元素的状态。例如将某个悬停导航强制设置成hover状态来让悬停显示的菜单一直显示以方便我们调试。
设置DOM断点
DOM断点和Sources工具下面的JavaScript代码断点类似,用来在特定条件下暂停JavaScript的执行。JavaScript代码断点关联在JavaScript文件的某一行,当执行到这行代码的时候就触发断点暂停余下的代码执行。DOM断点关联在某个DOM元素,当该DOM元素被修改时触发。
针对JavaScript代码的断点,一般用在我们了解大致的代码运行流程的情况下。例如我想调试某个按钮被设为disabled的这部分代码,可能需要事先去读代码,找类似于attr(‘disabled‘, ‘disabled‘)的代码,可能有一些复杂的页面,有好几个地方都设置了这个属性,我们需要一个个打上代码断点来调试。而借助DOM断点,我们不用去事先了解代码内容,只需要设置「在按钮的属性发生修改的时候暂停执行」这样的条件,当条件满足时候,自动的会在相应的代码处暂停JavaScript执行。
DevTools给我们提供了三种DOM断点:
- Subtree Modifications
Subtree Modifications会在子节点的增加、删除、移动时候触发。例如下面这段代码,如果你在「main-content」元素上设置了Subtree Modifications断点,那么当这段代码执行时候会触发Subtree Modifications断点。
var element = document.getElementById('main-content'); //modify the element's subtree var mySpan = document.createElement('span'); element.appendChild( mySpan );
- Attributes Modifications
Attributes Modifications断点会在当前元素的状态(id、class、disabled等)发生改变时候触发。
var element = document.getElementById('main-content'); // class attribute of element has been modified element.className = 'active';
- Node Removal
Node Removal断点会在当前元素被移除时候触发。
document.getElementById('main-content').remove();
DOM断点的设置非常简单,右键要设置断点的元素,在菜单中选择「Break on...」在二级菜单中就可以设置三种DOM断点。
在Elements工具的右边CSS区域有个「DOM Breakpoints」的Tab可以查看已经设置的DOM断点,光标移上去会显示断点对应的DOM元素,右键菜单里面可以移除当前或者全部DOM断点,前面的checkbox可以用来暂时取消DOM断点。
转载自我的技术博客http://www.cc-lab.cn/chrome-dev-tools-2/
(完)