Вставьте innerHTML с помощью Prototypejs - PullRequest
0 голосов
/ 25 мая 2011

Скажи, у меня есть такой список:

<ul id='dom_a'>
  <li>foo</li>
</ul>

Я знаю, как вставить элементы в тег ul с помощью:

Element.insert('dom_a', {bottom:"<li>bar</li>"});

Поскольку полученная строка содержит идентификатор dom, мне нужно вставить внутренний HTML вместо всего элемента. Мне нужна функция для этого:

insert_content('dom_a', {bottom:"<ul id='dom_a'><li>bar</li></ul>"});

И получить:

<ul id='dom_a'>
  <li>foo</li>
  <li>bar</li>
</ul>

Как мне сделать это с Prototype?

Вот решение, которое я придумала, кто-нибудь может сделать это лучше?

Zena.insert_inner = function(dom, position, content) {
  dom = $(dom);
  position = position.toLowerCase();
  content = Object.toHTML(content);
  var elem = new Element('div');
  elem.innerHTML = content; // strip scripts ?
  elem = elem.down();
  var insertions = {};
  $A(elem.childElements()).each(function(e) {
    insertions[position] = e;
    dom.insert(insertions);
  });
}

Ответы [ 5 ]

2 голосов
/ 25 мая 2011

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

Это может выглядеть такэто:

var rep_struct = "<ul id='dom_a'><li>bar</li></ul>";
var dummy_node = new Element('div'); // So we can easily access the structure
dummy_node.update(rep_struct);
$('dom_a').insert({bottom: dummy_node.childNodes[0].innerHTML});
1 голос
/ 25 мая 2011

Я думаю, что вы можете немного уменьшить код, просто добавив innerHTML первого дочернего элемента временного элемента:

Zena.insert_inner = function(dom, position, content) {
    var d = document.createElement('div');
    d.innerHTML = content;
    var insertions = {};
    insertions[position] = d.firstChild.innerHTML;
    Element.insert(dom, insertions);
}

Не слишком много улучшений, пример здесь.

0 голосов
/ 04 марта 2013

Если вы используете PrototypeJS, вы также можете добавить script.aculo.us в ваш проект. Конструктор в script.aculo.us предоставляет хороший способ построения сложных структур DOM, например:

var myList = Builder.node("ul", {
    id: "dom_a"
},[
    Builder.node("li", "foo"),
    Builder.node("li", "bar"),
]);

После этого вы можете вставить этот объект, который должен отображаться как HTML, в любом месте DOM с любыми функциями вставки / обновления (из PrototypeJS) или даже стандартным JavaScript appendChild.

$("my_div").insert({After: myList});

Обратите внимание, что в PrototypeJS вставка поставляется в 4 различных режимах: After, Before, Top и Bottom. Если вы используете вставку без указания «mode», как указано выше, по умолчанию будет «Bottom». То есть новый код DOM будет добавлен ниже существующего содержимого элемента контейнера как innerHTML. Top сделает то же самое, но добавит его поверх существующего содержимого. До и после - это также классные способы добавления в DOM. Если вы используете их, содержимое будет добавлено в структуру DOM до и после элемента контейнера, а не внутри как innerHTML.

Однако в Builder есть одна вещь, о которой нужно помнить: ладно, две вещи на самом деле: я. Вы не можете ввести необработанный HTML в объект как контент ... Это не удастся:

Builder.node("ul", "<li>foo</li>");

II. Когда вы указываете атрибуты узла, имейте в виду, что вы должны использовать className для обозначения класса атрибута HTML (и, возможно, также htmlFor для для атрибута ... хотя для атрибута кажется устаревшим в HTML5 (?), Но кто не хочет использовать это для этикеток)

Builder.node("ul", {
    id: "dom_a",
    className: "classy_list"
});

Я знаю, что вы чесаете голову из-за пункта i. > Что, без сырого HTML, черт! Не беспокоиться. Если вам все еще нужно добавить контент, который может содержать HTML, в DOM, созданном Builder, просто сделайте это на втором этапе, используя вставку ({Before / After / Top / Bottom: string}). Но почему вы хотите сделать это в первую очередь? Было бы неплохо, если бы вы написали функцию «раз и навсегда», которая генерирует все виды элементов DOM, а не встраивает во все виды строк. Первый подход был бы аккуратным и элегантным. Это что-то вроде встроенного стиля в сравнении с типом вопроса. Хороший дизайн должен, в конце концов, отделять контент от meta content или форматирования разметки / markdown.

И последнее, что нужно держать под рукой в ​​вашем наборе инструментов, - это обход DOM Protype в случае, если вы хотите динамически вставлять и удалять контент, такой как HTML Houdini. Проверьте Элемент следующим, вверх, вниз, предыдущие методы. Кроме того, $$ также интересно использовать, особенно если вы знаете селекторы CSS3.

0 голосов
/ 25 мая 2011

Вы можете использовать регулярное выражение для удаления внешнего элемента.

Element.Methods.insert_content = function(element, insertions) {
    var regex = /^<(\w+)[^>]*>(.*)<\/\1>/;
    for (key in insertions) {
        insertions[key] = regex.exec(insertions[key])[2];
    }
    Element.insert(element, insertions);
};
Element.addMethods();

$('dom_a').insert_content({bottom:"<ul id='dom_a'><li>bar</li></ul>"});
0 голосов
/ 25 мая 2011

Я изучал документацию по прототипам и обнаружил следующее: функция обновления .

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

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