Javascript: изменение "document.body.onresize" не выполняется без "console.log"

Я пишу веб-сайт с холстом. На веб-сайте есть script, который успешно запускается при каждом обновлении, за исключением строки в конце. Когда script заканчивается:

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

"document.body.onresize" не изменяется. (Я дважды проверял в консоли Chrome javascript: Ввод "document.body.onresize" возвращает "undefined".)

Однако, когда script заканчивается:

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

"document.body.onresize" делает изменение. Функция работает точно так, как должна.

Я не могу объяснить, почему эти два функционально идентичных фрагмента кода имеют разные результаты. Может ли кто-нибудь помочь?


Изменить. Насколько я могу судить, "document.body" ссылается на правильный "document.body". Когда я вызываю console.log(document.body) непосредственно перед назначением document.body.onresize, печатается правильный HTML.


Изменить 2: Решение (вроде)

Когда я заменил "окно" для "документа", функция viewize "resizeCanvas" вызывалась без сбоев каждый раз при изменении размера окна.

Почему "окно" работает, когда "документ" работает, только если вы сначала вызываете "console.log"? Не подсказка.

enter image description here

Ответ 1

События изменения размера: no go

Большинство браузеров не поддерживают события изменения размера на чем-либо, кроме объекта окна. Согласно этой странице, только 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>

И этот script:

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 и, например, функции watch в структуре AngularJS. Это не идеально, потому что со многими такими проверками у вас будет много кода, работающего каждые 100 мс. Кроме того, любое действие будет отложено на 100 мс. Вы могли бы улучшить это, используя requestAnimationFrame вместо setInterval. Таким образом, обновление будет замечено всякий раз, когда браузер перерисовывает вашу веб-страницу.

Ответ 2

Что вы можете сделать, так это то, что если вы точно знаете, какое конкретное действие вызывает изменение размера вашего элемента, который не изменяет размер полного окна, вы можете вызвать событие изменения размера, чтобы ваш браузер пересчитывал все div (если по делу браузер не запускает событие правильно).

С помощью JQuery:

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

С другой стороны, если у вас есть действие, которое изменяет размер элемента, вы всегда можете удерживать его, чтобы обрабатывать следующую логику.

Ответ 3

<script>
    function body_OnResize() {
      alert('resize');
    }
</script>

<body onresize="body_OnResize()"></body>