Делегирование событий против прямого связывания при добавлении сложных элементов на страницу

У меня разметка выглядит примерно так (классы приведены для пояснения):

<ol id="root" class="sortable">
  <li>
    <header class="show-after-collapse">Top-Line Info</header>
    <section class="hide-after-collapse">
      <ol class="sortable-connected">
        <li>
          <header class="show-after-collapse">Top-Line Info</header>
          <section class="hide-after-collapse">
            <div>Content A</div>
          </section>
        </li>
      </ol>
    </section>
  </li>
  <li>
    <header/>
    <section class="hide-after-collapse">
      <ol class="sortable-connected">
        <li>
          <header/>
          <section class="hide-after-collapse">
            <div>Content B</div>
          </section>
        </li>
      </ol>
    </section>
  </li>
</ol>

То есть вложенные сортируемые списки. Однако сортируемого плагина достаточно, поскольку каждый li (далее "элемент") сохраняет свой уровень, хотя внутренние списки связаны. Элементы имеют всегда видимый заголовок и раздел, видимый в развернутом состоянии, который переключается нажатием на заголовок. Пользователь может добавлять и удалять элементы с любого уровня по своему усмотрению; добавление элемента верхнего уровня включает пустой список гнезда внутри него. Мой вопрос касается JS инициализации вновь созданного элемента: Хотя они будут иметь некоторую общую функциональность, которую я могу описать в

$("#root").on("click", "li > header", function() {
  $(this).parent().toggleClass("collapsed");
});

и

li.collapsed section {
  display: none;
}

(побочный вопрос: будет ли это подходящим местом для использования HTML5-тегов details/summary? Кажется сомнительным, попадут ли они в окончательный вариант спецификации, а мне нужен скользящий переход, так что, похоже, для этого все равно понадобится JS. Но я бросаю вопрос в массы. Привет, массы.)

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

$("#root").on("change", "li > section button.b1", function() {
  b1Function();
}).on("change", "li > section button.b2", function() {
  b2Function();
});

Это точно? В таком случае, не имеет ли смысл отказаться от .on() и привязывать события в момент добавления нового элемента на страницу? Общее количество элементов, вероятно, будет исчисляться десятками, если это имеет значение для ответа.

17
задан slk 11 January 2012 в 22:10
поделиться