【问题标题】:Javascript from file gives Uncaught ReferenceError文件中的 Javascript 给出未捕获的 ReferenceError
【发布时间】:2022-03-18 03:07:58
【问题描述】:

我正在尝试通过一些 JavaScript 根据 iFrame 中的内容动态调整网页上 iFrame 的高度。 我的问题是,当我将脚本直接放在页面上的 <script> 标记中时,它可以正常工作。当我将代码塞入一个单独的 js 文件并链接到它时,它不起作用!

<iframe id='StatusModule' onload='FrameManager.registerFrame(this)' src='http://randomdomain.dk/StatusModule.aspx'></iframe>

<script type='text/javascript' src='http://randomdomain.dk/FrameManager.js'></script>

它给了我错误:

Uncaught ReferenceError: FrameManager is not defined

这真的是真的吗?跟页面生命周期有关系吗?

附言。我猜 JavaScript 代码是无关紧要的,因为我们不能正常工作。

更新:我认为这可能与安全 http (https) 和不同的浏览器以某种奇怪的方式有关。我注意到该脚本实际上在 Firefox 中工作。或者更确切地说,我不确定它是否是脚本,或者只是 Firefox 的根据内容自动调整 iframe 大小的功能。但它并没有给我任何错误。

如果我随后将 https 添加到脚本 url 引用中,则脚本在 IE 和 Chrome 中有效 - 但在 Firefox 中无效。函数引用错误!这有点奇怪!

更新 #2: 它不是调整 iframe 大小的 Firefox 函数。它是有效的实际脚本(没有 https)。

更新 #3: JavaScript。如果我将它直接放入脚本标签中,效果很好。

var FrameManager = {
        currentFrameId: '',
        currentFrameHeight: 0,
        lastFrameId: '',
        lastFrameHeight: 0,
        resizeTimerId: null,
        init: function () {
            if (FrameManager.resizeTimerId == null) {
                FrameManager.resizeTimerId = window.setInterval(FrameManager.resizeFrames, 0);
            }
        },
        resizeFrames: function () {
            FrameManager.retrieveFrameIdAndHeight();
            if ((FrameManager.currentFrameId != FrameManager.lastFrameId) || (FrameManager.currentFrameHeight != FrameManager.lastFrameHeight)) {
                var iframe = document.getElementById(FrameManager.currentFrameId.toString());
                if (iframe == null) return;
                iframe.style.height = FrameManager.currentFrameHeight.toString() + "px";
                FrameManager.lastFrameId = FrameManager.currentFrameId;
                FrameManager.lastFrameHeight = FrameManager.currentFrameHeight;
                window.location.hash = '';
            }
        },
        retrieveFrameIdAndHeight: function () {
            if (window.location.hash.length == 0) return;
            var hashValue = window.location.hash.substring(1);
            if ((hashValue == null) || (hashValue.length == 0)) return;
            var pairs = hashValue.split('&');
            if ((pairs != null) && (pairs.length > 0)) {
                for (var i = 0; i < pairs.length; i++) {
                    var pair = pairs[i].split('=');
                    if ((pair != null) && (pair.length > 0)) {
                       if (pair[0] == 'frameId') {
                            if ((pair[1] != null) && (pair[1].length > 0)) {
                               FrameManager.currentFrameId = pair[1];
                            }
                        } else if (pair[0] == 'height') {
                            var height = parseInt(pair[1]);
                            if (!isNaN(height)) {
                                FrameManager.currentFrameHeight = height;
                                //FrameManager.currentFrameHeight += 5;
                            }
                        }
                    }
                }
            }
        },
        registerFrame: function (frame) {
            var currentLocation = location.href;
            var hashIndex = currentLocation.indexOf('#');
            if (hashIndex > -1) {
                currentLocation = currentLocation.substring(0, hashIndex);
            }
            frame.contentWindow.location = frame.src + '&frameId=' + frame.id + '#' + currentLocation;
        }
    };
    window.setTimeout(FrameManager.init, 0);

