На днях я работал над генератором схем JSON и хотел отображать номера строк в
Я провел небольшое исследование и нашел несколько подходов:
Мне ни один из них не понравился! Первый выглядел нечетко и не соответствовал стилям, которые я уже использовал для своих элементов
Второму требовалось множество JavaScript для поддержания этого упорядоченного списка: динамическое добавление/удаление элементов
В итоге я создал гибрид.
Это динамически создаваемый SVG, хранящийся как Пользовательское свойство CSS — и используемый в качестве фонового изображения, наследующий стили от родительского элемента
Давайте углубимся.
Во-первых, основной метод:
lineNumbers(element, numLines = 50, inline = false)
element — это элемент
Далее мы определяем префикс для пользовательского свойства:
const prefix = '--linenum-';
Прежде чем продолжить, мы проверяем, можно ли повторно использовать какое-либо существующее свойство:
if (!inline) { const styleString = document.body.getAttribute('style') || ''; const regex = new RegExp(`${prefix}[^:]*`, 'g'); const match = styleString.match(regex); if (match) { element.style.backgroundImage = `var(${match[0]})`; return; } }
Далее мы извлекаем стили из элемента, визуализируя SVG с тем же семейством шрифтов, размером шрифта, высотой строки и т. д. :
const bgColor = getComputedStyle(element).borderColor; const fillColor = getComputedStyle(element).color; const fontFamily = getComputedStyle(element).fontFamily; const fontSize = parseFloat(getComputedStyle(element).fontSize); const lineHeight = parseFloat(getComputedStyle(element).lineHeight) / fontSize; const paddingTop = parseFloat(getComputedStyle(element).paddingTop) / 2; const translateY = (fontSize * lineHeight).toFixed(2);
Нам также нужен случайный идентификатор для нашего объекта:
const id = `${prefix}${Math.random().toString(36).substr(2, 6)}`;
А теперь пришло время отрендерить SVG:
const svg = ``;
Давайте разберемся:
В разделе
Последняя часть повторяет массив, созданный из numLines, и добавляет элементы
Мы почти у цели!
Чтобы использовать сгенерированный SVG в качестве свойства url(), нам нужно закодировать его:
const encodedURI = `url("data:image/svg xml,${encodeURIComponent(svg)}")`;
И, наконец, мы устанавливаем это свойство либо для элемента, либо для тела документа:
const target = inline ? element : document.body; target.style.setProperty(id, encodedURI); element.style.backgroundImage = `var(${id})`;
И все!
Не так уж плохо, всего 610 байт, минимизировано и сжато!
Вы можете увидеть демо-версию здесь и загрузить полный сценарий здесь.
Ниже приведен упрощенный код Codepen, не использующий логику встроенных свойств:
Есть ли плюсы и минусы? Конечно, есть!
Лично для моего текущего проекта мне нужен был простой и четкий способ добавления номеров строк в JSON-предварительный просмотр внутри
Этот метод не основан на манипулировании DOM. Номера строк генерируются как один SVG и хранятся в пользовательском свойстве CSS.
Поскольку номера строк являются частью фонового изображения, они автоматически прокручиваются вместе с текстовым содержимым, что устраняет необходимость в логике ручной синхронизации.
Сохраняя сгенерированный SVG в пользовательском свойстве CSS, его можно повторно использовать в нескольких элементах. Это означает, что если нескольким элементам требуются одинаковые номера строк, все они могут ссылаться на одно и то же пользовательское свойство, избегая избыточной генерации SVG.
Упорядоченные списки более доступны для программ чтения с экрана и вспомогательных технологий, а номера строк на основе SVG могут быть проигнорированы или неправильно истолкованы.
Стилизовать отдельные номера строк в упорядоченном списке и взаимодействовать с ними очень просто. Напротив, подход SVG затрудняет настройку или добавление интерактивности к определенным номерам строк.
Пользовательские свойства SVG и CSS могут не отображаться одинаково во всех браузерах — текущая реализация имеет проблемы с Safari, где нам нужно вычесть (paddingTop / 10) из TranslateY.
Упорядоченные списки могут быть более гибкими для обработки динамических обновлений контента, таких как добавление или удаление строк, тогда как подход SVG может потребовать регенерации и повторного применения всего фонового изображения.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3