Основанный на контексте getElementById время на медленнее, чем собственный getElementById. Селекторным механизмам нравится использование шипения более умная стратегия?

Интересоваться созданием HTML разделяет на блоки не-dom, прежде для вставки их в dom я сделал некоторое тестирование с помощью dynatrace. Я использовал метод bobince: там какой-либо путь состоит в том, чтобы найти элемент в documentFragment?

Я нашел, что это было почти в 1000 раз медленнее (в IE7), который удивил меня много.

Так как функция является довольно основной, я задавался вопросом о стратегии, используемой механизмами, такими как шипение.

Я хотел бы знать, существуют ли некоторые более эффективные способы сделать основанный на контексте выбор узла?

6
задан Community 23 May 2017 в 12:13
поделиться

2 ответа

Framework selector engines обычно оцениваются правой рукой, поэтому я бы ожидал, что контекстный селектор ID в document.getElementById ID, а затем проверил, были ли результаты в контекстном узле, увеличив значение параметра parentNodes. Это достаточно быстро, но это не будет работать для деревьев DOM вне документа, как в этом примере. Тогда селекторным механизмам придётся делать это отчаянно медленным способом, или же им всё равно (например, Sizzle не работает с DocumentFragment).

Существует лучший способ получить ID внутри фрагмента, который я запомнил с тех пор, для браузеров, которые реализуют Selectors-API (IE8, Firefox 3.5, Opera 10, Safari 3.1, Chrome 3). Вы можете использовать requestSelector для применения CSS-селектора с DocumentFragment в качестве контекстного узла, так как API требует DocumentFragment реализации NodeSelector:

alert(frag.querySelector('#myId'))

Это не так быстро, как getElementById, но это загружается лучше, чем DOM-версия.

К сожалению, большинство фреймворков, имеющих Selector-API оптимизации, в данном случае не будут использовать их, как и любые другие фреймворки с узлами контекста, так как в querySelector[All], работа с узлами контекста отличается от того, как фреймворки традиционно реализовывали это, что делает их несовместимыми.

Selectors-API Level 2 предлагает "scoped" методы, которые ведут себя как традиционные селекторы фреймворка... пройдет некоторое время, прежде чем это станет возможным, но мы, вероятно, не увидим оптимизированных контекстных селекторов в существующих фреймворках до тех пор. Думаю, это обидно, так как хотя метод requestSelector использования контекстного узла для фильтрации, но не scoping не так хорош, он все равно практически пригоден для всех распространенных случаев.

1
ответ дан 17 December 2019 в 22:13
поделиться

Возможно, проблема связана с «swing» функцией смягчения jQuery, используемой по умолчанию.

Вместо этого вы можете попробовать «линейную» функцию замедления:

$(document).ready(function() {
  function pulsate() {
    $("#pulsating-block").
      animate({opacity: 0.2}, 3000, 'linear').
      animate({opacity: 1}, 3000, 'linear', pulsate);
  }
  pulsate();
});

Я также закодировал небольшой пульсирующий плагин, который включает функцию замедления «отскока» , которая может быть вам больше по душе. Я должен отметить, что плагин использует непрерывный расчет для выполнения анимации, а не две отдельные fade-in/fade-out анимации, так что это может помочь с проблемой «пауза».

Рабочая демонстрация

http://jsbin.com/isicu (редактируемая с помощью http://jsbin.com/isicu/edit )

Полный исходный

JavaScript

(function ($) {
  $.fn.pulsate = function (properties, duration, type, speed, callback) {
    type = type || 'Swing'
    speed = speed || 'Normal';
    this.animate(properties, duration, 'pulsate' + type + speed, callback);
  };

  function createPulsateLinear (speed) {
    speed *= 2;
    return function (p, n) {
      return (Math.asin(Math.sin(Math.PI * n / speed)) + Math.PI / 2) / Math.PI;
    }
  }

  function createPulsateSwing (speed) {
    return function (p, n) {
      return (1 + Math.sin(n / speed)) / 2;
    }
  }

  function createPulsateBounce (speed) {
    speed *= 2;
    return function (p, n) {
      return (
        ((Math.asin(Math.sin(Math.PI * n / speed)) + Math.PI / 2) / Math.PI) *
        (Math.sin(Math.PI * n / speed) + 1) / -2 + 1
      );
    }
  }

  var speeds = {
    fast: 100,
    normal: 200,
    slow: 400
  }

  $.extend(jQuery.easing, {
    pulsateLinearFast: createPulsateLinear(speeds.fast),
    pulsateLinearNormal: createPulsateLinear(speeds.normal),
    pulsateLinearSlow: createPulsateLinear(speeds.slow),
    pulsateSwingFast: createPulsateSwing(speeds.fast),
    pulsateSwingNormal: createPulsateSwing(speeds.normal),
    pulsateSwingSlow: createPulsateSwing(speeds.slow),
    pulsateBounceFast: createPulsateBounce(speeds.fast),
    pulsateBounceNormal: createPulsateBounce(speeds.normal),
    pulsateBounceSlow: createPulsateBounce(speeds.slow)
  });
})(jQuery);

$(document).ready(function() {
  var
    pulsatingBlocks = $('.pulsating-block'),
    forever = 5 * 24 * 60 * 60 * 1000; // 5 days! (Which is forever in Internet time)

  pulsatingBlocks.filter('.opacity').each(function () {
    $(this).pulsate({opacity: 0.2}, forever, this.className.split(' ')[0], 'Slow');
  });

  pulsatingBlocks.filter('.top').each(function () {
    $(this).pulsate({top: 100}, forever, this.className.split(' ')[0], 'Slow');
  });

});

HTML

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
<meta charset=utf-8 />
<title>Pulsate</title>
<style>
  div { clear: left; margin-bottom: 2em; }
  .pulsating-block {
    width: 6em; height: 4em;
    margin: 0.5em; margin-right: 10em;
    float: left; clear: none; position: relative;
    background: lightblue;
    text-align: center;
    padding-top: 2em;
    font: bold 1em sans-serif;
  }
</style>
</head>
<body>
  <div>
    <div class="Linear opacity pulsating-block">linear</div>
    <div class="Swing opacity pulsating-block">swing</div>
    <div class="Bounce opacity pulsating-block">bounce</div>
  </div>
  <div>
    <div class="Linear top pulsating-block"></div>
    <div class="Swing top pulsating-block"></div>
    <div class="Bounce top pulsating-block"></div>
  </div>
</body>
</html>
-121--335741-

Найдите информацию о контроллерах прерываний Intel 8214 или 8259.

-121--3579252-

Если вы не против временно вставить свой documentFragment в DOM...

function getElementFromFragById(frag, id) {
    var tempDiv = document.createElement("div");
    tempDiv.style.display = "none";
    tempDiv.appendChild(frag);
    document.body.appendChild(tempDiv);
    var elem = document.getElementById(id);
    document.body.removeChild(tempDiv);
    return document.getElementById(id) ? null : elem; //if the element still exists, we have a problem
}

Это работает надежно, если documentFragment не содержит элементов с идентификатором, которые уже существуют в документе , и требуется выполнить поиск по этому идентификатору.

0
ответ дан 17 December 2019 в 22:13
поделиться
Другие вопросы по тегам:

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