页面完全呈现后运行 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 == 'completesetTimeout 的组合。这个想法是我想等到页面完全呈现(因此是'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 内容,直到页面呈现后?

Ionic 4 Tabs无法完全呈现

NativeScript 识别页面是不是完全呈现

在IE11中呈现时,只有在ReportViewer中完全向下滚动后才会出现水平ScrollBar

MS Edge错误地呈现页面

IE8 - 如何在内容加载后运行 jquery 代码?