Теги объекта Chrome загружаются несколько раз при установке позиции стиля: абсолютное

Возникли проблемы с сортировкой правильного подхода к обработке события загрузки в Chrome при загрузке объектов HTML.

Я использую объекты HTML для загрузки виджетов в веб-панель управления, и событие загрузки выглядит нарушенным в Chrome, поскольку я получаю повторное срабатывание события загрузки, но только если я установил стиль объекта в событии загрузки на позицию : absolute. К сожалению, для моего приложения это критическая функция, так как мне нужно разместить виджет в определенных местах экрана с помощью javascript.

Скрипка ниже помещает Chrome в бесконечный цикл, в то время как в других браузерах он запускается только один раз (хотя в моем приложении Chrome запускает событие загрузки дважды, а затем останавливается).

HTML

<div id = "container"></div>
<br/><br/><br/><br/>
<div id = "xx">Not Fired..."</div>

JavaScript:

    var cnt = 0;
    (function loadWidget() {
        var widgetObj = document.createElement("object");
        widgetObj.data = ("http://13.75.145.9/widgets/dial.html")                                  // location of widget
        var tt = document.getElementById("container");
        tt.appendChild(widgetObj);
        widgetObj.addEventListener("load", widgetLoaded, false);
    })();

    function widgetLoaded(e) {
        cnt = cnt + 1;
        document.getElementById("xx").innerText = "fired x" + cnt;
    //any manipulation of style is OK, its only the position: absolute that causes re-firing
        e.currentTarget.style = "cursor: move; text-decoration: overline";
        e.currentTarget.style.setProperty("position", "relative");
    // Uncomment out the line below in Chrome and the event will continuously fire, but only once in othe browsers
        e.currentTarget.style = "position: absolute; left: 50px";
    }

Бесконечная петля

Я предполагаю, что это ошибка Chrome, и хотя я могу обойти ее, проверив, сколько раз объект был загружен, и досрочно завершил событие загрузки, это снижает производительность, потому что похоже, что весь объект перезагружается каждый раз (глобальный JavaScript в объекте запускается повторно) и при загрузке пары виджетов в качестве объектов браузер значительно замедляется, что влияет на работу конечного пользователя.

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

В соответствующем примечании Chrome отобразит и отобразит объект, а затем переместит его в правильное положение, при котором экран мерцает, в то время как другие браузеры отобразят виджет в его конечном месте (после того, как загрузочный javascript был запущен), что является более приятным опытом и Я не могу найти способ дважды остановить рендеринг Chrome.

[Обновление от декабря '18] - обходной путь, описанный в ответах ниже, больше не работает с последней версией Chrome (71.0.3578.80), а Chrome дважды загружает объекты HTML и дважды запускает загруженные события. См. Это сообщение об ошибке Chromium для получения дополнительной информации: Ошибка Chrome с объектами HTML

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
8
0
281
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не уверен в причинах такого поведения в Chrome. Однако обходным путем, похоже, является изменение стиля контейнера вместо стиля объекта - увидеть скрипку

function widgetLoaded(e) {        
    const target = e.currentTarget;        
    target.parentElement.style = "position: absolute; left: 50px;";
 }

Также после некоторого расследования я обнаружил, что проблема, вероятно, вызвана изменением display с inline на block - увидеть скрипку.

Изменение блока отображения устраняет проблему для моего приложения. Другой вариант изменения стиля контейнера также возможен путем инкапсуляции объекта в DIV, однако для моего приложения блок отображения более подходит, спасибо.

deandob 28.04.2018 01:16

@deandob, это может быть ошибка кроссбраузерного материала, который работает иначе. Но есть гораздо более простой обходной путь, см. Ответ, который я опубликовал.

Tarun Lalwani 28.04.2018 08:29

Я все еще не могу решить последнюю часть этой проблемы - где хром будет отображать объект дважды (даже если событие загрузки запускается только один раз). В первый раз хром отображает объект в позиции 0,0, а затем, если он перемещает его в правильное место (слева: 50 пикселей), и вы видите, что объект мерцает на экране. Это очевидно на скрипке и делает работу с хромом в моем приложении визуально беспорядочной. Другие браузеры будут правильно отображать объект после завершения события загрузки. Я пробовал несколько вещей (например, убрать контейнер с экрана), но, похоже, ничего не изменило это поведение. Любые идеи?

deandob 28.04.2018 23:29

@deandob в качестве опции вы можете использовать некоторые хитрости CSS - сделать ваш объект «невидимым» и показывать только после load - jsfiddle.net/xLzo25jp/8

mykhailo.romaniuk 28.04.2018 23:49

@mykhailo, у меня есть до 50 объектов для загрузки на экран, поэтому переходы CSS, скорее всего, замедлят загрузку страницы (важна быстрая загрузка). Но если я установил ширину: 0 до загрузки объекта, а затем отрегулирую ширину после загрузки, Chrome теперь отображает изящно. Edge по-прежнему является проблемой, но я попробую несколько похожих советов, чтобы заставить его работать изящно (эти небольшие различия в поведении браузера раздражают ...)

deandob 29.04.2018 01:25

@deandob transition в моем примере полностью необязателен, не стесняйтесь его пропустить. Рад слышать, что вы преодолели свои проблемы. И я полностью согласен, что эта проблема с load болезненна. Вы можете попробовать отправить эту проблему в трекер проблем с хромом

mykhailo.romaniuk 29.04.2018 16:38

Получил, что это хорошо работает как для Edge, так и для Chrome, используя непрозрачность 0 в родительском div перед загрузкой виджетов, затем непрозрачность 1 после завершения всех событий загрузки. Красиво выглядит и хорошо работает - спасибо за советы.

deandob 29.04.2018 22:27

Эта проблема вернулась с последней версией Chrome, ранее обходной путь для изменения отображаемого объекта: блок избегал двойного события для загрузки объекта, теперь он не работает в Chrome 71.0.3578.80 (ошибка двойного вызова события вернулась) . Посмотрите на эту скрипку, которая помещает последний цикл вызовов объектов Chrome, но запускается только один раз с другими браузерами. jsfiddle.net/xLzo25jp/5

deandob 08.12.2018 04:19

Если у кого-то есть идея, как это обойти, напишите здесь. Подам в гугл как ошибку.

deandob 08.12.2018 04:20

Обходной путь, приемлемый для моего приложения для предотвращения двойной загрузки, заключается в замене тега объекта тегом iframe - они очень похожи, работают одинаково (замените .data на .scr), и, согласно нашему тестированию, не имеют других побочных эффектов. .

deandob 23.05.2019 14:19

Другие вопросы по теме