Принудительная перерисовка / обновление DOM на Chrome / Mac - PullRequest
201 голосов
/ 12 января 2012

Время от времени Chrome отображает совершенно корректный HTML / CSS неправильно или не отображает его вообще. Копания через инспектора DOM часто достаточно, чтобы заставить его осознать ошибку своих путей и правильно перерисовать, поэтому вполне вероятно, что разметка хорошая. Это происходит достаточно часто (и, как и ожидалось, достаточно) в проекте, над которым я работаю, и я поместил код на место, чтобы вызвать перерисовку при определенных обстоятельствах.

Это работает в большинстве комбинаций браузер / операционная система:

    el.style.cssText += ';-webkit-transform:rotateZ(0deg)'
    el.offsetHeight
    el.style.cssText += ';-webkit-transform:none'

Например, настройте неиспользуемое свойство CSS, затем запросите информацию, которая вызывает перерисовку, а затем отмените свойство. К сожалению, яркая команда Chrome для Mac, похоже, нашла способ получить это offsetHeight без перерисовки. Таким образом убивая полезного в противном случае взломать.

Пока что лучшее, что я придумал, чтобы получить тот же эффект на Chrome / Mac, это уродство:

    $(el).css("border", "solid 1px transparent");
    setTimeout(function()
    {
        $(el).css("border", "solid 0px transparent");
    }, 1000);

Как в действительности, заставить элемент немного подскочить, затем охладить секунду и отскочить назад. Хуже того, если вы сократите этот тайм-аут ниже 500 мс (туда, где он будет менее заметен), он часто не будет иметь желаемого эффекта, так как браузер не дойдет до перерисовки, пока не вернется в исходное состояние.

Кто-нибудь хочет предложить лучшую версию этого хака для перерисовки / обновления (предпочтительно на основе первого примера выше), который работает на Chrome / Mac?

Ответы [ 21 ]

1 голос
/ 08 июля 2016
function resizeWindow(){
    var evt = document.createEvent('UIEvents');
    evt.initUIEvent('resize', true, false,window,0);
    window.dispatchEvent(evt); 
}

вызовите эту функцию через 500 миллисекунд.

1 голос
/ 30 октября 2014

Пример HTML:

<section id="parent">
  <article class="child"></article>
  <article class="child"></article>
</section>

Js:

  jQuery.fn.redraw = function() {
        return this.hide(0,function() {$(this).show(100);});
        // hide immediately and show with 100ms duration

    };

функция вызова:

$('article.child').redraw(); // <== плохая идея </p>

$('#parent').redraw();
0 голосов
/ 21 февраля 2019

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

// Set initial HTML description
var defaultHTML;
function DefaultSave() {
  defaultHTML = document.body.innerHTML;
}
// Restore HTML description to initial state
function HTMLRestore() {
  document.body.innerHTML = defaultHTML;
}



DefaultSave()
<input type="button" value="Restore" onclick="HTMLRestore()">
0 голосов
/ 07 июля 2017

Я столкнулся с подобной проблемой, и эта простая строка JS помогла исправить это:

document.getElementsByTagName('body')[0].focus();

В моем случае это была ошибка с расширением Chrome, не перерисовывающим страницу после изменения ее CSS изнутрирасширение.

0 голосов
/ 15 февраля 2016

Это мое решение, которое работало для исчезновения контента ...

<script type = 'text/javascript'>
    var trash_div;

    setInterval(function()
    {
        if (document.body)
        {
            if (!trash_div)
                trash_div = document.createElement('div');

            document.body.appendChild(trash_div);
            document.body.removeChild(trash_div);
        }
    }, 1000 / 25); //25 fps...
</script>
0 голосов
/ 13 декабря 2015

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

Но я придумал этот, который работает плавно, потому что он синхронный:

var p = el.parentNode,
    s = el.nextSibling;
p.removeChild(el);
p.insertBefore(el, s);
0 голосов
/ 06 марта 2019

У меня был список реагирующих компонентов, который при прокрутке открывал другую страницу, а затем при возврате список не отображался в Safari iOS до прокрутки страницы.Так что это исправление.

    componentDidMount() {
        setTimeout(() => {
            window.scrollBy(0, 0);
        }, 300);
    }
0 голосов
/ 19 июля 2013

Подход, который работал для меня в IE (я не мог использовать технику отображения, потому что был ввод, который не должен терять фокус)

Это работает, если у вас 0 полей (изменение заполнения работает какхорошо)

if(div.style.marginLeft == '0px'){
    div.style.marginLeft = '';
    div.style.marginRight = '0px';
} else {
    div.style.marginLeft = '0px';
    div.style.marginRight = '';
}
0 голосов
/ 02 августа 2014

только CSS. Это работает для ситуаций, когда дочерний элемент удален или добавлен. В этих ситуациях границы и закругленные углы могут оставлять артефакты.

el:after { content: " "; }
el:before { content: " "; }
0 голосов
/ 16 июля 2019

Ниже css работает для меня в IE 11 и Edge, JS не требуется.scaleY(1) добивается цели здесь.Кажется самое простое решение.

.box {
    max-height: 360px;
    transition: all 0.3s ease-out;
    transform: scaleY(1);
}
.box.collapse {
    max-height: 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...