Как вы обходите клонированные шаблоны, теряя ссылки на элементы?

Я заметил, что hyperHTML сохраняет ссылки, которые я делаю на элементы:

let div = document.createElement("div");
div.textContent = "Before Update";
hyperHTML.bind(document.body)`static1 - ${div} - static2`;
div.textContent = "After Update";

Выше появится страница с надписью:

static1 - After Update - static2

Насколько я понимаю, HyperHTML в конечном итоге клонирует HTML <tempate> элемент для отображения окончательного результата. Однако разве вы не теряете ссылки при клонировании HTML-шаблона (например, переменная "div" в приведенном выше примере)?

Следовательно, при первоначальном рендеринге HyperHTML каким-то образом заменяет клонированные элементы их оригиналами после клонирования шаблона HTML?

Вот как я думаю, что это работает:

  1. Создайте шаблон HTML исходного литерала шаблона, заменив все интерполяции комментариями.
  2. Клонируйте HTML-шаблон с оставленными комментариями.
  3. Сделать элементы или фрагменты документа из каждой интерполяции, первоначально полученной
  4. Замените каждый комментарий в клоне его обработанной интерполяцией.

Это правильно?

1 ответ

Решение

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

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

function update(text) {
  var render = hyperHTML.bind(document.body);
  render`static1 - <div>${text}</div> - static2`;
}

и позвонить update("any text") в любое время

Вот как я думаю, что это работает... Это правильно?

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

Часть библиотеки, которая делает это, называется domtagger, и отображение для литерала шаблона основано на стандартном факте, что они уникальны для каждой области:

const templates = [];
function addTemplate(template, value) {
  templates.push(template);
  return template.join(value);
}
function asTemplate(value) {
  return addTemplate`number ${value}!`;
}
asTemplate(1);
asTemplate(2);
asTemplate(Math.random());
templates[0] === templates[1]; // true
templates[1] === templates[2]; // true
// it is always the same template object!

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

hyperHTML никогда не удаляет комментарии, он использует их как pin, а затем использует domdiff, чтобы в конечном итоге обновлять узлы, связанные с этими выводами, всякий раз, когда есть необходимость что-либо обновить.

Domdiff - это реализация алгоритма petit-dom без использования vDOM, который, в свою очередь, основан на статье EW Myers " Разностный алгоритм O(ND) и его вариации".

Когда у вас есть узлы DOM в отверстиях, hyperHTML понимает это и заполняет эти отверстия этими узлами. Если вы неоднократно проходите один и тот же узел, hyperHTML не будет ничего делать, потому что он полон алгоритмов и умных решений, описанных в документации, для достижения максимальной производительности из своей абстракции.

Все эти вещи и многое другое, нормализованное для любого браузера, делает вес HyperHTML примерно 7 КБ после минимизации и сжатия, но он также предлагает:

  • Пользовательские элементы, такие как перехваты через подключенных / отключенных слушателей
  • легкие компоненты через hyperHTML.Component
  • SVG манипуляция как контент или через провод
  • простое определение пользовательских элементов через класс HyperHTMLElement

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

Если вы просто пытаетесь понять, как это работает, вам не нужно ничего предполагать, потому что проект полностью открыт.

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

Вы хотите написать свою собственную библиотеку lit/hyperHTML? Не стесняйтесь использовать domtagger или библиотеку domdiff тоже, немногие уже делают то же самое.

Другие вопросы по тегам