„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Erstellen eines intelligenten Editors: URLs automatisch erkennen und in Hyperlinks umwandeln

Erstellen eines intelligenten Editors: URLs automatisch erkennen und in Hyperlinks umwandeln

Veröffentlicht am 04.11.2024
Durchsuche:111

Dies ist eine Idee, die ich mir bei der Arbeit ausgedacht habe, um das Benutzererlebnis zu verbessern. Dazu gehört die Implementierung eines Textfelds, das URLs automatisch erkennt und sie in Hyperlinks umwandelt, während der Benutzer sie eingibt (Quellcode Github/AutolinkEditor). Die Implementierung dieser coolen Funktion ist etwas schwierig und die folgenden Probleme müssen behoben werden.

  • URLs im Text genau erkennen
  • Behalten Sie die Cursorposition bei, nachdem Sie die URL-Zeichenfolge in einen Hyperlink konvertiert haben
  • Aktualisieren Sie die Ziel-URL entsprechend, wenn Benutzer den Hyperlink-Text bearbeiten
  • Zeilenumbrüche im Text beibehalten
  • Unterstützt das Einfügen von Rich-Text unter Beibehaltung von Text und Zeilenumbrüchen, wobei der Textstil dem Format des Textfelds entspricht.

Building a Smart Editor: Automatically Detect URLs and Convert Them to Hyperlinks

...
 if(target && target.contentEditable){
  ...
  target.contentEditable = true;
  target.focus();
 }
...

Die Konvertierung wird durch „onkeyup“- und „onpaste“-Ereignisse gesteuert. Um die Häufigkeit von Konvertierungen zu reduzieren, wird mit „setTimeout“ ein Verzögerungsmechanismus implementiert, bei dem die Konvertierungslogik standardmäßig erst ausgelöst wird, wenn der Benutzer 1 Sekunde lang mit der Eingabe aufhört.

idle(func, delay = 1000) {
      ...
      const idleHandler = function(...args) {
        if(this[timer]){
          clearTimeout(this[timer]);
          this[timer] = null;
        }
        this[timer] = setTimeout(() => {
          func(...args);
          this[timer] = null;
        }, delay);

      };
      return idleHandler.bind(this);
    }

Identifizieren und extrahieren Sie URLs mit regulären Ausdrücken

Ich hatte nicht vor, Zeit damit zu verbringen, den perfekten regulären Ausdruck für passende URLs zu erstellen, also habe ich über eine Suchmaschine einen brauchbaren gefunden. Wenn jemand ein besseres hat, lasst es mich gerne wissen!

