」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 SVG 的行號

使用 SVG 的行號

發佈於2024-08-23
瀏覽:482

前幾天我正在開發 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);
    

    我們的財產也需要一個隨機 ID:

    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,不使用內聯屬性邏輯:


    優點和缺點

    有優點和缺點嗎?當然有!

    就我個人而言,對於我目前的項目,我需要一種簡單、清晰的方法來將行號添加到

    優點

    減少 DOM 操作

    此方法不依賴操作 DOM。行號以單一 SVG 生成,儲存在 CSS 自訂屬性中。

    自動同步

    由於行號是背景圖像的一部分,它們會隨著文字內容自動滾動,而無需手動同步邏輯。

    跨元素的可重複使用性

    透過將產生的 SVG 儲存在 CSS 自訂屬性中,它可以在多個元素之間重複使用。這意味著如果多個元素需要相同的行號,它們都可以引用相同的自訂屬性,從而避免冗餘的 SVG 生成。

    可擴展性

    SVG 的向量特性確保行號在任何縮放等級下都保持清晰。

    缺點

    無障礙

    螢幕閱讀器和輔助技術更容易存取有序列表,而基於 SVG 的行號可能會被忽略或誤解。

    客製化複雜性

    對有序清單中的各個行號進行樣式設定和互動非常簡單。相較之下,SVG 方法使得自訂特定行號或在特定行號上新增互動性變得更加困難。

    瀏覽器相容性

    SVG 和 CSS 自訂屬性可能無法在所有瀏覽器中一致地呈現 - 目前的實作在 Safari 中存在問題,我們需要從 translateY 中扣除 (paddingTop / 10)。

    動態內容處理

    有序清單可以更靈活地處理動態內容更新,例如新增或刪除行,而 SVG 方法可能需要重新產生和重新套用整個背景影像。

  • 版本聲明 本文轉載於:https://dev.to/madsstoumann/line-numbers-for-using-svg-1216?1如有侵犯,請聯絡[email protected]刪除
    最新教學 更多>

    免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

    Copyright© 2022 湘ICP备2022001581号-3