«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Номера строк для использования SVG

Номера строк для использования SVG

Опубликовано 23 августа 2024 г.
Просматривать:414

На днях я работал над генератором схем JSON и хотел отображать номера строк в

Я провел небольшое исследование и нашел несколько подходов:

  1. Использование фонового изображения (TinyMCE делает это с использованием PNG)
  2. Использование упорядоченного списка
      .

Мне ни один из них не понравился! Первый выглядел нечетко и не соответствовал стилям, которые я уже использовал для своих элементов

Второму требовалось множество JavaScript для поддержания этого упорядоченного списка: динамическое добавление/удаление элементов

  • , синхронизация событий прокрутки и многое другое.

    В итоге я создал гибрид.

    Это динамически создаваемый SVG, хранящийся как Пользовательское свойство CSS — и используемый в качестве фонового изображения, наследующий стили от родительского элемента

    Line Numbers for <textarea> с использованием SVG

    Давайте углубимся.


    JavaScript

    Во-первых, основной метод:

    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 = `
      ${Array.from({ length: numLines }, (_, i) => `${i   1}`).join("")}
    `;
    

    Давайте разберемся:

    В разделе

    Последняя часть повторяет массив, созданный из numLines, и добавляет элементы к основному SVG.

    Мы почти у цели!


    Чтобы использовать сгенерированный 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

    Этот метод не основан на манипулировании DOM. Номера строк генерируются как один SVG и хранятся в пользовательском свойстве CSS.

    Автоматическая синхронизация

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

    Повторное использование элементов

    Сохраняя сгенерированный SVG в пользовательском свойстве CSS, его можно повторно использовать в нескольких элементах. Это означает, что если нескольким элементам требуются одинаковые номера строк, все они могут ссылаться на одно и то же пользовательское свойство, избегая избыточной генерации SVG.

    Масштабируемость

    Векторная природа SVG гарантирует, что номера строк останутся четкими и четкими при любом уровне масштабирования.

    Минусы

    Доступность

    Упорядоченные списки более доступны для программ чтения с экрана и вспомогательных технологий, а номера строк на основе SVG могут быть проигнорированы или неправильно истолкованы.

    Сложность настройки

    Стилизовать отдельные номера строк в упорядоченном списке и взаимодействовать с ними очень просто. Напротив, подход SVG затрудняет настройку или добавление интерактивности к определенным номерам строк.

    Совместимость браузера

    Пользовательские свойства SVG и CSS могут не отображаться одинаково во всех браузерах — текущая реализация имеет проблемы с Safari, где нам нужно вычесть (paddingTop / 10) из TranslateY.

    Динамическая обработка контента

    Упорядоченные списки могут быть более гибкими для обработки динамических обновлений контента, таких как добавление или удаление строк, тогда как подход SVG может потребовать регенерации и повторного применения всего фонового изображения.

  • Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/madsstoumann/line-numbers-for-using-svg-1216?1. В случае нарушения авторских прав свяжитесь с [email protected], чтобы удалить ее.
    Последний учебник Более>

    Изучайте китайский

    Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

    Copyright© 2022 湘ICP备2022001581号-3