...
const URLRegex = /^(https?:\/\/(([a-zA-Z0-9] -?) [a-zA-Z0-9] \.) (([a-zA-Z0-9] -?) [a-zA-Z0-9] ))(:\d )?(\/.*)?(\?.*)?(#.*)?$/;
const URLInTextRegex = /(https?:\/\/(([a-zA-Z0-9] -?) [a-zA-Z0-9] \.) (([a-zA-Z0-9] -?) [a-zA-Z0-9] ))(:\d )?(\/.*)?(\?.*)?(#.*)?/;
...

if(URLRegex.test(text)){
  result  = `${escapeHtml(text)}`;
}else {
  // text contains url
  let textContent = text;
  let match;
  while ((match = URLInTextRegex.exec(textContent)) !== null) {
    const url = match[0];
    const beforeUrl = textContent.slice(0, match.index);
    const afterUrl = textContent.slice(match.index   url.length);

    result  = escapeHtml(beforeUrl);
    result  = `${escapeHtml(url)}`;
    textContent = afterUrl;
  }
  result  = escapeHtml(textContent); // Append any remaining text
}

Wiederherstellen der Cursorposition nach der Konvertierung

Berechnen Sie mit den Funktionen document.createRange und window.getSelection die Cursorposition im Text des Knotens. Da durch die Umwandlung von URLs in Hyperlinks nur Tags hinzugefügt werden, ohne den Textinhalt zu ändern, kann der Cursor basierend auf der zuvor aufgezeichneten Position wiederhergestellt werden. Weitere Einzelheiten finden Sie unter „Auswahl nach HTML-Änderung kann nicht wiederhergestellt werden, auch wenn es sich um denselben HTML-Code handelt.“

Beim Bearbeiten des Hyperlinks aktualisieren oder entfernen
Manchmal erstellen wir Hyperlinks, bei denen der Text und die Ziel-URL identisch sind (hier „einfache Hyperlinks“ genannt). Der folgende HTML-Code zeigt beispielsweise diese Art von Hyperlink.

http://www.example.com
Wenn bei solchen Links der Hyperlinktext geändert wird, sollte auch die Ziel-URL automatisch aktualisiert werden, um sie synchron zu halten. Um die Logik robuster zu machen, wird der Link wieder in einfachen Text umgewandelt, wenn der Hyperlinktext keine gültige URL mehr ist.

handleAnchor: anchor => {
  ...
    const text = anchor.textContent;
    if(URLRegex.test(text)){
      return nodeHandler.makePlainAnchor(anchor);
    }else {
      return anchor.textContent;
    }
  ...
}
...
makePlainAnchor: target => {
  ...
  const result = document.createElement("a");
  result.href = target.href;
  result.textContent = target.textContent;
  return result;
  ...
}

Um diese Funktion zu implementieren, speichere ich die „einfachen Hyperlinks“ in einem Objekt und aktualisiere sie in Echtzeit während der Ereignisse „onpaste“, „onkeyup“ und „onfocus“, um sicherzustellen, dass die obige Logik nur einfache Hyperlinks verarbeitet.

target.onpaste = initializer.idle(e => {
  ...
  inclusion = contentConvertor.indexAnchors(target);
}, 0);

const handleKeyup = initializer.idle(e => {
  ...
  inclusion = contentConvertor.indexAnchors(target);
  ...
}, 1000);

target.onkeyup = handleKeyup;
target.onfocus = e => {
  inclusion = contentConvertor.indexAnchors(target);
}

...

indexAnchors(target) {
  const inclusion = {};
  ...
  const anchorTags = target.querySelectorAll('a');
  if(anchorTags) {
    const idPrefix = target.id === "" ? target.dataset.id : target.id;

    anchorTags.forEach((anchor, index) => {
      const anchorId = anchor.dataset.id ?? `${idPrefix}-anchor-${index}`;
      if(anchor.href.replace(/\/ $/, '').toLowerCase() === anchor.textContent.toLowerCase()) {
        if(!anchor.dataset.id){
          anchor.setAttribute('data-id', anchorId);
        }
        inclusion[[anchorId]] = anchor.href;
      }
    });
  }
  return Object.keys(inclusion).length === 0 ? null : inclusion;
  ...
}

Behandeln Sie Zeilenumbrüche und Stile

Beim Bearbeiten von eingefügtem Rich-Text formatiert der Editor den Text automatisch mit den Textstilen des Editors. Um die Formatierung beizubehalten, bleiben die Tags
im Rich-Text und alle Hyperlinks erhalten. Der Umgang mit Eingabetext ist komplexer. Wenn der Benutzer die Eingabetaste drückt, um eine neue Zeile hinzuzufügen, wird dem Editor ein div-Element hinzugefügt, das der Editor durch ein
ersetzt, um die Formatierung beizubehalten.

node.childNodes.forEach(child => {
  if (child.nodeType === 1) { 
    if(child.tagName === 'A') { // anchar element
      const key = child.id === "" ? child.dataset.id : child.id;

      if(inclusion && inclusion[key]){
        const disposedAnchor = handleAnchor(child);
        if(disposedAnchor){
          if(disposedAnchor instanceof HTMLAnchorElement) {
            disposedAnchor.href = disposedAnchor.textContent;
          }
          result  = disposedAnchor.outerHTML ?? disposedAnchor;
        }
      }else {
        result  = makePlainAnchor(child)?.outerHTML ?? "";
      }
    }else { 
      result  = compensateBR(child)   this.extractTextAndAnchor(child, inclusion, nodeHandler);
    }
  } 
});

...
const ElementsOfBR = new Set([
  'block',
  'block flex',
  'block flow',
  'block flow-root',
  'block grid',
  'list-item',
]);
compensateBR: target => {
  if(target && 
    (target instanceof HTMLBRElement || ElementsOfBR.has(window.getComputedStyle(target).display))){
      return "
"; } return ""; }

Schlussfolgerungen

In diesem Artikel werden einige praktische Techniken beschrieben, die zum Implementieren eines einfachen Editors verwendet werden, z. B. allgemeine Ereignisse wie onkeyup und onpaste, die Verwendung von Selection und Range zum Wiederherstellen der Cursorposition und die Handhabung der Knoten eines Elements, um die Position des Editors zu erreichen Funktionalität. Während reguläre Ausdrücke nicht im Mittelpunkt dieses Artikels stehen, kann ein vollständiger regulärer Ausdruck die Robustheit des Editors bei der Identifizierung bestimmter Zeichenfolgen verbessern (der in diesem Artikel verwendete reguläre Ausdruck bleibt für Änderungen offen). Sie können über Github/AutolilnkEditor auf den Quellcode zugreifen, um weitere Details zu erhalten, wenn er für Ihr Projekt hilfreich ist.

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/oninebx/building-a-smart-editor-automatically-detect-urls-and-convert-them-to-hyperlinks-ilg?1 Wenn es einen Verstoß gibt, bitte Kontaktieren Sie Study_golang@163 .comdelete
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3