`

我对Javascript渲染加载以及解释调用顺序的一点理解

阅读更多
      原本在项目中的需求是这样的,向服务器提交一个Ajax请求后,在服务器的FTL中生成动态的数据后返回,同时在FTL模板文件中夹杂了一些JS脚本以及XX方法定义,渲染返回后直接作为文本添加到客户端页面DIV的innerHTML。先暂且不论这种方式的优劣,就这个需求看,大家应该理解我的用意是在页面中去调用Ajax返回生成的js代码。按我原来的想法,只要在回调函数返回后将我将要调用JS代码加载到当面页面中的某个DIV的innerHTML,包含XX方法,然后就可以顺利调用XX方法。但是事实上,会出现XX方法 is not defined的问题。我个人将这个问题定义为由于对浏览器对JS的渲染加载以及解释调用顺序不理解造成的设计错误。鉴于项目中的代码过于庞大,对于这个问题,我写了个测试页面来进行分析,新建一个test.htm:
<script>
	function a(){
		sadasd
		alert("a");
	}
	function c(){
		document.getElementById("test1").innerHTML="<script>function z(){alert(\"z\");}<\/script>";
		z();
	
	}
	function d(){
		document.getElementById("test2").innerHTML="";
		b();
	
	}
</script>
<input type="button" value="test_a" onclick="a();">
<input type="button" value="test_b" onclick="b();">
<input type="button" value="test_c" onclick="c();">
<input type="button" value="test_d" onclick="d();">
<div id="test1"></div>
<div id="test2">
<script>
	function b(){
		alert("b");
	}
</script>
</div>

       首先,你用浏览器打开该页面时,应该不会有任何错误。这说明浏览器加载页面对JS进行渲染解释时并没有去解释方法内部的实现,因为方法a()中我写了一行没有语法规则的字符串,如果刚才解析了必会报错。
      然后你点击按钮test_b,你会发现b()方法顺利调用了,没有出现问题。
      接着,你点击按钮test_a,发现并没有alert(a),而是报了'sadasd' 未定义的错误。可见js方法中的内容是在方法被调用时去解析的。
      到此,我解释下方法c(),d()的设计用意。
      方法c(),我是模拟了本文开头提到的ajax回调方法中向页面div的innerHTML添加js方法定义这种场景。通过添加按钮test_c,触发方法c(),在方法c()中向id为“test1”的div的innerHTML添加了方法z()的定义,代码仅仅是非常简单的alert("z")。然后试图调用z(),这也正是我当时遇到的错误。
      方法d()是对c()的结论一个再次论证,如果我在d()中清除了div“test2”中的innerHTML,即删除了方法b()的定义,那我还能调用b()嘛?
     
      思考一分钟,预测下你的结果?
    
      然后你义无反顾的点击按钮test_c,发现z is not defined的错误。
      如果此时你通过firebug去查看“test1”div,你可以看到存在:
        <script>function z(){alert("z");}</script>

     但是为什么会报z is not defined呢?
     接着你疑惑着去点击test_d,结果b调用又成功了....alert了b.

     我的理解是这样的(纯属个人通过实验的结论):
     1.浏览器在第一次加载页面后将所有<script>标签内的js放入浏览器中属于js的上下文内存栈,然后解析并执行所有<script>标签内的js全局脚本。(这也就是为什么在后面通过事件往页面innerHTML添加的js方法被认为是is not defined的原因,而我们删除的b()却还可以调用)
     2.在事件触发等原因造成方法被调用时,首先去上下文栈里查找该方法定义,找到的解释并执行该方法(所以a()在此时报错了),否则报XX is not defined的错误。

      暂时做个实验记录,有时间再去看看具体浏览器对JS引擎的相关实现。
    



分享到:
评论
3 楼 shhbobby 2011-02-15  
我的理解跟博主的差不多
在页面加载的时候,所有的javascript都加载并且处于激活状态
当 ajax返回js之后 不知道有没有办法让浏览器再把返回来的js也激活就好了
2 楼 emsn 2010-06-30  
eason007 写道
inner对js是没有用的,要用eval。

删除inner同样对js无效


这话有点片面,比如阁下对“inner对js是没有用的”的具体指哪种无效,比如我如下:
<script>
	function e(){
		document.getElementById("test").innerHTML="<input type=\"button\" onclick=\"javascript:function y(){alert(123);} y();\"/>";	
	}
</script>
<input type="button" value="test_e" onclick="e();">
<div id="test"></div>
<script>

中对于y()的定义和执行也是没问题的,这也是innerHTML对js的一种“有效”。eval的话是动态的去解释执行js字符串,它跨越了浏览器对于js解释执行顺序的界限,肯定是可以的。我讨论的是浏览器对于js的加载以及解释的顺序,我还是比较希望有老鸟这方面能给予一些详细的讲解,来验证我的实验的某些细节甚至是设计思路是否正确。
1 楼 eason007 2010-06-30  
inner对js是没有用的,要用eval。

删除inner同样对js无效

相关推荐

    scriptjs异步JavaScript加载器和依赖管理器

    **script.js:异步JavaScript加载器与依赖管理器详解** 在Web开发中,JavaScript的异步加载和依赖管理是优化页面性能的关键因素。`script.js`是一个轻量级且功能强大的工具,它允许开发者实现异步加载JavaScript...

    JavaScript执行顺序

    浏览器会按照文档的结构从上到下解析和渲染页面,遇到`&lt;script&gt;`标签时,会立即执行其中的JavaScript代码或加载外部文件。例如,如果有多个`&lt;script&gt;`标签,浏览器会按照它们在HTML中的出现顺序依次执行。外部脚本...

    smallLoader:顺序加载javascript

    在Web开发中,JavaScript文件的加载速度和执行顺序对页面性能至关重要。"smallLoader"是一个轻量级的解决方案,旨在帮助开发者实现JavaScript脚本的顺序加载,确保它们按照预设的顺序正确执行。下面将详细探讨...

    stan-loader:一个非常简单的非渲染阻塞 javascript 加载器,它将按顺序加载一组库,然后在加载或错误时执行回调函数

    一个非常简单的非渲染阻塞 javascript 加载器,它将按顺序加载一组库,然后在加载或错误时执行回调函数。 将允许在 、 、 和上获得更高的分数。 它是什么/它是如何工作的 STAN Loader 是一个接受四个参数的函数; ...

    Javascript代码在页面加载时的执行顺序介绍

    在探讨JavaScript代码在网页加载过程中的执行顺序时,我们首先需要了解JavaScript在HTML文档中的几种嵌入方式,以及它们在页面加载过程中的执行行为。 一、HTML中嵌入JavaScript的方法 1. 直接将JavaScript代码...

    高性能JavaScript PDF

    7. **PDF渲染与JavaScript执行顺序**:理解PDF文档加载和JavaScript执行的顺序对于优化用户体验至关重要。JavaScript代码通常在文档加载完成后执行,因此应设计代码以适应延迟执行。 8. **调试与测试**:调试PDF中...

    javascript按顺序加载运行js方法

    首先,理解JavaScript的基本加载机制。默认情况下,浏览器会按HTML文档中`&lt;script&gt;`标签的顺序逐个下载和执行JS文件。然而,如果在`&lt;script&gt;`标签中添加了`async`或`defer`属性,情况会有所不同。 1. `defer`属性:...

    完整的arcgis for js调用天地图示例

    《全面解析:使用ArcGIS for JavaScript调用天地图的实战指南》 在现代地理信息系统(GIS)开发中,ArcGIS for JavaScript是一个强大的工具,它允许开发者构建交互式的地图应用程序。结合天地图,我们可以利用中国...

    同步加载JS文件Demo

    因此,通常只对那些必须按特定顺序执行且对页面初始渲染至关重要的脚本使用同步加载。 在本Demo中,主要关注的是如何通过一个"init.js"主入口文件来管理项目中的所有其他JavaScript文件,确保它们能被正确、有序地...

    LightningJS安全快速异步嵌入代码用于第三方Javascript交付

    LightningJS是一个专门为高效、安全地异步加载第三方JavaScript代码而设计的库。在Web开发中,优化页面加载速度和用户体验至关重要,而LightningJS正为此提供了解决方案。它通过智能加载策略,使得网页中的第三方...

    2010html执行顺序.docx

    在给定的示例中,JavaScript的执行顺序是:`alert(1)`、`alert(2)`(来自外部文件`a.js`)、`alert(3)`,以及对`&lt;input id="a"&gt;`的操作。如果在`&lt;input&gt;`元素之上放置一个`&lt;script&gt;`标签来获取`id="a"`的元素,由于...

    jsloader 异步加载js文件

    为了解决这个问题,开发者引入了异步加载(Asynchronous Loading)技术,使得JavaScript文件可以在不阻塞页面渲染的情况下加载。`JSLoader`就是这样一种工具,它允许开发者在JSP页面中异步地加载JS文件,提高页面...

    基于Vue渲染与插件的加载顺序的问题详解

    在Vue.js框架中,理解和掌握渲染与插件的加载顺序对于优化应用性能和避免出现错误至关重要。Vue渲染过程包括模板编译、虚拟DOM创建、DOM更新等步骤,而插件通常用于扩展Vue的功能,如路由管理、状态管理、全局方法等...

    JAVA培训C#后台调用前台javascript的五种方法.pdf

    在ASP.NET框架下,C#作为后台语言,有时需要调用前端的JavaScript函数来实现某些功能,例如更新用户界面或者进行复杂的交互。以下就是五种常见的C#后台调用前端JavaScript的方法: 1. **OnClientClick属性**: ...

    原生js延迟加载

    在实际应用中,我们还需要考虑到浏览器兼容性和性能优化,例如使用`requestAnimationFrame`来避免阻塞渲染,以及合理设置加载阈值以平衡用户体验和网络性能。 综上所述,原生JavaScript实现的延迟加载结合面向对象...

    调用内部JS和外部JS的演示程序

    `defer`会让脚本在HTML解析完成后、DOM加载前执行,而`async`则使脚本并行下载,不会阻塞页面渲染,但执行顺序不保证。 ```html &lt;!-- 延迟加载 --&gt; &lt;script src="script.js" type="text/javascript" defer&gt; &lt;!-- ...

    2010html执行顺序.pdf

    在HTML文档中,JavaScript的执行顺序与HTML元素的加载顺序密切相关。HTML文档的加载是从上到...此外,合理组织和管理JavaScript代码,避免全局变量污染,以及使用异步加载技术,可以帮助提高网页的响应速度和用户体验。

    javascript优先加载笔记代码

    传统的JavaScript代码在页面加载完成后执行,这可能会在很大程度上影响页面的渲染效率,特别是在包含大量JavaScript脚本的页面中。JavaScript优先加载是一种优化技术,目的是让关键的JavaScript代码在指定DOM元素...

    跟我学习javascript的异步脚本加载

    在脚本管理的过程中,开发者需要评估脚本是否会被`&lt;body&gt;`内的内联JavaScript调用,以及是否会对页面渲染产生影响。如果脚本中包含了上述元素,则可能需要调整位置或选择其他异步加载方式。 此外,对于一些特别大的...

Global site tag (gtag.js) - Google Analytics