整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

浅谈Html的内容加载及JS执行顺序

事跟我说他用jQuery取不到页面上隐藏元素input的值,他的html页面大概内容如下。

<!DOCTYPE html>
<html lang="zh">
 
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<script type="text/javascript" src="jslib/jquery-1.11.2.min.js"></script>
	<title>浅谈Html页面内容执行顺序</title>
	<script type="text/javascript">
		var userId = $('#hiddenUserId').val();
		var contextPath = $('#hiddenContextPath').val();
		var userName = $('#hiddenUserName').val();
	</script>
</head>
 
<body>
	<input type="hidden" id="hiddenUserId" value="101" />
	<input type="hidden" id="hiddenContextPath" value="/web" />
	<input type="hidden" id="hiddenUserName" value="小明" />
</body>
 
</html>

页面中的JS脚本在head中,JS脚本要读取的input在body中。浏览器对html页面内容的加载是顺序加载,也就是在html页面中前面先加载,因此当加载到JS脚本时,input还没有加载到浏览器中。JS是一种解释性的脚本,也是从上而下顺序执行,由于这段JS代码是立即执行的,所以当JS在执行的时候,读取不到input的值。

最直接的修改方法是把JS放到网页的最下面执行。

<!DOCTYPE html>
<html lang="zh">
 
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<script type="text/javascript" src="jslib/jquery-1.11.2.min.js"></script>
	<title>浅谈Html页面内容执行顺序</title>	
</head>
 
<body>
	<input type="hidden" id="hiddenUserId" value="101" />
	<input type="hidden" id="hiddenContextPath" value="/web" />
	<input type="hidden" id="hiddenUserName" value="小明" />
	
	<script type="text/javascript">
		var userId = $('#hiddenUserId').val();
		var contextPath = $('#hiddenContextPath').val();
		var userName = $('#hiddenUserName').val();
	</script>
</body>
 
</html>

把JS放到网页的最下面,这样在JS执行的时候,网页内容都已经加载完毕。把JS放在网页的最下面方法并不是最好的解决方法,大部分情况JS并不是总能放在网页的最下面。这时可以用window的onload事件,onload事件在整个页面都加载完成后才触发,可以把JS脚本放在onload里面执行。不同浏览器onload事件添加方式也不一样。

IE下事件:

window.attachEvent('onload', function(){
			var userId = $('#hiddenUserId').val();
			var contextPath = $('#hiddenContextPath').val();
			var userName = $('#hiddenUserName').val();
		});

Chrome/Firefox等DOM标准事件:

window.addEventListener('load', function(){
			var userId = $('#hiddenUserId').val();
			var contextPath = $('#hiddenContextPath').val();
			var userName = $('#hiddenUserName').val();
		});

由于不同浏览器的事件添加方式不一样,jQuery为我们提供了通用的初始化方法,该方法在页面加载完成时触发。

$(function(){
			var userId = $('#hiddenUserId').val();
			var contextPath = $('#hiddenContextPath').val();
			var userName = $('#hiddenUserName').val();
		});

上面方法本质就是添加onload监听事件。

最终修改后的页面

览器解析HTML文件的过程是网页呈现的关键步骤之一。具体介绍如下:


HTML文档的接收和预处理

  1. 网络请求处理:当用户输入URL或点击链接时,浏览器发起HTTP请求,服务器响应并返回HTML文件。此过程中,浏览器需要处理DNS查询、建立TCP连接等底层网络通信操作。
  2. 预解析优化:为了提高性能,现代浏览器在主线程解析HTML之前会启动一个预解析线程,提前下载HTML中链接的外部CSS和JS文件。这一步骤确保了后续渲染过程的顺畅进行。

解析为DOM树

  1. 词法分析和句法分析:浏览器的HTML解析器通过词法分析将HTML文本标记转化为符号序列,然后通过句法分析器按照HTML规范构建出DOM树。每个节点代表一个HTML元素,形成了多层次的树状结构。
  2. 生成对象接口:生成的DOM树是页面元素的结构化表示,提供了操作页面元素的接口,如JavaScript可以通过DOM API来动态修改页面内容和结构。

CSS解析与CSSOM树构建

  1. CSS文件加载与解析:浏览器解析HTML文件中的<link>标签引入的外部CSS文件和<style>标签中的内联CSS,生成CSSOM树。CSSOM树反映了CSS样式的层级和继承关系。
  2. CSS属性计算:包括层叠、继承等,确保每个元素对应的样式能够被准确计算。这些计算过程为后续的布局提供必要的样式信息。

JavaScript加载与执行

  1. 阻塞式加载:当解析器遇到<script>标签时,它会停止HTML的解析,转而先加载并执行JavaScript代码。这是因为JS可能会修改DOM结构或CSSOM树,从而影响已解析的部分。
  2. 异步和延迟加载:为了不影响页面的初步渲染,可以采用async或defer属性来异步加载JS文件,这样可以在后台进行JS的加载和执行,而不阻塞HTML解析。

