Рефакторинг HTML-генерирующего JavaScript

К сожалению, в моем проекте мы генерируем много HTML-кода в JavaScript, например:

var html = new StringBuffer();
html.append("<td class=\"gr-my-deals\"><a href=\"").append(deal.url).append("\" target=\"_blank\">").append(deal.description).append("</a></td>");

У меня есть две конкретные жалобы по этому поводу:

  1. Использование экранированных двойных кавычек (\ ») в строке HTML. Их следует заменить одинарными кавычками (‘), чтобы улучшить читаемость.
  2. Использование .append () вместо оператора объединения строк JavaScript «+».

Применение обоих этих предложений дает следующую эквивалентную строку кода, которую я считаю более читаемой:

var html = "<td class=’gr-my-deals’><a href=’" + deal.url + "’ target=’_blank’>" + deal.description + "</a></td>";

Сейчас я ищу способ автоматически преобразовать первую строку кода во вторую. Все, что я до сих пор придумал, - это выполнить следующую операцию поиска и замены всего нашего кода Javascript:

Find:    ).append(  
Replace: +

Это преобразует строку кода, показанную выше, в:

html.append("<td class=\"gr-my-deals\"><a href=\"" + deal.url + "\" target=\"_blank\">" + deal.description + "</a></td>)";

Это должно безопасно удалить все, кроме первого оператора append (). К сожалению, я не могу придумать безопасного способа автоматического преобразования экранированных двойных кавычек в одинарные. Имейте в виду, что я не могу просто выполнить поиск / замену, потому что в некоторых случаях вам действительно нужно использовать экранированные двойные кавычки. Обычно это происходит, когда вы создаете HTML, который включает вложенный JS, и этот JS содержит строковые параметры, например.

function makeLink(stringParam) {

  var sb = new StringBuffer();
  sb.append("<a href=\"JavaScript:myFunc('" + stringParam + "');\">");
}

Мои вопросы (наконец):

  • Есть ли лучший способ безопасно заменить вызовы 'append ()' на '+'
  • Есть ли способ безопасно заменить экранированные двойные кавычки одинарными кавычками, регулярным выражением?

Ваше здоровье, Дон

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
742
5

Ответы 5

Вот функция формата строки, которая помогает устранить конкатенацию и некрасивые значения замены.

function stringFormat( str ) {

    for( i = 0; i < arguments.length; i++ ) {
        var r = new RegExp( '\\{' + ( i ) + '\\}','gm' );

        str = str.replace( r, arguments[ i + 1 ] );    
    }
    return str;
}

Используйте это так:

var htmlMask = "<td class=’gr-my-deals’><a href=’{0}’ target=’_blank’>{1}</a></td>";

var x = stringFormat( htmlMask, deal.Url, deal.description ); 

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

Dónal 29.10.2008 19:10

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

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

Shog9 29.10.2008 19:15

«Микро-шаблоны» Джона Ресига - очень эффективный и очень лаконичный фрагмент кода. Это также хорошо, если вы ищете способ заставить коллег делать двойную работу. Это где-то в сообщениях, которые вы связали, но я отправлю его снова: ejohn.org/blog/javascript-micro-templating

Prestaul 29.10.2008 19:15

Это хорошее предложение, но не то, что в краткосрочной перспективе я просто ищу автоматический способ улучшить код (например, найти-заменить)

Dónal 29.10.2008 19:47

Как предполагает Shog9, существует несколько хороших движков для создания шаблонов JavaScript. Вот пример того, как вы могли бы использовать мой, Простые шаблоны jQuery:

var tmpl, vals, html;

tmpl  = '<td class = "gr-my-deals">';
tmpl += '<a href = "#{href}">#{text}</a>';
tmpl += '</td>';

vals  = {
    href : 'http://example.com/example',
    text : 'Click me!'
};

html  = $.tmpl(tmpl, vals);

Есть веская причина, по которой вы должны использовать StringBuffer () вместо конкатенации строк в JavaScript. StringBuffer () и его метод append () используют Array и Array join () для объединения строки. Если у вас есть значительное количество частичных строк, которые вы хотите присоединить, это, как известно, более быстрый способ сделать это.

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

Dónal 30.10.2008 06:28

Каждому свое - метод, о котором вы говорите, не будет поддерживать каждый разработчик. FTW, упомянутые системы шаблонов, включая подход Джона Ресига, используют Array и join ().

user4903 30.10.2008 14:50

@ hal10001: у вас правильная производительность WRT (не то чтобы это должно иметь большое значение для отмеченных кратких примеров). Но StringBuffer.append () мучительно многословен. Использование литералов массива + join () (["<a href='", deal.url, "'target='_blank'>", deal.description, "</a>"] .join ("")) приведет к быть предпочтительнее.

Shog9 30.10.2008 20:50

Шаблоны? Создание шаблонов - отстой! Вот как я бы написал ваш код:

TD({ "class" : "gr-my-deals" },
   A({ href : deal.url,
       target : "_blank"},
     deal.description ))

Я использую 20-строчную библиотеку под названием DOMination, которую я отправлю всем, кто попросит, для поддержки такого кода.

Преимущества многочисленны, но некоторые из наиболее очевидных:

  • разборчивый, интуитивно понятный код
  • легко учиться и писать
  • компактный код (без закрывающих тегов, только закрывающие скобки)
  • хорошо понятны редакторам, минификаторам и т. д. с поддержкой JavaScript
  • решает некоторые проблемы, связанные с браузером (например, разницу между rowSpan и rowspan в IE)
  • хорошо интегрируется с CSS

(Ваш пример, BTW, подчеркивает единственный недостаток DOMination: любые атрибуты HTML, которые также являются зарезервированными словами JavaScript, в данном случае class, должны быть заключены в кавычки, чтобы не случилось плохого.)

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