页面完全呈现后运行 javascript
Posted
技术标签:
【中文标题】页面完全呈现后运行 javascript【英文标题】:Running javascript after page is fully rendered 【发布时间】:2012-01-26 13:22:24 【问题描述】:我正在尝试创建一个语法高亮脚本。我尝试在具有 10000 行的代码上使用我的脚本,但我看到的只是加载时的空白页。脚本完成任务后,一切都会显示出来。顺便说一句,我在 jQuery 的 ready 函数中调用了我的脚本。
$(myFunction);
脚本应在页面完全呈现后执行,即使脚本尚未完成,用户也可以实际浏览页面。 javascript 将在后台运行,因为它会一一突出显示代码,同时不会干扰页面的响应性。提前致谢。
编辑:
为了更清楚地说明这一点,我想在所有内容都“渲染”而不是“加载”之后执行代码。一切都应该已经在屏幕上可见,并且用户实际上可以看到代码在突出显示时变得栩栩如生。谢谢。
【问题讨论】:
该代码 sn-p 用于 DOM 准备好被操作时,而不是在每个资源都已加载时。不幸的是,我不知道有任何清晰且无故障的方法来检查每个元素是否已加载。 How do you execute a Javascript function when the page has fully rendered? 的可能重复项 您应该在脚本标签、webworkers 和 onload 事件中使用异步来创建 webworkers。 Webworkers 很酷,但它们并不完全受支持。我只想在你的 DOM 底部放一张图片(甚至是一张空白的透明图片),它应该是浏览器加载的最后一个东西,所以该图片的“onload”可以调用你的“highlight”函数。 【参考方案1】:我知道最初的发帖人早就离开了这个 10 岁的问题。但我希望这个答案可以帮助某人。
首先,良好的异步编程和 window.onload 的使用可能是解决方案的重要组成部分。个别实施会有所不同。
我认为,我们在这里试图克服的另一个问题是,在客户端的主线程中完成了太多的工作。除了编写更高效的代码之外,我想不出任何技巧来解决这个问题。唯一的解决方案是不在主线程上执行该工作。一种选择是在服务器上做更多的工作。
另一种选择是使用web worker 将该工作置于后台线程中。您不能直接从工作线程更新 DOM,但您仍然可以完成大部分准备工作。
如果您以前从未使用过网络工作者,请不要害怕;假设您了解 JavaScript,它们的实现速度非常快。您真正需要开始的只是new Worker()
启动后台线程,postMessage()
将数据从主线程发送到工作线程(反之亦然)和onmessage
事件处理程序用于接收数据(在任一方向)。
它就像一个纯函数,在不阻塞 DOM 的情况下运行,并在完成后用数据回调你。
这是一个示例实现,其中有一个黑色文本的初始页面呈现。与此同时,web worker 决定蓝色更好,思考了 2 秒长而艰难的时间,然后将结果报告回主线程。然后主线程更新 DOM 作为响应。
<body>
<div id="cool-div"></div>
<script>
let myData = [
"This is my sample data that I want to do a bunch of work to, such as parsing it and returning new html to render.",
];
document.getElementById(
"cool-div"
).innerHTML = `<p style="color:black">$myData</p>`;
const myWorker = new Worker("worker.js");
myWorker.onmessage = (event) =>
(document.getElementById("cool-div").innerHTML = event.data);
myWorker.postMessage(myData);
</script>
</body>
然后在worker.js中:
onmessage = (e) =>
const newData = `<p style="color:blue">$e.data</div>`;
//pretend to do hard work, then pass the result back to main thread
setTimeout(() => postMessage(newData), 2000);
;
【讨论】:
【参考方案2】:如果你还没有尝试过,9 年后……
$(document).ready(function ()
window.setTimeout('ctlEmployeeEdit.document_load()', 50);
);
我猜如果您将时间设置为 9 年毫秒,页面可能已经呈现,但这只是我的假设!
【讨论】:
页面完全加载后发生 jQuery 就绪事件。因此,由于页面已经呈现,因此通过 setTimeout 添加延迟毫无用处。事实上,该解决方案甚至根本不需要 jQuery。如果突出显示脚本只是简单地添加到页面底部,它会在页面呈现后运行。请参阅相关的 SO 帖子:***.com/a/6026730/943435【参考方案3】:window.onload 方法的问题
即使您使用 $(window).load
方法,您的荧光笔内容也可以在 $(document).ready
完成之前运行,因为到处都有很多异步回调函数。
我的方法
我使用了等待document.readyState == 'complete
和setTimeout
的组合。这个想法是我想等到页面完全呈现(因此是'complete'
),然后进一步确保$(document).ready
JQuery 包装器内容已经完成(因此是setTimeout
)。
以下是我将如何解决您的问题,假设 200 毫秒足以让 $(document).ready(function() /*...*/ );
中的所有内容完成。
function highlighterAction()
// actually do the highlighting stuff here
function highlighter()
/*
The short pause allows any required callback functions
to execute before actually highlighting, and allows
the JQuery $(document).ready wrapper to finish.
*/
setTimeout(function()
highlighterAction();
, 200);
/*
Only trigger the highlighter after document fully loaded. This is
necessary for cases where page load takes a significant length
of time to fully load.
*/
if (document.readyState == 'complete')
highlighter();
else
document.onreadystatechange = function ()
if (document.readyState === "complete")
highlighter();
【讨论】:
【参考方案4】:不确定究竟要引入多少数据...但是如果在文档准备就绪时运行 jquery ajax 调用并使用 completed 方法运行荧光笔功能怎么办?如果有很多数据,页面加载会比较慢。
无论如何都想和这个类似
$.ajax(
type: "POST",
url: "Where data is actually stored",
data: ChannelTypeID: ChannelTypeID ,
datatype: "html",
beforeSend: function ()
,
success: function (myHTML)
$('body').html(myHTML);
,
error: function ()
alert("Ajax request was unsuccessful");
,
complete: function ()
highlighterFunction();
);
complete 方法指定 AJAX 请求完成时要运行的函数。希望成功能够尽早触发以推送数据并让您的亮点正常工作
【讨论】:
您好,要高亮的代码已经在pre标签内的页面中了。【参考方案5】:你的意思是在所有图片都加载之后?
我认为window.onload 就是您要找的东西
window.onload = function()
//dom not only ready, but everything is loaded
;
编辑
根据 Chris 的评论,这里是 jQuery 方式:
$(window).load(function()
//dom not only ready, but everything is loaded
);
【讨论】:
jQuery 的做法是 $(window).load(function()...); 解决方案无效。加载 javascript 时页面仍为空白。还有其他解决方案吗?我编辑了我的帖子以强调我想要发生的事情。谢谢。 好的,我正在寻找的术语是非阻塞 javascript。 javascript 不应阻止浏览器的呈现和响应。上面的解决方案是在页面加载后执行代码,但仍然阻塞页面的渲染。有任何想法吗?谢谢。 @RueLeonheart - 我不认为这是可能的,虽然不是 100% 确定$(window).load(function() ...
已被弃用。你必须使用$(window).on('load', function() ...);
。 More info here.以上是关于页面完全呈现后运行 javascript的主要内容,如果未能解决你的问题,请参考以下文章
如何推迟加载 UpdatePanel 内容,直到页面呈现后?