渲染树的构建

  1. 合并DOM树和CSSOM树:有了DOM树和CSSOM树后,浏览器将它们组合成渲染树,这个树只包含显示界面所需的DOM节点及对应的样式信息。
  2. 不可见元素的排除:渲染树会忽略例如<head>、<meta>等不可见元素,只关注<body>内的可视化内容。

布局计算(Layout)

  1. 元素位置和尺寸确定:浏览器从渲染树根节点开始,递归地计算每个节点的精确位置和尺寸,这个过程也被称为“回流”或“重排”,是后续绘制的基础。
  2. 布局过程的优化:现代浏览器会尽量优化布局过程,例如通过流式布局的方式减少重复计算,确保高效地完成布局任务。

绘制(Paint)

  1. 像素级绘制:绘制是一个将布局计算后的各元素绘制成像素点的过程。这包括文本、颜色、边框、阴影以及替换元素的绘制。
  2. 层次化的绘制:为了高效地更新局部内容,浏览器会将页面分成若干层次(Layer),对每一层分别进行绘制,这样只需更新变化的部分。

因此,我们开发中要注意以下几点:

  • 避免过度使用全局脚本:尽量减少使用全局脚本或者将它们放在文档底部,以减少对HTML解析的阻塞。
  • 合理组织CSS和使用CSS预处理器:合理组织CSS文件的结构和覆盖规则,利用CSS预处理器进行模块化管理。
  • 利用浏览器缓存机制:通过设置合理的缓存策略,减少重复加载相同资源,提升二次访问的体验。
  • 优化图片和多媒体资源:适当压缩图片和优化多媒体资源的加载,减少网络传输时间和渲染负担。

综上所述,浏览器解析HTML文件是一个复杂而高度优化的过程,涉及从网络获取HTML文档到最终将其渲染到屏幕上的多个步骤。开发者需要深入理解这些步骤,以优化网页性能和用户体验。通过合理组织HTML结构、优化资源加载顺序、减少不必要的DOM操作和合理安排CSS和JavaScript的加载与执行,可以显著提升页面加载速度和运行效率。

号持续更新前端面试题和答案......

以下是一些HTML基础面试题:

  1. 请解释一下HTML是什么以及它的作用。
  2. 什么是HTML标签(Tag)?举例说明几个常见的HTML标签及其作用。
  3. HTML中的块级元素(Block-level elements)和内联元素(Inline elements)有什么区别?请举例说明。
  4. 请解释一下HTML5和HTML之间的区别。
  5. HTML中的元数据(Metadata)是什么?请举例说明几个常见的HTML元数据标签。
  6. HTML中的超链接(Hyperlink)是什么?请解释一下如何创建超链接。
  7. HTML中的表单(Form)是什么?请解释一下如何创建一个基本的表单。
  8. HTML中的图像(Image)是如何插入的?请解释一下如何在HTML中插入图像。
  9. 请解释一下HTML中的无序列表(Unordered List)和有序列表(Ordered List)的区别,并举例说明。
  10. HTML中的特殊字符(Special Characters)是什么?请举例说明如何使用特殊字符。
  11. HTML中的表格(Table)是什么?请解释一下如何创建一个简单的HTML表格。
  12. HTML中的注释(Comment)是什么?请解释一下如何在HTML中添加注释。
  13. HTML中的DOCTYPE是什么?请解释一下DOCTYPE的作用和用法。
  14. HTML中的元素(Element)和标签(Tag)有什么区别?请解释一下它们之间的关系。
  15. HTML中的语义化(Semantic HTML)是什么?请解释一下语义化的重要性和如何实现语义化。
  1. HTML5中的新特性有哪些?请举例说明其中几个新特性及其作用。
  2. HTML中的元素可以有哪些全局属性(Global Attributes)?请解释一下其中几个全局属性的作用。
  3. HTML中的表单元素有哪些常见的类型(Type)?请解释一下其中几个类型的作用。
  4. HTML中的音频(Audio)和视频(Video)是如何嵌入的?请解释一下如何在HTML中嵌入音频和视频。
  5. HTML中的元素可以有哪些事件属性(Event Attributes)?请解释一下其中几个事件属性的作用。
  6. HTML中的语义化标签(Semantic Tags)有哪些?请解释一下其中几个语义化标签的作用。
  7. HTML中的响应式设计(Responsive Design)是什么?请解释一下如何使用HTML实现响应式设计。
  8. HTML中的地理定位(Geolocation)是什么?请解释一下如何使用HTML获取用户的地理位置信息。
  9. HTML中的离线存储(Offline Storage)是什么?请解释一下如何使用HTML实现离线存储。
  10. HTML中的元素可以有哪些媒体属性(Media Attributes)?请解释一下其中几个媒体属性的作用。
  11. HTML中的元素可以有哪些表单属性(Form Attributes)?请解释一下其中几个表单属性的作用。
  12. HTML中的可访问性(Accessibility)是什么?请解释一下如何使用HTML实现可访问性。
  13. HTML中的SVG是什么?请解释一下SVG在HTML中的使用方法和优势。
  14. HTML中的IFrame是什么?请解释一下IFrame的作用和用法。
  15. HTML中的字符编码(Character Encoding)是什么?请解释一下字符编码的作用和常见的字符编码方式。