【问题标题】:Javascript: Changing "document.body.onresize" does not take hold without "console.log"Javascript:没有“console.log”,更改“document.body.onresize”不会生效
【发布时间】:2014-09-03 06:14:37
【问题描述】:

我正在编写一个带有画布的网站。该网站有一个脚本可以在每次刷新时成功运行,除了最后一行。当脚本结束时:

document.body.onresize = function() {viewport.resizeCanvas()}

“document.body.onresize”没有改变。 (我在 Chrome 的 javascript 控制台中仔细检查过:输入“document.body.onresize”会返回“undefined”。)

但是,当脚本结束时:

document.body.onresize = function() {viewport.resizeCanvas()}
console.log(document.body.onresize)

“document.body.onresize”确实改变了。该功能完全按照应有的方式工作。

我无法解释为什么这两个功能相同的代码会产生不同的结果。有人可以帮忙吗?


编辑:据我所知,“document.body”指的是正确的“document.body”。当我在分配document.body.onresize 之前调用console.log(document.body) 时,会打印正确的HTML。


编辑 2:一种解决方案(有点)

当我用“window”替换“document”时,每次调整窗口大小时都会调用视口的“resizeCanvas”函数。

为什么“window”有效,而“document”只有在你先调用“console.log”时才有效?一点头绪都没有。

【问题讨论】:

  • 您的脚本是否与以括号开头的其他内容连接?始终使用分号。 (另外,window.onresize 不是更……常见吗?)
  • 不是,而是很好的建议。好消息是“window.onresize”实际上完全解决了这个问题:D 谢谢。但我仍然很好奇,这是我遇到过的最奇怪的错误之一
  • body.resize 中有一个错字(缺少on)。也许你的实际代码也有这样的东西?
  • documentdocument.body 未调整大小。 window 已调整大小。所以,我想你想要的是window.onresize
  • 你的函数没有返回值,所以它应该返回undefineddocument.body.onresize 的值是一个函数,document.body.onresize() 的值是 undefined,因为它不返回任何内容。另外,我认为@bergi 是在反驳您写.resize 而不是.onresize 的事实,而不是指document.body 是否是有效的参考。

标签: javascript html events web


【解决方案1】:

调整事件大小:不行

大多数浏览器不支持窗口对象以外的任何东西上的调整大小事件。根据this page 的说法,只有 Opera 支持检测调整大小的文档。您可以使用test page 在多个浏览器中快速测试它。 Another source 提到了 body 元素上的调整大小事件,还特别指出它不起作用。如果我们查看 Internet Explorer 的 these bug 报告,我们会发现在任意元素上触发调整大小事件是 Internet Explorer 独有的功能,已被删除。

Object.observe:也许在未来

已经提出了一种更通用的确定属性更改的方法,并且很可能会跨浏览器实现:Object.observe()。您可以观察任何属性的更改并在发生这种情况时运行函数。这样,您可以观察元素,并且当任何属性(例如 clientWidth 或 clientHeight)发生变化时,您都会收到通知。它目前仅适用于 Chrome 并打开了实验性 Javascript 标志。另外,它是越野车。我只能让 Chrome 通知我在 Javascript 中更改的属性,而不是浏览器更改的属性。实验材料;将来可能会也可能不会。

当前解决方案

目前,您将不得不进行脏检查:将您要监视的属性的值分配给一个变量,然后检查它是否每 100 毫秒更改一次。例如,如果您在页面上有以下 HTML:

<span id="editableSpan" contentEditable>Change me!</span>

还有这个脚本:

window.onload = function() {

function watch(obj, prop, func) {
    var oldVal = null;
    setInterval(function() {
        var newVal = obj[prop];
        if(oldVal !=  newVal) {
            var oldValArg = oldVal;
            oldVal = newVal;
            func(newVal, oldValArg);
        }
    }, 100);
}

var span = document.querySelector('#editableSpan');

// add a watch on the offsetWidth property of the span element

watch(span, "offsetWidth", function(newVal, oldVal) {
    console.log("width changed", oldVal, newVal);
});

}

这与 Object.observe 的工作方式类似,例如 AngularJS 框架中的 watch 函数。这并不完美,因为通过许多此类检查,您将每 100 毫秒运行大量代码。此外,任何操作都将延迟 100 毫秒。您可以通过使用 requestAnimationFrame 而不是 setInterval 来改进这一点。这样,每当浏览器重绘您的网页时,都会注意到更新。

【讨论】:

  • 我认为 Resize events: no go 部分无效。在大多数浏览器中,附加到body 的“属性”事件侦听器也将附加到window。在 IE9、Chrome 36、FF 21 中测试。作为证明 - test pageWebKit 项目中。
  • 有趣。这应该足以让开发人员感到困惑...... ;) 当然,这仍然意味着您无法检测到身体的大小调整。但至少你可以认为你做到了。
  • Object.observe() 现在支持 Chrome :)
【解决方案2】:

您可以做的是,如果您确定哪些特定操作会触发您的元素调整大小而不调整整个窗口的大小,您可以触发调整大小事件,以便您的浏览器重新计算所有 div(如果按这种情况浏览器未正确触发事件)。

使用 Jquery:

$(window).trigger('resize');

另一方面,如果您有一个调整元素大小的操作,您可以随时从该操作中保持以处理其他后续逻辑。

【讨论】:

    【解决方案3】:
    <script>
        function body_OnResize() {
          alert('resize');
        }
    </script>
    
    <body onresize="body_OnResize()"></body>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-16
      • 2011-10-17
      • 1970-01-01
      • 2019-08-31
      • 2016-03-30
      • 1970-01-01
      相关资源
      最近更新 更多