更新 #4: 好吧,我按照 ShadowWizard 和 TheZuck 的建议做了:

   <script type="text/javascript">
        var iframe = document.createElement("iframe");
        iframe.src = "http://www.randomdomain.dk/StatusWebModule.aspx";
        iframe.width = '100%';
        iframe.id = 'StatusModule';
        iframe.scrolling = 'no';
        if (iframe.attachEvent) {
            iframe.attachEvent("onload", function () {
                FrameManager.registerFrame(iframe);
            });
        } else {
                iframe.onload = function () {
                    FrameManager.registerFrame(iframe);
                };
            }
  document.getElementById('framecontainer').appendChild(iframe);                                     
        </script>

使用 HTTP 作为 URL,它在 IE 和 Firefox 上工作 - 而不是 Chrome。如果我将它设置为 HTTPS,它可以在 Chrome 和 IE 上运行 - 而不是 Firefox。同样的错误:

“ReferenceError: FrameManager 未定义”。

这是怎么回事?

【问题讨论】:

  • 你把你的脚本参考放在哪里?在 iframe 定义之下还是之上?
  • 您可能以某种方式将该函数置于窗口范围之外。
  • @MinkoGechev 都试过了。没有运气。
  • @adeno 我不确定我是否理解。我该怎么做?
  • 不是让框架使用内联 JavaScript 注册自己,而是让管理器将它们全部注册。在 JavaScript 代码中添加 onload 事件,您将在其中迭代所有 iframe 并为每个 iframe 分配 FrameManager.registerFrame

标签: javascript iframe dom-events


【解决方案1】:

几件事:

  1. 当你有两个独立的 应该同时加载的资源。你可以 通过写入日志(或文档,无论哪个有效)轻松检查这一点 为您)当两者都完成加载时(即在 iframe 动态添加时间到内容或写入日志,如果 您正在使用 chrome,也可以在外部脚本文件中执行此操作, 并查看他们是否在失败时按特定顺序发布时间)。在您的情况下,如果脚本出现在 iframe 之前,并且您没有将其标记为异步,则它应该在获取 iframe 之前加载,因此找不到 iframe 似乎很奇怪这是由于比赛条件。在这种情况下,我会赌 (3)。
  2. 假设有这样的问题(如果现在没有,当你去 进入现实世界),更好的方法是 确保两者都表现良好,以防其他先加载。在你的 情况下,我会告诉 iframe 将自身添加到局部变量 独立于脚本,并会告诉脚本检查是否 iframe 在加载时注册,之后重复 间隔,直到找到 iframe。
  3. 如果脚本加载到的页面不在同一个域中 作为 iframe(请注意,脚本来自何处并不重要 来自,它只关心页面的域是什么),(甚至相同 协议正如这里提到的那样),您将无法访问 内容,因此您将无法根据内容调整大小 内容是。我不确定 onload 方法是否被视为包装页面的一部分或内部 iframe 的一部分。
  4. 查看this question,这听起来与您的情况相关:
  5. 还有一篇关于此的有趣文章here

【讨论】:

  • 嘿 Zuck 感谢您的回答。我更新了问题(更新#4)。请检查一下 :) 我认为这可能与 HTTP/HTTPS 有关。
【解决方案2】:

我认为你的框架是在脚本之前加载的,所以当 iframe 完成加载时“FrameManager”还不存在。

【讨论】:

  • 他试图将脚本放在框架上方,但不起作用,您可以查看cmets。
  • 如果您明确提及,它会异步加载脚本...请阅读手册...阅读有关异步属性和异步脚本加载的信息...
  • 没关系,在看到你的评论被删除之前,我已经发布了评论。无论如何,花一些时间在这个领域进行研究(对于任何人)都是很好的。脚本加载和加载时间优化是阴险的,总有一些新东西要学。最好的问候。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 2023-01-23
  • 1970-01-01
相关资源
最近更新 更多