简体   繁体   English

异步脚本不可访问

[英]Asynchronous script not accessible

I am loading a script that I created asynchronously to help prevent slowing down the site. 我正在加载异步创建的脚本,以帮助防止降低网站速度。 I'm unable to call the class Class.track({"some_param":"some_data"}) due to it not being available yet. 由于无法使用,因此无法调用Class.track({“ some_param”:“ some_data”})类。 How can I achieve asynchronous loading and having the ability to call the class? 如何实现异步加载并具有调用类的能力?

The code for loading in the js is below, it's occurring before the closing body tag and the Class.track is getting called below it. js中的加载代码如下,它发生在关闭body标记之前,而Class.track在其下面被调用。

<script type="text/javascript">

    (function() {
        function async_load(){
            var api_id = "XXXXXXXXX";
            var s = document.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://site.com/script.js?id=' + api_id;
            var x = document.getElementsByTagName('script')[0];
            x.parentNode.insertBefore(s, x);
         }
    if (window.attachEvent)
        window.attachEvent('onload', async_load);
    else
        window.addEventListener('load', async_load, false);
    })();

    Class.track("page_view", {"page":"plans"});
</script>

Edit 编辑

Took the comment from Dan and the answer from TJ and decided to modify it, below is what I came up with, hoping this will help someone else. 采纳了Dan的评论和TJ的回答,并决定对其进行修改,以下是我提出的内容,希望这对其他人有所帮助。

<script type="text/javascript">
    var _Class = new function(){
        var items = [];

        this.track = function(type, params){
            params = params || {};
            items.push({"type":type, "params":params});
        }

        this.get = function(){
            return items;
        }

    };

    var Class = _Class;

    (function() {
        function async_load(){
            var api_id = "XXXXXXXXX";
            var s = document.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://site.com/script.js?id=' + api_id;
            s.onload = function(){
                var items = _Class.get();
                Class.trackBatch(items);
            };
            var x = document.getElementsByTagName('script')[0];
            x.parentNode.insertBefore(s, x);
         }
    if (window.attachEvent)
        window.attachEvent('onload', async_load);
    else
        window.addEventListener('load', async_load, false);
    })();

    Class.track("page_view", {"page":"plans"});
</script>

In all major current browsers, the script element's onload can be used: 在当前所有主要的浏览器中,都可以使用script元素的onload

s.onload = function() {
    /* ...this is called when the script is loaded, so `Class` should
       be available...
    */
    Class.track("page_view", {"page":"plans"});
};

In older versions of IE, you had to use onreadystatechange instead and check that the element's readyState property was the string "complete" . 在旧版本的IE中,您必须改用onreadystatechange并检查元素的readyState属性是否为字符串"complete"

Alternately, of course, you can use setTimeout or setInterval to poll for a global symbol ( Class , in your case, I suspect) you create (via typeof , eg if (typeof Class === "undefined") { /* ...schedule another check in a few milliseconds... */ } ). 当然,您也可以使用setTimeoutsetInterval来轮询创建的全局符号( Class ,我怀疑是您的情况)(通过typeof ,例如if (typeof Class === "undefined") { /* ...schedule another check in a few milliseconds... */ } )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM