0

我正在尝试根据 iFrame 中的内容通过一些 javascript 动态调整网页上 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 大小的 FF 函数。它是有效的实际脚本(没有 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 和 FF 上的工作 - 不是 chrome。如果我将它设置为 HTTPS,它可以在 chrome 和 IE 上运行——不是 FF。相同的错误“ReferenceError:未定义 FrameManager”。这到底是怎么回事?

4

2 回答 2

1

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

于 2012-12-18T09:31:42.490 回答
1

几件事:

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