0

Для тренировки пишу простенький таймер на Vue.js Столкнулся с ошибкой при которой window.getComputedStyle отдаёт для свойства fontSize пустую строку, хотя для требуемого элемента объект содержит это свойство, просто полтергейст какой-то...

Вот HTML:

window.onload = function() {

Vue.directive("timer", { bind(el, options) {

  let timer;
  let need_steps = Infinity; // Количество шагов таймера, которые необходимо сделать
  let do_steps = 0; // Количество шагов таймера, которые уже сделаны

  for (name in options.modifiers) {
    if (!isNaN(+name)) {
      need_steps = parseInt(name);
    }
  }

  if (options.modifiers.run) {
    options.value.call(this, el);
    do_steps++;
  }


}

});

new Vue({ el: ".sample", methods: { onTimer(el) { let computedStyle = window.getComputedStyle(el); let curr_font_size = parseInt(computedStyle['fontSize']); // computedStyle.fontSize и computedStyle.getPropertyValue('font-size') тоже NaN console.log(computedStyle); // Содержит объект со стилями console.log(curr_font_size); // <----- NaN, никак не получается получить значение fontSize

  }
}

}); }

.sample div {
  font-size: 14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="sample">
  <div v-timer:1000.5="onTimer">1</div>
  <div v-timer:1000.5.run="onTimer">2</div>
  <div v-timer:1000="onTimer">3</div>
</div>

В итоге в переменной computedStyle присутствует объект со стилями, но переменная curr_font_size пуста, в ней ничего нет. Почему?? Как в этом случае получить font-size?

Grundy
  • 81,538
F. Tomas
  • 745
  • ты уверен, что именно значения computedStyle.fontSize и computedStyle.getPropertyValue('font-size') - NaN, а не результат parseInt? – Grundy Sep 01 '19 at 06:46
  • проблема заключается в том, что метод OnTimer вызывается слишком рано. Элемент еще не добавлен в DOM, следовательно к нему еще не применялись стили из родительского элемента (так как у дива его еще нет) поэтому текущий стиль не установлен. – Grundy Sep 01 '19 at 06:58
  • Это точно vue? Или от него тут только название? Не видел никогда чтобы настолько неправильно его использовали – MoloF Sep 01 '19 at 07:49
  • @MoloF, это абсолютно точно vue, флудите в другом месте – F. Tomas Sep 03 '19 at 19:19
  • @Grundy, спасибо. Заменил хук bind на хук inserted и всё заработало. Больше всего напрягало то, что console.log(computedStyle); содержал нужное свойство с искомым значением (14px), но на следующей строке в console.log(curr_font_size); переменная curr_font_size оказывалась пуста. Если стили из родительского элемента ещё не применились, тогда почему в переменной computedStyle был объект с уже рассчитанными стилями? – F. Tomas Sep 03 '19 at 19:24
  • подробнее смотри тут – Grundy Sep 03 '19 at 20:34

1 Answers1

0

Проблема что елемен не был приатачен в документ, используй другой евент inserted: https://v2.vuejs.org/v2/guide/custom-directive.html#Hook-Functions

window.onload = function() {

Vue.directive("timer", { bind(el, options) {

  let timer;
  let need_steps = Infinity; // Количество шагов таймера, которые необходимо сделать
  let do_steps = 0; // Количество шагов таймера, которые уже сделаны

  for (name in options.modifiers) {
    if (!isNaN(+name)) {
      need_steps = parseInt(name);
    }
  }

  if (options.modifiers.run) {
    options.value.call(this, el);
    do_steps++;
  }


}

});

new Vue({ el: ".sample", methods: { onTimer(el) { let computedStyle = window.getComputedStyle(el); let curr_font_size = parseInt(computedStyle['fontSize']); // computedStyle.fontSize и computedStyle.getPropertyValue('font-size') тоже NaN console.log(computedStyle); // Содержит объект со стилями console.log(curr_font_size); // <----- NaN, никак не получается получить значение fontSize let inDom = document.body.contains(el); console.log(inDom); // <- будет false } } }); }

.sample div {
  font-size: 14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="sample">
  <div v-timer:1000.5="onTimer">1</div>
  <div v-timer:1000.5.run="onTimer">2</div>
  <div v-timer:1000="onTimer">3</div>
</div>