通过DOM插入执行的JavaScript加载 [英] Executing javascript loaded via DOM insertion

查看:132
本文介绍了通过DOM插入执行的JavaScript加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的东西,将一个小部件添加到客户的网站,我想异步加载JS我,以免阻挡客户的页面加载速度。我一直在阅读了很多关于这个主题,并一直在努力实现在此建议作为我的项目的模式十分相似:

I'm working on something that will add a widget to a customer's site, and I want to load my js asynchronously so as not to block the customer's page loading. I've been reading a lot of threads about this, and have been trying to implement the pattern suggested here as my project is very similar:

http://friendlybit.com/js/lazy-loading-asyncronous-javascript

我的问题是,在我的动态加载JavaScript文件中的code只是没有得到执行。很抱歉,如果这似乎是一个重复的问题,但我已经花了几个小时的搜索和尝试略有不同的技巧,我读过许多职位,包括这些计算器的问题:

The problem I have is the code in my dynamically-loaded javascript file just doesn't get executed. Sorry if this seems to be a duplicate question, but I've spent hours searching and trying slightly different techniques, and I've read numerous posts including these stackoverflow questions:

  • Load javascript async, then check DOM loaded before executing callback
  • Load jQuery in a js, then execute a script that depends on it
  • Loading scripts dynamically

但我仍然在努力使这项工作,所以我希望如果我问的问题直接有人在这里也许能帮助我!

but I'm still struggling to make this work, so I was hoping if I ask the question directly someone here might be able to help me out!

我目前得到了下面的一个很基本的测试;显然有很多更在我的真实脚本怎么回事,但我只需要了解这里发生了什么(或者,其实,有什么不发生)。

I've currently got the following as a really basic test; obviously there's a lot more going on in my real script, but I just need to understand what's happening here (or, in fact, what's not happening).

所以在我的code文件test.js我只是有:

So in my code file "test.js" I simply have:

run_test = function () {
    alert('hello from test');
};

然后在页面上我有:

then on the page I have:

(function () {
     load_test = function () {
        var t = document.getElementsByTagName('script')[0];
        var s = document.createElement('script');
        s.type = 'text/javscript';
        s.async = true;
        s.src = 'test.js';

        s.onload = s.readystatechange = function () {
            if (run_test) run_test();

            s.onload = null;
            s.onreadystatechange = null;
        };

        t.parentNode.insertBefore(s, t);
    };

    load_test();
})();

我已经尝试了几种变体这一点 - 我试图消除s.async =真只是为了看它是否有差别,但事实并非如此。我本来以下,而不是load_test();,所建议的第一篇文章,我提到:

I've already tried several variations on this - I've tried removing "s.async = true" just to see if it makes a difference, but it doesn't. I originally had the following instead of "load_test();", as suggested in the first post I mentioned:

window.attachEvent ? window.attachEvent('onload', load_test) : window.addEventListener('load', load_test, false);

但结果总是相同的,我从来没有看到消息你好,从测试。事实上我甚至可以把警报在load_test功能 - 如果我把警报只是行s.onload = s.readystatechange ..之前,我看到这样的信息,但从来没有看起来的onload函数内的报警。所以这样看来,在动态添加脚本的onload永远不会触发。

but the result is always the same, I never see the message "hello from test". In fact I can even put alerts in the load_test function - if I put an alert just before the line "s.onload = s.readystatechange .." I see that message, but an alert within that onload function never appears. So it would appear that the dynamically added script's onload never fires.

顺便说一句题外话 - 可能会或可能不相关,但我一般测试在Firefox,如果我看在Firebug的HTML,我看剧本test.js已经加载,但如果我展开我的节点刚看到消息重新加载页面以获取源......。不要紧,多少次我重新载入页面,我看不到code。我曾尝试在其他浏览器的测试结果相同。

BTW as an aside - may or may not be relevant, but I generally test in Firefox, and if I look at the html in firebug, I see the test.js script has been loaded, but if I expand that node I just see the message "Reload the page to get source for ...". Doesn't matter how many times I reload the page, I can't see the code. I have tried testing in other browsers with the same results.

不禁感慨,我在这里失踪的东西根本;任何帮助将非常AP preciated!

Can't help feeling I'm missing something fundamental here; any help would be very much appreciated!

皮特

感谢所有的投入。

@zzzzBov,感谢为例,虽然我不知道我完全理解还是 - 我认为的onload将剧本后一旦开火完成加载,以同样的方式连接code到onload事件网页的事件。我的的onreadystatechange的理解是,这是刚好赶上了同样的事情在IE浏览器。

