javascript DOM object (window) extended 属性 is null on page reload after being idle

javascript DOM object (window) extended property is null on page reload after being idle

我有一个自定义扩展 属性 附加到 JavaScript 中的 window 对象,如下所示:

Community.js

(function (window, document, $) {
    'use strict';
    var containerScrollPositionOnHideList = [];
    var scrollToTopOnShowContainerList = [];
    var userProfileInfo = {};

    window.Community = $.extend({
        //init
        init: function () {
            var Site = window.Site;
            Site.run();
            this.enableHideShowEventTrigger();
        },
    setUserInfo: function (userObj) {
            if (UtilModule.allowDebug) { debugger; }
            window.localStorage.setItem('userInfo', JSON.stringify(userObj));
            var d = new $.Deferred();
            $.when(this.initUserProfile(userObj.UserId)).done(function () {
                d.resolve("ok");
            });
        },
    getUserInfo: function () {
            var userJson = window.localStorage.getItem('userInfo');
            var userObj = JSON.parse(userJson);
            return userObj;
        },  
})(window, document, jQuery);   

问题是当我刷新页面时,这个扩展 属性 window.Community 在某些情况下为空,我将在下面描述代码流。

这里是 JavaScript 中的一个模块,即使在每次刷新页面时都会缓存脚本,因为我的代码严重依赖于 javascript 调用,所以我只是启用它来进行当然我还在写代码页每次都重新加载,代码如下:

Util.js

var UtilModule = (function () {
    var allowDebug = false;
    var currentVersion = 0;
    var properlyLoadScript = function (scriptPath, callBackAfterLoadScript) {
        //get the number of `<script>` elements that have the correct `src` attribute
        //debugger;
        var d = $.Deferred();
        $('script').each(function () {
            console.log($(this).attr('src'));
        });
        if (typeof window.Community == 'undefined') {
            //debugger;
            console.log('community was undefined till this point');
            //the flag was not found, so the code has not run
            $.when(forceReloadScript(scriptPath)).done(function () {
                callBackAfterLoadScript();
                d.resolve("ok");
            });
        }
        else {
            console.log('Community loaded already and running now : ' + scriptPath);
            callBackAfterLoadScript();
        }
        return d.promise();
    };
    var forceReloadScript = function (scriptPath) {
        if (UtilModule.allowDebug) { debugger; }
        var d = $.Deferred();
        initCurrentVersion();
        var JSLink = scriptPath + "?version=" + currentVersion;
        var JSElement = document.createElement('script');
        JSElement.src = JSLink;
        JSElement.onload = customCallBack;
        document.getElementsByTagName('head')[0].appendChild(JSElement);
        function customCallBack() {
            d.resolve("ok");
        }
        return d.promise();
    };
    var enableDebugger = function () {
        allowDebug = true;
    };
    var disableDebugger = function () {
        allowDebug = false;
    };
    var debugBreakPoint = function () {
        if (allowDebug) {
                    }
    };
    var initCurrentVersion = function () {
        if (currentVersion == 0) {
            var dt = new Date();
            var ttime = dt.getTime();
            currentVersion = ttime;
        }
    };
    var getCurrentVersion = function () {
        return currentVersion;
    };
    return {
        forceReloadScript,
        properlyLoadScript,
        enableDebugger,
        disableDebugger,
        debugBreakPoint,
        allowDebug,
        getCurrentVersion
    };

})();

注意:我已将延迟对象设置为仅在成功调用 JSElement.onload 时才解析。此步骤仅用于测试目的,以确保在到达调用我遇到错误的方法的点之前我没有遗漏任何东西。

之后,我在布局文件中使用 UtilModule 加载脚本的代码如下所示:

_Layout.cshtml

<script src = "~/Scripts/Application/Modules/Util.js" ></script>
<script>

$.when(
    UtilModule.properlyLoadScript('/Scripts/Application/Community.js', () => {
    // Community.init() was supposed to be called here but i was still getting the error so i implemented this using promise that is returned from properlyLoadScript and call Community.init() further in .done callback to make sure that script is properly loading till this point.
    //window.Community.init();
    })
).done(function() {
    window.Community.init();
});
</script>
@RenderSection("scripts", required: false)

现在转到我的主文件,我的索引文件正在执行,其中父布局为 (_layout.chsmtl)

Index.cshtml

@{
    ViewBag.Title = "My Blog";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<article id="BlogPage" style="margin: 5px;">
</article>
@section scripts{


  <script type="text/javascript">
    $(document).ready(function () {
      $.when(UtilModule.properlyLoadScript('/Scripts/Application/Modules/Blog.js', () => {
      })).done(function () {
        BlogModule.init();
      });
    });

    //});
  </script>
}

据我所知,@section 脚本只有在布局页面中的所有脚本都首先加载后才会执行,因此似乎是一个安全的地方来初始化依赖于 _Layout.HTML 中某些脚本的代码文件并进一步包含在 $(document).ready() 中用于测试,以确保此脚本在其他所有内容加载后加载。

注意:我 运行 在 chrome 中所有这些代码都处于隐身模式,因此当此代码处于 运行

时,不会缓存任何内容

现在我的 Blog.js 文件如下所示

var BlogModule = (function () {
    var moduleReference = this;
    var PageId = "#BlogPage ";
    var currentUser;
    var BlogPostList = [];
    var blogPostInfo = {};

    //init
    var init = function () {
        if (UtilModule.allowDebug) { debugger; }
        //This is where the problem happens
        console.log(window.Community);
        console.log(window.Community.getUserInfo());
        currentUser = window.Community.getUserInfo();
        initBlogInformation();
        //window.Community.registerModule(BlogModule);
        if (Object.keys(window.Community.getUserProfileObject()) <= 0) {
            $.when(window.Community.initUserProfile(currentUser.UserId)).then(function () {
                $.when(initBlogInformation()).done(function () {
                    //debugger;
                    console.log(BlogPostList);
                    window.WidgetManager.populateWidget(PageId, moduleReference);
                    loadBlogPostWidget();
                    loadBlogViewWidget();
                    loadBlogCommentsWidget();
                });
            });
        }
        else {
            $.when(initBlogInformation()).done(function () {
                window.WidgetManager.populateWidget(PageId, moduleReference);
                loadBlogPostWidget();
                loadBlogViewWidget();
                loadBlogCommentsWidget();
            });
        }
    };
    var loadBlogIndexMenuWidget = function () {
        if (UtilModule.allowDebug) { debugger; }
    };
    var loadBlogPostWidget = function () {
        var widgetOptions = {};
        widgetOptions.type = "BlogPostWidget";
        widgetOptions.container = PageId + "#BlogPostWidgetContainer";

        var settings = {};
        settings.UserId = 1;
        widgetOptions.settings = settings;

        window.WidgetManager.loadWidget(widgetOptions);
    }
    var loadBlogViewWidget = function () {
        var widgetOptions = {};
        widgetOptions.type = "BlogViewWidget";
        widgetOptions.container = PageId + "#BlogViewWidgetContainer";

        var settings = {};
        settings.UserId = 1;
        widgetOptions.settings = settings;

        window.WidgetManager.loadWidget(widgetOptions);
    };

    var loadBlogCommentsWidget = function () {
        var widgetOptions = {};
        widgetOptions.type = "BlogCommentsWidget";
        widgetOptions.container = PageId + "#BlogCommentsWidgetContainer";

        var settings = {};
        settings.UserId = 1;
        widgetOptions.settings = settings;

        window.WidgetManager.loadWidget(widgetOptions);
    };

    var initBlogList = function () {
        $.when(getBlogPosts()).then(function (results) {
            if (UtilModule.allowDebug) { debugger; }
            BlogPostList = results.Record;
            console.log(BlogPostList);
        });
    };
    var getBlogPosts = function () {
        if (UtilModule.allowDebug) { debugger; }
        var d = new $.Deferred();

        var uri = '/Blog/GetBlogPosts?userId=' + currentUser.UserId;

        $.post(uri).done(function (returnData) {
            if (UtilModule.allowDebug) { debugger; }
            if (returnData.Status == "OK") {
                BlogPostList = returnData.Record;
                BlogPostList.map(x => {
                    if (UtilModule.allowDebug) { debugger; }
                    x.UserName = window.Community.getUserProfileObject().UserName;
                    if (x.Comments != null) {
                        x.CommentsObject = JSON.parse(x.Comments);
                        x.CommentsCount = x.CommentsObject.length;
                    }
                });
                console.log(returnData.Record);
                d.resolve("ok");
            } else {
                window.Community.showNotification("Error", returnData.Record, "error");
                d.resolve("error");
            }

        });

        return d.promise();
    };
    var initBlogInformation = function () {
        //debugger;
        var d = $.Deferred();
        getBlogPosts().then(getBlogModelTemplate()).then(function () {
            d.resolve("ok");
        });
        return d.promise();
    };
    //Get Blog Model
    var getBlogModelTemplate = function () {
        var d = new $.Deferred();

        var uri = '/Blog/GetBlogModel';

        $.post(uri).done(function (returnData) {
            blogPostInfo = returnData.Record;
            d.resolve("ok");
        });
        return d.promise();
    };


    return {
        init: init,
    };

})();

我在下面突出显示的错误

所以问题出在 BlogModule 的初始化函数中,即 BlogModule.init() 页面空闲时间过长,我重新加载它时出现以下错误: 不能打电话 window.Community.getUserInfo() of undefined 表示社区未定义 几次刷新后,问题就不会发生,除非我更改 js 文件的合理代码部分,以便浏览器再次重新编译,或者浏览器空闲时间太长,我无法理解是什么触发了这个问题。

下面是来自控制台的日志

p.s。如果我使用 f5 刷新页面,错误会更频繁地发生,但如果我使用 ctrl + f5

刷新页面,则很少发生

请提供任何帮助都非常有价值

回答我自己的问题,花了一段时间才弄清楚,但我只是在修复以下功能时犯了一个小错误 Util.js 为我修复了它

  var properlyLoadScript = function(scriptPath, callBackAfterLoadScript) {
      //get the number of `<script>` elements that have the correct `src` attribute
      //debugger;
      var d = $.Deferred();
      $('script').each(function() {
          console.log($(this).attr('src'));
      });
      if (typeof window.Community == 'undefined') {
          //debugger;
          console.log('community was undefined till this point');
          //the flag was not found, so the code has not run
          $.when(forceReloadScript('/Scripts/Application/Community.js')).done(function() {
              //debugger;
              $.when(forceReloadScript(scriptPath)).done(function() {
                  callBackAfterLoadScript();
              });
              d.resolve("ok");
          });
      } else {
          console.log('Community loaded already and running now : ' + scriptPath);
          $.when(forceReloadScript(scriptPath)).done(function() {
              callBackAfterLoadScript();
          });
      }
      return d.promise();
  };