Скрытие опции, если она выбрана в другом окне выбора JavaScript

В большинстве браузеров неактивные вкладки имеют невысокое выполнение, и это может повлиять на таймеры JavaScript.

Если значения вашего перехода были рассчитаны с использованием реального времени, прошедшего между кадрами, вместо фиксированных приращений на каждом интервале, вы не только обходной путь этой проблемы, но также можно добиться анимации с помощью requestAnimationFrame , поскольку он может получить до 60 кадров в секунду, если процессор не очень занят.

Вот пример ванильного JavaScript анимированный переход с использованием requestAnimationFrame:

var target = document.querySelector('div#target')
var startedAt, duration = 3000
var domain = [-100, window.innerWidth]
var range = domain[1] - domain[0]

function start() {
  startedAt = Date.now()
  updateTarget(0)
  requestAnimationFrame(update)
}

function update() {
  let elapsedTime = Date.now() - startedAt

  // playback is a value between 0 and 1
  // being 0 the start of the animation and 1 its end
  let playback = elapsedTime / duration

  updateTarget(playback)
  
  if (playback > 0 && playback < 1) {
  	// Queue the next frame
  	requestAnimationFrame(update)
  } else {
  	// Wait for a while and restart the animation
  	setTimeout(start, duration/10)
  }
}

function updateTarget(playback) {
  // Uncomment the line below to reverse the animation
  // playback = 1 - playback

  // Update the target properties based on the playback position
  let position = domain[0] + (playback * range)
  target.style.left = position + 'px'
  target.style.top = position + 'px'
  target.style.transform = 'scale(' + playback * 3 + ')'
}

start()
body {
  overflow: hidden;
}

div {
    position: absolute;
    white-space: nowrap;
}
...HERE WE GO

Для фоновых задач (не связанных с UI)

Комментарий @UpTheCreek:

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

blockquote>

Если у вас есть фоновые задачи, которые нуждается в для точного выполнения с заданными интервалами, вы можете использовать HTML5 Web Workers . Взгляните на ответ Möhre ниже для более подробной информации ...

CSS против JS «анимация»

Эта проблема и многие другие можно было избежать, используя CSS-переходы / анимации вместо анимации на основе JavaScript, что добавляет значительные накладные расходы. Я бы порекомендовал этот плагин jQuery , который позволит вам использовать переходы CSS так же, как методы animate().

-1
задан Shakespear 17 January 2019 в 10:06
поделиться

2 ответа

Я не знаю, что не так с вашим кодом, логика кажется запутанной. Вы не можете надежно скрыть параметры, установив для дисплея значение «нет», в некоторых браузерах они остаются видимыми. Если бы это было так просто, жизнь была бы легкой.

Вы можете скрыть опции, удалив их из списка, но затем вы должны запомнить, откуда они появились, чтобы вы могли вернуть их обратно при изменении выбора.

Далее, каждый раз, когда выбирается какой-либо параметр, если он сохраняется, он возвращается и тот, который соответствует выбранному параметру, удаляется. Если выбран первый вариант, сохраненный просто возвращается, ничего не удаляется.

Это зависит только от двух селекторов, имеющих одинаковое значение класса, они могут быть связаны каким-то другим значением (например, свойством data- *).

Надеюсь, комментарии достаточны.

var matchSelected = (function() {
  // Store for "hidden" node
  var nodeStore = {
    sourceElement: null,
    node: document.createDocumentFragment(),
    index: null
  };

  return function(evt) {
    // Get the element that got the event
    var tgt = this;
    // If there's a stored option, put it back
    if (nodeStore.sourceElement) {
      let sel = nodeStore.sourceElement;
      sel.insertBefore(nodeStore.node.firstChild, sel.options[nodeStore.index]);
      nodeStore.sourceElement = null;
      nodeStore.node = document.createDocumentFragment();
      nodeStore.index = null;
    }
    // If the selected option is the first one, stop here
    if (tgt.selectedIndex == 0) return;
    // Get all selects with the same className
    var sels = document.querySelectorAll('.' + this.className);
    // Get the "other" option
    var other = sels[0] == this ? sels[1] : sels[0];
    // Remove and keep the option on the other element that is the same
    // as the selected option on the target element
    nodeStore.sourceElement = other;
    nodeStore.index = tgt.selectedIndex;
    nodeStore.node.appendChild(other.options[tgt.selectedIndex]);
  }
}());

window.addEventListener('DOMContentLoaded', function() {
  document.querySelectorAll('.countrySelect').forEach(
    node => node.addEventListener('change', matchSelected, false)
   );
}, false);
<select id="country1" class="countrySelect">
  <option value="" selected>Choose</option>
  <option value="1">Australia Dollar</option>
  <option value="2">Indonesian Rupiah</option>
  <option value="3">Chinese Yaun</option>
  <option value="4">Japanese Yen</option>
</select>
Convert to
<select id="country2" class="countrySelect">
  <option value="" selected>Choose</option>
  <option value="1">Australia Dollar</option>
  <option value="2">Indonesian Rupiah</option>
  <option value="3">Chinese Yaun</option>
  <option value="4">Japanese Yen</option>
</select>

0
ответ дан RobG 17 January 2019 в 10:06
поделиться

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

Редактировать Вышеуказанный метод работает не во всех браузерах. Лучший способ HTML5 - установить и удалить скрытый атрибут. Я обновил фрагмент.

window.CheckDropDowns = function(thisSelect) {
  var otherSelectId = ("country1" == thisSelect.id) ? "country2" : "country1";
  var otherSelect = document.getElementById(otherSelectId);

  for (i = 0; i < otherSelect.options.length; i++) {
    //otherSelect.options[i].style.display = 'block';
    otherSelect.options[i].removeAttribute('hidden');
    if (otherSelect.options[i].value == thisSelect.value) {
      //otherSelect.options[i].style.display = 'none';
      otherSelect.options[i].setAttribute('hidden', 'hidden');
    }
  }
}
<section>

  <select id="country1" onchange="CheckDropDowns(this)">
    <option value="">Choose</option>
    <option value="1">Australia</option>
    <option value="2">Indonesian Rupiah</option>
    <option value="3">Chinese Yaun</option>
    <option value="4">Japanese Yen</option>
  </select>
  Convert to
  <select id="country2" onchange="CheckDropDowns(this)">
    <option value="">Choose</option>
    <option value="1">Australia</option>
    <option value="2">Indonesian Rupiah</option>
    <option value="3">Chinese Yaun</option>
    <option value="4">Japanese Yen</option>
  </select>

</section>

0
ответ дан Arleigh Hix 17 January 2019 в 10:06
поделиться
Другие вопросы по тегам:

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