@zzzzBov, thanks for the example, although I'm not sure I completely understand still - I thought that "onload" would fire once after the script finishes loading, in the same way as attaching code to the onload event of the page. My understanding of "onreadystatechange" was that it was just to catch the same thing in IE.

在回答您的意见,新的脚本插入到页面的头(使用insertBefore语句)原始脚本块之前权(假设原来的脚本块是在头部,这是)。

In response to your comments, the new script is inserted in the head of the page (with the insertBefore statement) right before the original script block (assuming the original script block is in the head, which it is).

关于test.js路径,我省略了路径只是以简化的例子。我的脚本路径是绝对正确的;我可以通过脚本实际上是添加(头部)看萤火虫。

With regard to the test.js path, I omitted the path just to simplify the example. My path to the script is definitely correct; I can see via firebug that the script is actually added (to the head).

我的问题是,加载脚本之后,它根本无法运行,但我觉得我其实打一些缓存的问题,因为我已经得到了这方面的工作用我上面贴的第一个链接这里描述的(模式又是很好的措施: http://friendlybit.com/js/lazy-loading- asyncronous的JavaScript / )。

My problem was that after the script loaded, it simply failed to run, but I think I was actually hitting some caching problems as I've since got this working using the pattern described in the first link I posted above (here it is again for good measure: http://friendlybit.com/js/lazy-loading-asyncronous-javascript/).

所以,我的code是这样的:

So my code is something like this:

(function () {
    var addscript = function () {
        var h = document.getElementsByTagName('head')[0],
            s = document.createElement('script');
        s.type = "text/javascript";
        s.async = true;
        s.src = "myscript.js";
        h.appendChild(s);
    };
    window.attachEvent ? window.attachEvent('onload', addscript) : 
        window.addEventListener('load', addscript, false);
})();

如果您检查该文章的评论,我认为这是地方解释了为什么这是一个好主意,还包括s.async =真,即使在这种情况下,脚本被附加到窗口onload事件。

If you check the comments on that post, I think it's explained somewhere why it's a good idea to still include "s.async = true" even though in this case the script is attached to the window onload event.

我的真正的主脚本实际上确实需要jQuery的,所以我觉得我的最终解决方案将使用类似这样来加载jQuery的,那么一旦我知道的加载,让jQuery的做加载任何其他脚本,我需要工作

My "real" main script does actually require jQuery, so I think my eventual solution will be to use something like this to load jQuery, then once I know that's loaded, let jQuery do the work of loading any other scripts I need.

您的帮助再次感谢。

皮特

推荐答案

您已经得到了你的脚本的几个问题。这里有一个,应该工作。

You've got a few issues with your script. Here's one that should work.

function loadScript(src, callback)
{
  var s, r;
  r = false;
  s = document.createElement('script');
  s.type = 'text/javascript';
  s.src = src;
  s.onload = s.onreadystatechange = function() {
    //console.log( this.readyState ); //uncomment this line to see which ready states are called.
    if ( !r && (!this.readyState || this.readyState == 'complete') )
    {
      r = true;
      callback();
    }
  };
  document.body.appendChild(s);
}

load_test 函数的问题是,它会调用 RUN_TEST()新的脚本执行前。你的脚本将删除的onload 的onreadystatechange 在第一事件回调的onreadystatechange 事件通常是加载

The issue with your load_test function is that it'll call run_test() before the new script has executed. Your script will remove the onload and onreadystatechange event callbacks at the first onreadystatechange event which is typically loading.

此外,异步应该是不必要的,因为新添加的脚本将在该月底插入 document.body的可以是任何地方。如果您想在页面的其余部分之后加载脚本,然后等待页面的其余部分加载( body.onload document.onreadystatechange )之前调用 loadScript

Also, async should be unnecessary, as the newly added script will be inserted at the end of the document.body wherever that may be. If you'd like to load the script after the rest of the page, then wait for the rest of the page to load (body.onload or document.onreadystatechange) before calling loadScript.

你的脚本最大的问题听起来像是 test.js 在它被称为路径不存在。确保加入<脚本类型=文/ JavaScript的SRC =test.js>< / SCRIPT> 内嵌实际工作

The biggest issue with your script sounds like test.js doesn't exist at the path it's being called. Make sure that adding <script type="text/javascript" src="test.js"></script> inline actually works.

这篇关于通过DOM插入执行的JavaScript加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