wbrapist
@wbrapist
Ты в порядке?

Почему не применяются стили к элементу после перезагрузки страницы?

Привет.
Есть слайдер. Есть навигация в нем в виде кругов (отображение на каком слайде ты находишься). Сама эта навигация позиционируется таким образом:
var sliderWidth      = getComputedStyle(document.getElementsByClassName('slider')[0]).width;

function setSliderNavPosition() {
  var nav = document.querySelector('.slider .navigation');
  var navWidth = parseFloat(getComputedStyle(nav).width);
  var slidersWidth = parseFloat(sliderWidth);

  nav.style.left = ( (slidersWidth / 2) - (navWidth / 2) ) + 'px';
}


Перейдите на страницу со слайдером: https://wbrapist.github.io/slider/index.html
Перезагрузите страницу Ctrl + F5, подождите несколько 2-3 секунды и обычно перезагрузите страницу F5. Увидите, что навигация съехала влево так, как будто js-функция, описанная выше не отрабатывает. Почему так происходит? Мне кажется, что javascript по-любому должен отработать, что и происходит, раз слайды расположены так, как расположены (меняются местами с помощью js). Но почему-то именно с расположением навигации косяк.
Если опять форсануть Ctrl + F5 - то всё ОК. Проблема при обычной перезагрузке.

UPD Кстати, проблема и с другими стилями, которые устанавливает JS. Анимация переключения слайдов тоже не работает.
  • Вопрос задан
  • 602 просмотра
Решения вопроса 1
wbrapist
@wbrapist Автор вопроса
Ты в порядке?
Всё оказалось довольно банальным. Я почему-то думал, что при подключении скрипта, атрибут defer ждёт полной загрузки страницы, в итоге, так и есть, но defer не ждёт загрузки внешних подключаемых ресурсов, как я понял:

It's a bad idea to use the document when it's not fully loaded. Depending on the time it takes to load it, your values are going to be different. That's why you get different behaviors.

To solve this, just wait for the document to be loaded by wrapping your code like this:
window.addEventListener('load', function(){
    /* ...YOUR CODE GOES HERE... */
});

When you load a page, 2 main events are fired: DOMContentLoaded, when the DOM is ready (All the HTML is loaded). Then, a load event fires when all external resources (CSS, images) are loaded. Using defer waits for the first event to fire, but not the other one. In your case, I think it is the CSS that was causing a problem. It was not loaded yet

stackoverflow.com/questions/45702723/


Может быть мои знания английского не позволяют мне понять, но вроде как ответ постом выше немного отличается от того, что написано на MDN:

defer
This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.

The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. A very different event load should be used only to detect a fully-loaded page. It is an incredibly popular mistake to use load where DOMContentLoaded would be much more appropriate, so be cautious.


То есть, грубо говоря, как я понял, происходит 3 этапа:
- Страница парсится
- Загружается HTML
- Загружаются внешние ресурсы

UPD: Критический путь рендеринга веб-страниц
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы