Как избежать написания HTML-тегов в javascript

#javascript

#javascript

Вопрос:

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

Например:

введите описание изображения здесь

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

Я не думаю, что это хорошая идея, есть предложения?

Комментарии:

1. Есть два способа создать HTML с помощью JavaScript: записать HTML в виде строк и использовать innerHTML для его добавления. В большинстве случаев это плохо. Или используйте DOM API для создания элементов, что идеально подходит для этого. Конечно, это все равно будет утомительно для сложных элементов.

Ответ №1:

Вы можете извлечь сгенерированный JS HTML в шаблоны, созданные на стороне клиента. Ознакомьтесь, например, с шаблонами jQuery:

http://api.jquery.com/category/plugins/templates/

Пример:

 <ul id="movieList"></ul>

<script id="movieTemplate" type="text/x-jquery-tmpl">
    <li><b>${Name}</b> (${ReleaseYear})</li>
</script>

<script type="text/javascript">
    var movies = [
        { Name: "The Red Violin", ReleaseYear: "1998" },
        { Name: "Eyes Wide Shut", ReleaseYear: "1999" },
        { Name: "The Inheritance", ReleaseYear: "1976" }
    ];

    // Render the template with the movies data and insert
    // the rendered HTML under the "movieList" element
    $( "#movieTemplate" ).tmpl( movies )
        .appendTo( "#movieList" );
</script>
  

Комментарии:

1. к сожалению, мы не можем использовать jquery lib, поскольку мы используем прототип, я боюсь, что это вызовет проблему конфликта, поэтому….

2. Ну, тогда вы можете просто реализовать такой механизм самостоятельно. Основная идея довольно проста: создать специальный <script type=»text/x-your-tmpl»>, а затем заменить заполнители реальными данными и вставить в DOM. Смотрите github.com/jquery/jquery-tmpl/blob/master/jquery.tmpl.js для справки

3. Спасибо, я попробую. Кажется, что даже шаблон также должен быть определен в js.

4. @hguser: Шаблоны — это просто текст, вы можете либо записать их в JS (но у меня создается впечатление, что вы пытаетесь избежать этого), либо вы можете поместить их в отдельный файл, который вы требуете загрузить с сервера, или встроить на страницу с помощью display: none . И хорошие новости: в Prototype есть шаблоны (подробности в моем ответе).

Ответ №2:

Другой подход с использованием простого jQuery (я не знаю прототипа, но я думаю, вы можете сделать то же самое довольно похоже):

Шаблон:

 <div id="template" style="display: none">
    Hello, <span class="name">[world]</span>
</</div>
  

Рендеринг:

 function render(name) {
    $('#template').clone().removeAttr('id')
        .find('.name').text(name).end()
        .appendTo('body').show();
    }

render("Stack Overflow");
render("..and world");
  

Идея довольно проста: поместите свой шаблон, скрытый в HTML. Когда вам это понадобится, найдите его по идентификатору, удалите этот идентификатор, замените данные и добавьте вновь созданный элемент туда, где вы этого хотите.

Ответ №3:

Вы сказали, что используете Prototype. Вы могли бы использовать его Template класс. Вы могли бы даже хранить шаблоны на сервере и загружать их по запросу через ajax, если хотите (хотя я бы беспокоился о количестве HTTP-запросов), чтобы ваш код и ваша разметка были полностью различимы.

Например, вот прототип шаблона для построения строки таблицы:

 <tr><td>#{name}</td><td>#{description}</td></tr>
  

У вас есть различные варианты того, где и как хранить текст шаблона:

  • Вы можете поместить его в свой собственный файл, который вы требуете загрузить через Ajax, хотя, если их много, это может привести к чрезмерным HTTP-запросам.
  • Вы можете поместить их в свой JavaScript, но тогда вы привязали свою разметку к своему JavaScript, и у меня создается впечатление, что вы не хотите этого делать.
  • Вы можете включить их на свою главную страницу с помощью display: none , извлечь их как HTML, а затем повторно использовать.

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

 var rowString = "<tr><td>#{name}</td><td>#{description}</td></tr>";
  

(Но опять же, вам может не понадобиться помещать это на самом деле в JavaScript.)

Из строки вы создаете шаблон:

 var rowTemplate = new Template(rowString);
  

А затем используйте его:

 $('tableBodyId').insert({
    bottom: rowTemplate.evaluate({
        name:        bizobject.name.escapeHTML(),
        description: bizobject.description.escapeHTML()
    })
});
  

Обратите внимание, что (к сожалению) вам придется выполнять экранирование HTML самостоятельно (поскольку шаблоны Prototype специально не привязаны к HTML, вы можете использовать их для любой ситуации, когда у вас есть шаблонная строка). Или вы можете внести довольно небольшое изменение в Template класс, чтобы сделать это за вас (это то, что я сделал, когда использовал Prototype; я фактически сделал возможным вызов функций для элементов шаблона).

Комментарии:

1. Похоже, что prototype1.4 не поддерживает шаблон. Кстати, как насчет того, если мне нужно привязать какое-то событие к элементу?

2. @hguser: Prototype 1.4 был заменен более четырех лет назад . Текущая версия 1.7. Что касается привязки: вы делаете это обычным способом после создания их экземпляра (например, после insert или чего-то еще).