「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > SVGを使用するための行番号

SVGを使用するための行番号

2024 年 8 月 23 日に公開
ブラウズ:339

先日、JSON スキーマ ジェネレーターに取り組んでいて、

いくつか調査したところ、複数のアプローチが見つかりました:

  1. 背景画像の使用 (TinyMCE は PNG を使用して行います)
    1. 順序付きリストを使用します。

どれも気に入らなかったです!最初のものは見た目が鮮明ではなく、

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