"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > एक स्मार्ट संपादक का निर्माण: स्वचालित रूप से यूआरएल का पता लगाएं और उन्हें हाइपरलिंक में परिवर्तित करें

एक स्मार्ट संपादक का निर्माण: स्वचालित रूप से यूआरएल का पता लगाएं और उन्हें हाइपरलिंक में परिवर्तित करें

2024-11-04 को प्रकाशित
ब्राउज़ करें:658

यह एक विचार है जो मैं उपयोगकर्ता अनुभव को बेहतर बनाने के लिए काम के दौरान लेकर आया हूं। इसमें एक टेक्स्ट बॉक्स को लागू करना शामिल है जो स्वचालित रूप से यूआरएल का पता लगाता है और उन्हें उपयोगकर्ता प्रकार (स्रोत कोड जीथब/ऑटोलिंकएडिटर) के अनुसार हाइपरलिंक में परिवर्तित करता है। इस शानदार सुविधा को लागू करना कुछ हद तक मुश्किल है, और निम्नलिखित मुद्दों पर ध्यान दिया जाना चाहिए।

  • पाठ के भीतर यूआरएल का सटीक पता लगाएं
  • यूआरएल स्ट्रिंग को हाइपरलिंक में बदलने के बाद कर्सर की स्थिति बनाए रखें
  • जब उपयोगकर्ता हाइपरलिंक टेक्स्ट को संपादित करते हैं तो लक्ष्य यूआरएल को तदनुसार अपडेट करें
  • पाठ में पंक्ति विराम सुरक्षित रखें
  • टेक्स्ट बॉक्स के प्रारूप से मेल खाने वाली टेक्स्ट शैली के साथ, टेक्स्ट और लाइन ब्रेक दोनों को बनाए रखते हुए समृद्ध टेक्स्ट चिपकाने का समर्थन करें।

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

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

रूपांतरण "ऑनकीअप" और "ऑनपेस्ट" घटनाओं द्वारा संचालित होता है। रूपांतरणों की आवृत्ति को कम करने के लिए, "सेटटाइमआउट" के साथ एक विलंब तंत्र लागू किया जाता है, जहां उपयोगकर्ता द्वारा डिफ़ॉल्ट रूप से 1 सेकंड के लिए टाइप करना बंद करने के बाद ही रूपांतरण तर्क चालू हो जाता है।

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);
    }

नियमित अभिव्यक्ति के साथ यूआरएल को पहचानें और निकालें

मेरा मिलान यूआरएल के लिए सही रेगेक्स तैयार करने में समय बर्बाद करने का इरादा नहीं था, इसलिए मुझे एक खोज इंजन के माध्यम से एक उपयोगी रेगेक्स मिला। यदि किसी के पास इससे बेहतर कोई हो, तो बेझिझक मुझे बताएं!

...
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
}

रूपांतरण के बाद कर्सर की स्थिति बहाल करना

document.createRange और window.getSelectionfunctions के साथ, नोड के टेक्स्ट के भीतर कर्सर की स्थिति की गणना करें। चूंकि यूआरएल को हाइपरलिंक में परिवर्तित करने से टेक्स्ट सामग्री को संशोधित किए बिना केवल टैग जुड़ते हैं, कर्सर को पहले से रिकॉर्ड की गई स्थिति के आधार पर पुनर्स्थापित किया जा सकता है। अधिक विवरण के लिए, कृपया HTML संशोधित करने के बाद चयन को पुनर्स्थापित नहीं किया जा सकता पढ़ें, भले ही वह वही HTML हो।

हाइपरलिंक संपादित करते समय अपडेट करें या हटाएं
कभी-कभी हम हाइपरलिंक बनाते हैं जहां टेक्स्ट और लक्ष्य यूआरएल समान होते हैं (यहां 'सरल हाइपरलिंक' कहा जाता है)। उदाहरण के लिए, निम्नलिखित HTML इस प्रकार का हाइपरलिंक दिखाता है।

http://www.example.com
ऐसे लिंक के लिए, जब हाइपरलिंक टेक्स्ट को संशोधित किया जाता है, तो उन्हें सिंक में रखने के लिए लक्ष्य URL को भी स्वचालित रूप से अपडेट किया जाना चाहिए। तर्क को और अधिक मजबूत बनाने के लिए, जब हाइपरलिंक टेक्स्ट वैध यूआरएल नहीं रह जाएगा तो लिंक को वापस सादे टेक्स्ट में बदल दिया जाएगा।

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;
  ...
}

इस सुविधा को लागू करने के लिए, मैं 'सरल हाइपरलिंक्स' को एक ऑब्जेक्ट में संग्रहीत करता हूं और उन्हें ऑनपेस्ट, ऑनकीअप और ऑनफोकस इवेंट के दौरान वास्तविक समय में अपडेट करता हूं ताकि यह सुनिश्चित हो सके कि उपरोक्त तर्क केवल सरल हाइपरलिंक्स को संभालता है।

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;
  ...
}

लाइन ब्रेक और शैलियों को संभालें

चिपकाए गए रिच टेक्स्ट को संभालते समय, संपादक स्वचालित रूप से संपादक की टेक्स्ट शैलियों के साथ टेक्स्ट को स्टाइल करेगा। फ़ॉर्मेटिंग बनाए रखने के लिए, रिच टेक्स्ट में
टैग और सभी हाइपरलिंक संरक्षित किए जाएंगे। इनपुट टेक्स्ट को संभालना अधिक जटिल है। जब उपयोगकर्ता एक नई लाइन जोड़ने के लिए Enter दबाता है, तो संपादक में एक div तत्व जोड़ा जाता है, जिसे संपादक फ़ॉर्मेटिंग बनाए रखने के लिए
से बदल देता है।

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 ""; }

निष्कर्ष

यह लेख एक साधारण संपादक को लागू करने के लिए उपयोग की जाने वाली कुछ व्यावहारिक तकनीकों का वर्णन करता है, जैसे कि ऑनकीप और ऑनपेस्ट जैसी सामान्य घटनाएं, कर्सर की स्थिति को बहाल करने के लिए चयन और रेंज का उपयोग कैसे करें, और संपादक की स्थिति को प्राप्त करने के लिए किसी तत्व के नोड्स को कैसे संभालना है कार्यक्षमता. हालाँकि नियमित अभिव्यक्तियाँ इस लेख का फोकस नहीं हैं, एक पूर्ण रेगेक्स विशिष्ट स्ट्रिंग्स की पहचान करने में संपादक की मजबूती को बढ़ा सकता है (इस लेख में प्रयुक्त रेगेक्स संशोधन के लिए खुला रहेगा)। यदि यह आपके प्रोजेक्ट के लिए उपयोगी है तो अधिक विवरण प्राप्त करने के लिए आप Github/AutolilnkEditor के माध्यम से स्रोत कोड तक पहुंच सकते हैं।

विज्ञप्ति वक्तव्य यह आलेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/oninebx/building-a-smart-editor-automatically-detect-urls-and-convert-them-to-hyperlinks-ilg?1 यदि कोई उल्लंघन है, तो कृपया स्टडी_गोलंग@163 .comडिलीट से संपर्क करें
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3