Javascript:没有"console.log",更改"document.body.onresize"不会保留

NcA*_*ams 10 html javascript events web

我正在写一个带有画布的网站.该网站有一个脚本,除了最后一行之外,每次刷新都会成功运行.当脚本结束时:

document.body.onresize = function() {viewport.resizeCanvas()}
Run Code Online (Sandbox Code Playgroud)

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

但是,当脚本结束时:

document.body.onresize = function() {viewport.resizeCanvas()}
console.log(document.body.onresize)
Run Code Online (Sandbox Code Playgroud)

"document.body.onresize" 确实发生了变化.该功能完全正常工作.

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


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


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

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

为什么"窗口"工作而"文档"仅在您首先调用"console.log"时才有效?不是线索.

在此输入图像描述

小智 3

调整事件大小:不行

大多数浏览器不支持除窗口对象之外的任何对象上的调整大小事件。根据此页面,只有 Opera 支持检测调整文档大小。您可以使用测试页面在多个浏览器中快速进行测试。另一个特别提到 body 元素上的调整大小事件的来源也指出它不起作用。如果我们查看Internet Explorer 的这些 错误报告,我们会发现在任意元素上触发调整大小事件是Internet Explorer 特有的功能,现已被删除。

Object.observe:也许在未来

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

目前的解决方案

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

<span id="editableSpan" contentEditable>Change me!</span>
Run Code Online (Sandbox Code Playgroud)

这个脚本:

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);
});

}
Run Code Online (Sandbox Code Playgroud)

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