DOM完成后运行脚本

时间:2019-04-16 21:23:15

标签: javascript html

我正在根据使用XMLHttpRequest()导入的外部文件的标题动态创建要放置在菜单栏上的菜单项。当我浏览不同页面时,该菜单栏会动态更新。

这很好。 我将每张文档以一叠纸牌的形式加载到一个单独的div元素中,并隐藏除setVisible()页面之外的所有页面。

 window.onload = function(){
     loadContent("personalinfo");
     loadContent("academicalinfo");
     loadContent("employmentinfo");
     setVisible("academicalinfo");
     /*setMenues("academicalinfo");*/
}

setVisible()的最后一个动作是调用setMenues(),它负责读取所述主窗口的所有标题。这也很好用。

function loadMenues(file) {
     var rightmenu = document.getElementById("right-menu");
     while(rightmenu.firstChild){
         rightmenu.removeChild(rightmenu.firstChild);
     }
     [].forEach.call(document.getElementById(file).children,
         function(custompaddingchild) {
             /* searching for h1 and adding menu items happens here */
         }
     );

当尚未加载DOM元素(如页面加载)时,就会出现问题。由于在页面完全呈现之前文档元素中没有ElementsById(file),因此无法在加载时添加菜单项。

我尝试在窗口的“ load”事件和文档上添加EventListener,我尝试在主页正文的末尾以及on onload=参数上执行该函数(<body>)的运行(甚至在捕获子页面之前运行,使我留有空白页面而不是实际内容),但看起来,在页面完全加载之后似乎没有任何事情发生。

在运行功能之前添加2秒的延迟不是有效的解决方案。此外,在onload函数上添加延迟不会影响结果,只会将加载时间增加两秒钟。

单击任何更新菜单的菜单即可正常工作。唯一的问题是onload。

<div class="menu-item" onclick="setVisible('personalinfo');"><span>Personal information</span></div>

如何确定页面将setVisible()函数延迟到呈现页面之后?我发现的所有来源都声称在呈现页面之后触发了“加载”事件,但就我而言似乎并未触发。 DOMContentLoaded事件也未触发,但我怀疑我不希望发生此事件。相反,click事件或窗口上的scroll事件确实可以正确触发。

Mozilla, Window: load event

Javascript.info, Page: DOMContentLoaded, load, beforeunload, unload

编辑:根据请求,这里是loadContent():

function loadContent(file) {
        var request = new XMLHttpRequest();
        request.open("GET", file+".html?_=" + new Date().getTime());
        request.onreadystatechange=function(){
                var loadedcontent = request.responseText;
                document.getElementById(file).innerHTML = loadedcontent;
        }
        request.send();
}

编辑2:

完整代码位于https://github.com/mazunki/portfolioweb-stackoverflowquestion

3 个答案:

答案 0 :(得分:2)

You need to use promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Try this

function loadContent(file) {
    return new Promise(function (resolve, reject) {
        var request = new XMLHttpRequest();
        request.open("GET", file+".html?_=" + new Date().getTime());
        request.onreadystatechange=function(){
            var loadedcontent = request.responseText;
            document.getElementById(file).innerHTML = loadedcontent;

            resolve();
        }
        request.send();
    });
}

window.onload = function(){
    // when you finish all the content loading
    Promise.all([
        loadContent("personalinfo"),
        loadContent("academicalinfo"),
        loadContent("employmentinfo")
    ]).then(function() {
        // Load menu
        setVisible("academicalinfo");
        /*setMenues("academicalinfo");*/
    })
}

答案 1 :(得分:0)

Sorry, but you tried to use the "library" https://github.com/ded/domready ? I think that is the simpliest solutuion for you.

Then you code would be:

function loadMenues(file) {
    domready(function () {
        var rightmenu = document.getElementById("right-menu");
        while(rightmenu.firstChild){
            rightmenu.removeChild(rightmenu.firstChild);
        }
        [].forEach.call(document.getElementById(file).children,
            function(custompaddingchild) {/* searching for h1 and adding menu items happens here */ }
        );
    })
}

答案 2 :(得分:0)

虽然这只是一个后备解决方案,并且在慢速的网络连接上不可靠,但我通过将以下内容放入名为<script src="menuhandling.js" type="text/javascript" defer></script>的menuhandling.js文件中来解决了该问题:

setTimeout(function(){
    setVisible("personalinfo")
    /*setMenues("personalinfo")*/
},500) // half a second
{p> loadContent()stackhandling.js中的所有文件调用,没有延迟,并且没有document.onloadwindow.onload