لقد واجهت مؤخرًا وظيفة مثل هذه عند العمل في مشروع: تسليط الضوء على الكلمات الرئيسية في صفحات الويب.
اعتقدت أنها ستكون عملية بسيطة يمكن إجراؤها باستخدام استبدال InnerHTML، لكنني واجهت العديد من المشكلات. تسجل هذه المقالة هذه المشاكل والحل النهائي الأمثل، على أمل أن تكون مفيدة للأصدقاء الذين لديهم نفس التجربة. إذا كنت مهتمًا بالنتائج فقط، فتجاهل العملية وتخطاها لرؤية النتائج~
الممارسة الشائعة: الاستبدال المنتظمالفكرة: إذا كنت تريد تمييز العناصر، فأنت بحاجة إلى استخراج الكلمات الرئيسية ولفها في علامات، ثم ضبط نمط العلامات. استخدم InnerHTML أو outHTML، ولكن لا تستخدم InnerText أو outText.
const regex = new RegExp(keyword,g)element.innerHTML = element.innerHTML.replace(regex,<b class=a>+keyword+</b>)element.classList.add(highlight)
المخاطر الخفية للقيام بذلك هي كما يلي:
()/div<div id=parent> <div class=test>اختبار</div> </div>
يقوم عنصر العقدة الأصلية للكلمة الرئيسية بإجراء معالجة صبغ الخلفية من خلال الفئة، مما يلوث DOM الأصلي إلى حد ما وقد يؤثر على إعادة تحديد موضع العنصر. (كبرنامج إضافي، نأمل في تغيير DOM الأصلي بأقل قدر ممكن)
التحسين العادي الأول: عناصر العملية الموجودة داخل العلامات فقطvar formatKeyword = text.replace(/[-////^$*+?.()|[/]{}]/g, '//$&') // الهروب من الأحرف الخاصة الموجودة في الكلمة الأساسية، على سبيل المثال، /.var finder = new RegExp(>.*?++.*?<) // استخرج النص الموجود في العلامة لتجنب التشغيل الخاطئ للفئة والمعرف وما إلى ذلك. element.innerHTML = element.innerHTML.replace(finder,function(matched){ return matched.replace(text,<br>+text+</br>)})//استبدال الكلمات الرئيسية في النص المستخرج داخل العلامة
يمكن أن يحل هذا معظم المشكلات، لكن المشكلة التي لا تزال موجودة هي أنه طالما كان هناك رمز < مشابه في سمة العلامة، فسيتم كسر قواعد المطابقة وسيكون محتوى الاستخراج العادي خاطئًا ويمكن لمجموعة بيانات HTML5 تخصيص أي محتوى. لذلك لا يمكن تجنب هذه الأحرف الخاصة.
<div dataset=p>d>استبدال</div>التحسين العادي 2: مسح العلامات التي قد تتأثر
<div id=keyword>keyword</div> =》استبدل علامة الإغلاق بمتغير [replaced1]keyword[replaced2]// لن تتم معالجة المعرف=الكلمة الرئيسية في علامة الإغلاق=》[replaced1]<b>keyword </b >[replaced2] =》استبدل المتغير المؤقت بالعلامة الأصلية <div id=keyword><b>الكلمة الرئيسية</b></div>
والأهم من ذلك، أن هذه الطريقة لا يمكنها استخراج العلامة بشكل صحيح عندما تحتوي قيمة العلامة على الرمز <>.
باختصار، بعد العديد من المحاولات، لم يتم التعامل مع المواقف المختلفة بشكل فعال من خلال التنظيم. ثم غيرت رأيي وعالجته من خلال العقد بدلاً من السلاسل. يمكن لـ element.childNodes تنظيف معلومات التداخل في العلامات بشكل أكثر فعالية.
[الحل الأمثل] المعالجة من خلال عقد DOM<div id=parent> الكلمة الرئيسية 1 <span id=child> الكلمة الرئيسية 2 </span> </div>
احصل على جميع العقد الفرعية من خلالparent.childNodes. يمكن استبدال العقدة الفرعية بـ innerText.replce(keyword,result)
للحصول على تأثير التمييز المطلوب، كما يلي: <span id=child><b>keyword</b> 2</span>
(المعالجة العودية: عندما يكون الطفل يتم تنفيذ عملية الاستبدال عندما لا تحتوي العقدة على عقد فرعية).
ومع ذلك، فإن الكلمة الأساسية 1 هي عقدة نصية ويمكنها فقط تعديل محتوى النص، ولا يمكنها إضافة HTML، ولا يمكنها التحكم في نمطها بشكل مستقل. لا يمكن تحويل العقد النصية إلى عقد عادية، وهو الأمر الأكثر إزعاجًا أيضًا.
أخيرًا ~، هنا يأتي محور هذه المقالة، وبسبب هذه الوظيفة، أصبحت على اتصال جدي بالعقد النصية لأول مرة. من هنا اكتشفت النص، واستخدمت طريقة قطع العقد النصية واستبدالها لتحقيق التمييز.
رمز المصدر واستعادة النقاط البارزة راجع رمز المصدر
const reg = new RegExp(keyword.replace(/[-////^$*+?.()|[/]{}]/g, '//$&'))highlight = function (node,reg ){ if (node.nodeType == 3) { // معالجة العقد النصية فقط const match =node.data.match(new RegExp(reg)); if (match) { const HighlightEl = document.createElement(b); HighlightEl.dataset.highlight=y const wordNode =node.splitText(match.index) wordNode.splitText(match[0].length); // قص إلى ثلاث عقد نصية بعد الكلمة الرئيسية الأولى وconst wordNew = document.createTextNode(wordNode.data); HighlightEl.appendChild(wordNew);//highlight تم إنشاء العقدة بنجاح wordNode.parentNode.replaceChild(highlightEl, wordNode); // استبدال العقدة النصية} } else if (node.nodeType == 1 &&node.dataset.highlight!=y ) { for (var i = 0 ; i <node.childNodes.length; i++) { Highlight(node.childNodes[i], reg);تلخيص
ما ورد أعلاه هو الحل الأمثل لتسليط الضوء على الكلمات الرئيسية في HTML الذي قدمه المحرر وآمل أن يكون مفيدًا لك. إذا كانت لديك أي أسئلة، فيرجى ترك رسالة لي وسيقوم المحرر بالرد عليك في الوقت المناسب. أود أيضًا أن أشكر الجميع على دعمكم لموقع VeVb للفنون القتالية!