जावास्क्रिप्ट का उपयोग करके टेक्स्ट को हाइलाइट कैसे करें


98

क्या कोई मुझे जावास्क्रिप्ट फ़ंक्शन के साथ मदद कर सकता है जो वेब पेज पर पाठ को उजागर कर सकता है। और आवश्यकता यह है कि - केवल एक बार हाइलाइट करें, न कि टेक्स्ट की सभी घटनाओं को हाइलाइट करें जैसा कि हम खोज के मामले में करते हैं।


4
यदि आप फ़ंक्शन का कोड पोस्ट करते हैं तो हम मदद कर पाएंगे। अगर आप हमसे इस तरह का कोई फंक्शन बनाने के लिए कहते हैं ... तो इसकी संभावना कम है। आपको खुद ही कुछ करना होगा। कुछ करना शुरू करें और जब आप फंस जाएं तो वापस आ जाएं।
फेलिक्स क्लिंग

7
हाँ, मैंने पढ़ा है कि कैसे पूछें और मैंने अपने दम पर कुछ किया है, लेकिन मैं अटक गया और इसीलिए मैंने पूछा। मैं एंड्रॉइड पर काम करता हूं और मुझे जावास्क्रिप्ट का बहुत कम ज्ञान है यही कारण है कि मैं इसे अपने दम पर करने में सक्षम नहीं हूं। पहले मैं एक अलग जावास्क्रिप्ट का उपयोग कर रहा था जो कि काम करता था लेकिन कुछ सीमाओं के बिना नहीं। मैंने यह प्रश्न करते समय सही शब्दों का इस्तेमाल नहीं किया होगा और मुझे इसके लिए खेद है लेकिन कृपया अन्यथा के बारे में न सोचें।
अंकित

1
यह प्लगइन आपके लिए रुचि का हो सकता है: github.com/julmot/jmHighlight । यह कीवर्ड को अलग-अलग या एक शब्द के रूप में हाइलाइट कर सकता है, अपने कस्टम तत्व और क्लासनाम के साथ मैच को हाइलाइट कर सकता है और डायक्रिटिक्स की खोज भी कर सकता है। शीर्ष पर यह आपको उस संदर्भ को फ़िल्टर करने की अनुमति देता है जिसमें मैचों की खोज करना है।
यार

1
Regex way के बाद चेकआउट करें ... stackoverflow.com/a/45519242/2792959

मैं यहाँ कि पर एक लेख तैयार, exhesham.com/2017/11/20/...
हेशाम यासिन

जवाबों:


100

आप jquery हाइलाइट प्रभाव का उपयोग कर सकते हैं ।

लेकिन अगर आप कच्चे जावास्क्रिप्ट कोड में रुचि रखते हैं, तो एक नज़र डालिए कि मुझे बस एक HTML में कॉपी पेस्ट क्या मिला, फ़ाइल खोलें और "हाइलाइट" पर क्लिक करें - यह "लोमड़ी" शब्द को उजागर करना चाहिए। प्रदर्शन के हिसाब से मुझे लगता है कि यह छोटे पाठ और एकल पुनरावृत्ति (जैसे आपके द्वारा निर्दिष्ट) के लिए करना होगा

function highlight(text) {
  var inputText = document.getElementById("inputText");
  var innerHTML = inputText.innerHTML;
  var index = innerHTML.indexOf(text);
  if (index >= 0) { 
   innerHTML = innerHTML.substring(0,index) + "<span class='highlight'>" + innerHTML.substring(index,index+text.length) + "</span>" + innerHTML.substring(index + text.length);
   inputText.innerHTML = innerHTML;
  }
}
.highlight {
  background-color: yellow;
}
<button onclick="highlight('fox')">Highlight</button>

<div id="inputText">
  The fox went over the fence
</div>

संपादन:

का उपयोग करते हुए replace

मुझे लगता है कि इस जवाब ने कुछ लोकप्रियता हासिल की, मैंने सोचा कि मैं इस पर जोड़ सकता हूं। आप आसानी से प्रतिस्थापित का उपयोग भी कर सकते हैं

"the fox jumped over the fence".replace(/fox/,"<span>fox</span>");

या कई घटनाओं के लिए (प्रश्न के लिए प्रासंगिक नहीं है, लेकिन टिप्पणियों में पूछा गया था) आप बस globalनियमित अभिव्यक्ति को जोड़ते हैं ।

"the fox jumped over the other fox".replace(/fox/g,"<span>fox</span>");

आशा है कि यह कटु टिप्पणी करने वालों की मदद करता है।

HTML को पूरे वेब-पेज पर बदलना

HTML को पूरे वेब-पेज के लिए बदलने के लिए, आपको innerHTMLदस्तावेज़ के मुख्य भाग को संदर्भित करना चाहिए ।

document.body.innerHTML


आपके उत्तर के लिए बहुत बहुत धन्यवाद, लेकिन क्या आप मुझे यह भी बता सकते हैं कि जावास्क्रिप्ट में रंग कैसे निर्दिष्ट करें
अंकित

आप के "<span class='highlight'>"साथ की जगह ले सकते हैं "<span style='color: " + color + ";'>", रंग कुछ ऐसा होना चाहिएvar color = "#ff0000";
यनिरो

क्या होगा अगर मैं पूरे पृष्ठ पर किसी शब्द की सभी घटनाओं को उजागर करना चाहता हूं? @guy mograbi
Baqer Naqvi

4
एक सरल "बदलें" का उपयोग करना एक बुरा विचार है । मैंने यहाँ क्यों वर्णित किया है: stackoverflow.com/a/32758672/3894981
दोस्त

2
यह एक महान विचार नहीं है क्योंकि यह HTML टैग / विशेषताओं / आदि को उजागर करने का प्रयास करेगा। उदाहरण के लिए, इस मामले में क्या होगा: <img src="fox.jpg" /> आपको अमान्य HTML मिलेगा जो कि ऐसा दिखेगा: <img src="<span class='highlight'>fox</span>.jpg" /> अच्छा नहीं
dcporter7

46

यहां दिए जाने वाले समाधान काफी खराब हैं।

  1. आप रेगेक्स का उपयोग नहीं कर सकते, क्योंकि इस तरह से, आप HTML टैग में खोज / हाइलाइट करते हैं।
  2. आप रेगेक्स का उपयोग नहीं कर सकते, क्योंकि यह UTF * (गैर-लैटिन / अंग्रेजी वर्णों के साथ कुछ भी) के साथ ठीक से काम नहीं करता है।
  3. आप सिर्फ एक आंतरिक HTML.replace नहीं कर सकते, क्योंकि यह तब काम नहीं करता है जब वर्णों में एक विशेष HTML संकेतन होता है, उदाहरण के &amp;लिए & के &lt;लिए <, के &gt;लिए>, &auml;ä के &ouml;लिए ö के &uuml;लिए &szlig;for, आदि के लिए।

आपको क्या करने की आवश्यकता है:

HTML दस्तावेज़ के माध्यम से लूप करें, सभी टेक्स्ट नोड्स ढूंढें, प्राप्त करें textContent, हाइलाइट-टेक्स्ट की स्थिति प्राप्त करें indexOf(एक वैकल्पिक के साथ toLowerCaseयदि यह केस-असंवेदनशील होना चाहिए), पहले के indexofरूप में सब कुछ textNodeसंलग्न करें, मिलान किए गए पाठ को हाइलाइट अवधि के साथ जोड़ें। और बाकी टेक्स्टनोड के लिए दोहराएं (हाइलाइट स्ट्रिंग कई बार हो सकती हैtextContent )।

इसके लिए यह कोड है:

var InstantSearch = {

    "highlight": function (container, highlightText)
    {
        var internalHighlighter = function (options)
        {

            var id = {
                container: "container",
                tokens: "tokens",
                all: "all",
                token: "token",
                className: "className",
                sensitiveSearch: "sensitiveSearch"
            },
            tokens = options[id.tokens],
            allClassName = options[id.all][id.className],
            allSensitiveSearch = options[id.all][id.sensitiveSearch];


            function checkAndReplace(node, tokenArr, classNameAll, sensitiveSearchAll)
            {
                var nodeVal = node.nodeValue, parentNode = node.parentNode,
                    i, j, curToken, myToken, myClassName, mySensitiveSearch,
                    finalClassName, finalSensitiveSearch,
                    foundIndex, begin, matched, end,
                    textNode, span, isFirst;

                for (i = 0, j = tokenArr.length; i < j; i++)
                {
                    curToken = tokenArr[i];
                    myToken = curToken[id.token];
                    myClassName = curToken[id.className];
                    mySensitiveSearch = curToken[id.sensitiveSearch];

                    finalClassName = (classNameAll ? myClassName + " " + classNameAll : myClassName);

                    finalSensitiveSearch = (typeof sensitiveSearchAll !== "undefined" ? sensitiveSearchAll : mySensitiveSearch);

                    isFirst = true;
                    while (true)
                    {
                        if (finalSensitiveSearch)
                            foundIndex = nodeVal.indexOf(myToken);
                        else
                            foundIndex = nodeVal.toLowerCase().indexOf(myToken.toLowerCase());

                        if (foundIndex < 0)
                        {
                            if (isFirst)
                                break;

                            if (nodeVal)
                            {
                                textNode = document.createTextNode(nodeVal);
                                parentNode.insertBefore(textNode, node);
                            } // End if (nodeVal)

                            parentNode.removeChild(node);
                            break;
                        } // End if (foundIndex < 0)

                        isFirst = false;


                        begin = nodeVal.substring(0, foundIndex);
                        matched = nodeVal.substr(foundIndex, myToken.length);

                        if (begin)
                        {
                            textNode = document.createTextNode(begin);
                            parentNode.insertBefore(textNode, node);
                        } // End if (begin)

                        span = document.createElement("span");
                        span.className += finalClassName;
                        span.appendChild(document.createTextNode(matched));
                        parentNode.insertBefore(span, node);

                        nodeVal = nodeVal.substring(foundIndex + myToken.length);
                    } // Whend

                } // Next i 
            }; // End Function checkAndReplace 

            function iterator(p)
            {
                if (p === null) return;

                var children = Array.prototype.slice.call(p.childNodes), i, cur;

                if (children.length)
                {
                    for (i = 0; i < children.length; i++)
                    {
                        cur = children[i];
                        if (cur.nodeType === 3)
                        {
                            checkAndReplace(cur, tokens, allClassName, allSensitiveSearch);
                        }
                        else if (cur.nodeType === 1)
                        {
                            iterator(cur);
                        }
                    }
                }
            }; // End Function iterator

            iterator(options[id.container]);
        } // End Function highlighter
        ;


        internalHighlighter(
            {
                container: container
                , all:
                    {
                        className: "highlighter"
                    }
                , tokens: [
                    {
                        token: highlightText
                        , className: "highlight"
                        , sensitiveSearch: false
                    }
                ]
            }
        ); // End Call internalHighlighter 

    } // End Function highlight

};

तो आप इसे इस तरह से उपयोग कर सकते हैं:

function TestTextHighlighting(highlightText)
{
    var container = document.getElementById("testDocument");
    InstantSearch.highlight(container, highlightText);
}

यहाँ एक उदाहरण HTML दस्तावेज़ है

<!DOCTYPE html>
<html>
    <head>
        <title>Example of Text Highlight</title>
        <style type="text/css" media="screen">
            .highlight{ background: #D3E18A;}
            .light{ background-color: yellow;}
        </style>
    </head>
    <body>
        <div id="testDocument">
            This is a test
            <span> This is another test</span>
            äöüÄÖÜäöüÄÖÜ
            <span>Test123&auml;&ouml;&uuml;&Auml;&Ouml;&Uuml;</span>
        </div>
    </body>
</html>

वैसे, यदि आप किसी डेटाबेस में खोज करते हैं LIKE,
जैसेWHERE textField LIKE CONCAT('%', @query, '%') [जो आपको नहीं करना चाहिए, आपको फुलटेक्स्ट-सर्च या ल्यूसीन का उपयोग करना चाहिए], तो आप हर वर्ण को \ _ से बच सकते हैं और SQL-एस्केप-स्टेटमेंट जोड़ सकते हैं, इस तरह से आपको विशेष वर्ण मिलेंगे जो LIKE-अभिव्यक्तियाँ हैं।

जैसे

WHERE textField LIKE CONCAT('%', @query, '%') ESCAPE '\'

और @query का मान नहीं है '%completed%'लेकिन'%\c\o\m\p\l\e\t\e\d%'

(परीक्षण, SQL- सर्वर और PostgreSQL के साथ काम करता है, और हर दूसरे RDBMS सिस्टम जो ESCAPE का समर्थन करता है)


एक संशोधित टाइपस्क्रिप्ट-संस्करण:

namespace SearchTools 
{


    export interface IToken
    {
        token: string;
        className: string;
        sensitiveSearch: boolean;
    }


    export class InstantSearch 
    {

        protected m_container: Node;
        protected m_defaultClassName: string;
        protected m_defaultCaseSensitivity: boolean;
        protected m_highlightTokens: IToken[];


        constructor(container: Node, tokens: IToken[], defaultClassName?: string, defaultCaseSensitivity?: boolean)
        {
            this.iterator = this.iterator.bind(this);
            this.checkAndReplace = this.checkAndReplace.bind(this);
            this.highlight = this.highlight.bind(this);
            this.highlightNode = this.highlightNode.bind(this);    

            this.m_container = container;
            this.m_defaultClassName = defaultClassName || "highlight";
            this.m_defaultCaseSensitivity = defaultCaseSensitivity || false;
            this.m_highlightTokens = tokens || [{
                token: "test",
                className: this.m_defaultClassName,
                sensitiveSearch: this.m_defaultCaseSensitivity
            }];
        }


        protected checkAndReplace(node: Node)
        {
            let nodeVal: string = node.nodeValue;
            let parentNode: Node = node.parentNode;
            let textNode: Text = null;

            for (let i = 0, j = this.m_highlightTokens.length; i < j; i++)
            {
                let curToken: IToken = this.m_highlightTokens[i];
                let textToHighlight: string = curToken.token;
                let highlightClassName: string = curToken.className || this.m_defaultClassName;
                let caseSensitive: boolean = curToken.sensitiveSearch || this.m_defaultCaseSensitivity;

                let isFirst: boolean = true;
                while (true)
                {
                    let foundIndex: number = caseSensitive ?
                        nodeVal.indexOf(textToHighlight)
                        : nodeVal.toLowerCase().indexOf(textToHighlight.toLowerCase());

                    if (foundIndex < 0)
                    {
                        if (isFirst)
                            break;

                        if (nodeVal)
                        {
                            textNode = document.createTextNode(nodeVal);
                            parentNode.insertBefore(textNode, node);
                        } // End if (nodeVal)

                        parentNode.removeChild(node);
                        break;
                    } // End if (foundIndex < 0)

                    isFirst = false;


                    let begin: string = nodeVal.substring(0, foundIndex);
                    let matched: string = nodeVal.substr(foundIndex, textToHighlight.length);

                    if (begin)
                    {
                        textNode = document.createTextNode(begin);
                        parentNode.insertBefore(textNode, node);
                    } // End if (begin)

                    let span: HTMLSpanElement = document.createElement("span");

                    if (!span.classList.contains(highlightClassName))
                        span.classList.add(highlightClassName);

                    span.appendChild(document.createTextNode(matched));
                    parentNode.insertBefore(span, node);

                    nodeVal = nodeVal.substring(foundIndex + textToHighlight.length);
                } // Whend

            } // Next i 

        } // End Sub checkAndReplace 


        protected iterator(p: Node)
        {
            if (p == null)
                return;

            let children: Node[] = Array.prototype.slice.call(p.childNodes);

            if (children.length)
            {
                for (let i = 0; i < children.length; i++)
                {
                    let cur: Node = children[i];

                    // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
                    if (cur.nodeType === Node.TEXT_NODE) 
                    {
                        this.checkAndReplace(cur);
                    }
                    else if (cur.nodeType === Node.ELEMENT_NODE) 
                    {
                        this.iterator(cur);
                    }
                } // Next i 

            } // End if (children.length) 

        } // End Sub iterator


        public highlightNode(n:Node)
        {
            this.iterator(n);
        } // End Sub highlight 


        public highlight()
        {
            this.iterator(this.m_container);
        } // End Sub highlight 


    } // End Class InstantSearch 


} // End Namespace SearchTools 

उपयोग:

let searchText = document.getElementById("txtSearchText");
let searchContainer = document.body; // document.getElementById("someTable");
let highlighter = new SearchTools.InstantSearch(searchContainer, [
    {
        token: "this is the text to highlight" // searchText.value,
        className: "highlight", // this is the individual highlight class
        sensitiveSearch: false
    }
]);


// highlighter.highlight(); // this would highlight in the entire table
// foreach tr - for each td2 
highlighter.highlightNode(td2); // this highlights in the second column of table

शानदार जवाब .. तरीका ओवरकिल जैसा लग रहा है, लेकिन संक्षिप्त! निश्चित रूप से उस विधि के साथ एक गति परीक्षण करने में रुचि होगी क्योंकि मेरे मामले में परिणाम आलसी में लोड किए जाते हैं (जैसा कि हजारों परिणाम हो सकते हैं), जिज्ञासु अगर यह विधि आलसी लोड के लिए एक उच्च विलंबता जोड़ देगा।
पोग्रिंडिस

5
क्षमा करें, लेकिन आपका कोई भी तर्क सत्य नहीं है। 1. आप बिल्कुल एक RegExp का उपयोग कर सकते हैं, आपको बस HTML मूल्य के अंदर नहीं बल्कि एक तत्व के पाठ मूल्य को खोजना चाहिए। 2. आप विशेष रूप से डियाक्रिटिक वर्णों के साथ RegExp का उपयोग कर सकते हैं, जैसा कि mark.js में लागू किया गया है । 3. एचटीएमएल नोटेशनों को ब्राउज़र डोम में वास्तविक वर्णों में परिवर्तित किया जाएगा, इसलिए आप भी उनका पूरा उपयोग करेंगे!
यार

1
@julmot; 1 के लिए: जिसका अर्थ है कि आपको प्रत्येक तत्व के माध्यम से पुनरावृति करने की आवश्यकता है, जो ठीक है कि मैं क्या करता हूं। जब तक आप स्वरूपण खोने के बारे में परवाह नहीं करते हैं, उस स्थिति में आप document.body.innerText में खोज सकते हैं, जो काफी धीमा होगा। 3. DOM में नहीं, बल्कि इनर टेक्स्ट या टेक्स्ट-एलीमेंट के टेक्स्ट कॉन्टेंट प्रॉपर्टी में। जिसका अर्थ है कि आपको पाठ तत्वों के माध्यम से पुनरावृति करने की आवश्यकता है; RegEx AFAIK के साथ नहीं किया जा सकता है। 2: mark.js नहीं जानते, लेकिन मैं हर उस चीज़ से बचता हूँ जो jQuery.each करती है, क्योंकि यह बहुत धीमी है।
स्टेफेन स्टीगर

1
@StefanSteiger 1. फिर आपको अपना निर्णय संबंध सही करना चाहिए, क्योंकि यह कहता है कि हम एक RegExp के साथ बिल्कुल भी खोज नहीं कर सकते, जो कि सत्य नहीं है। यह jQuery.each का उपयोग नहीं करता है। आप ऐसा क्यों सोचते हैं? 3. यह सच नहीं है, कम से कम फ़ायरफ़ॉक्स में। &auml;उदाहरण के लिए उपयोग करते समय वास्तविक चरित्र में परिवर्तित हो जाएगा innerHTML
दोस्त

1
हाय @StefanSteiger वास्तव में, मैं आपके समाधान का उपयोग कर रहा हूं। यह एक सही है। लेकिन कुछ समस्या है जैसे, यदि II में P है, जिसमें दो स्पैन हैं और एक स्पैन में डिप्लोमा MSBTE जैसा डेटा है और दूसरे स्पैन में डेटा 2012 है। अब यदि स्ट्रिंग जिसे मैं हाइलाइट करना चाहता हूं, वह है डिप्लोमा MSBTE 2012, यह पूरी स्ट्रिंग तो मैंने चेक किया यह काम नहीं करता है, यदि जो कुछ मिलान करने वाला है वह एक स्पैन में मौजूद है तो यह काम करता है, लेकिन यदि टेक्स्ट कंटेंट अलग-अलग टैग में है तो यह काम नहीं करता। क्या आप कृपया इस बारे में कुछ बता सकते हैं?
गणेश

41

क्यों एक सेल्फमेड हाइलाइटिंग फ़ंक्शन का उपयोग करना एक बुरा विचार है

इसका कारण यह है कि खरोंच से अपने स्वयं के हाइलाइटिंग फ़ंक्शन का निर्माण शुरू करना संभवतः एक बुरा विचार है क्योंकि आप निश्चित रूप से उन मुद्दों में भाग लेंगे जो दूसरों ने पहले ही हल कर दिए हैं। चुनौतियां:

  • आपको अपने ईवेंट को नष्ट करने के लिए और फिर से और फिर से (जो भी उदाहरण के साथ मामला होगा innerHTML) DOM रीजनरेशन को ट्रिगर किए बिना HTML तत्वों के साथ टेक्स्ट नोड्स को हटाने की आवश्यकता होगी।
  • यदि आप हाइलाइट किए गए तत्वों को हटाना चाहते हैं, तो आपको HTML तत्वों को उनकी सामग्री के साथ हटाना होगा और आगे की खोजों के लिए स्प्लिट किए गए टेक्स्ट-नोड्स को भी संयोजित करना होगा। यह आवश्यक है क्योंकि प्रत्येक हाइलाइटर प्लगइन मैचों के लिए टेक्स्ट नोड्स के अंदर खोज करता है और यदि आपके कीवर्ड को कई टेक्स्ट नोड्स में विभाजित किया जाएगा तो वे नहीं मिलेंगे।
  • आपको यह सुनिश्चित करने के लिए परीक्षणों का निर्माण करना होगा कि आपका प्लगइन उन परिस्थितियों में काम करता है जिनके बारे में आपने नहीं सोचा है। और मैं क्रॉस-ब्राउज़र परीक्षणों के बारे में बात कर रहा हूं!

जटिल लगता है? यदि आप कुछ विशेषताओं को उजागर करना चाहते हैं जैसे कि हाइलाइटिंग से कुछ तत्व अनदेखा करना, डायक्रिटिक्स मैपिंग, समानार्थक मानचित्रण, iframes के अंदर खोज, शब्द खोज को अलग करना, आदि यह अधिक से अधिक जटिल हो जाता है।

किसी मौजूदा प्लगइन का उपयोग करें

मौजूदा, अच्छी तरह से लागू किए गए प्लगइन का उपयोग करते समय, आपको उपरोक्त नामित चीजों के बारे में चिंता करने की आवश्यकता नहीं है। साइटपॉइंट पर लेख 10 jQuery के टेक्स्ट हाइलाइटर प्लगइन्स लोकप्रिय हाइलाइटर प्लगइन्स की तुलना करते हैं।

Mark.js पर एक नज़र है

mark.js एक ऐसा प्लगइन है जो शुद्ध जावास्क्रिप्ट में लिखा गया है, लेकिन यह jQuery प्लगइन के रूप में भी उपलब्ध है। इसे अन्य प्लगइन्स की तुलना में अधिक अवसरों की पेशकश करने के लिए विकसित किया गया था:

  • पूर्ण अवधि के बजाय अलग से कीवर्ड खोजें
  • मानचित्र डायक्टिकिक्स (उदाहरण के लिए यदि "जस्टो" को "जस्टो" से मेल खाना चाहिए)
  • कस्टम तत्वों के अंदर मेल को अनदेखा करते हैं
  • कस्टम हाइलाइटिंग तत्व का उपयोग करें
  • कस्टम हाइलाइटिंग क्लास का उपयोग करें
  • नक्शा कस्टम पर्यायवाची
  • iframes के अंदर भी खोजें
  • नहीं मिली शर्तें

डेमो

वैकल्पिक रूप से आप इस बेला को देख सकते हैं ।

उपयोग उदाहरण :

// Highlight "keyword" in the specified context
$(".context").mark("keyword");

// Highlight the custom regular expression in the specified context
$(".context").markRegExp(/Lorem/gmi);

यह GitHub ( परियोजना संदर्भ ) पर मुक्त और विकसित ओपन-सोर्स है ।


4
अकेले पाठ को हाइलाइट करना मेरे लिए jQuery को शामिल करने के लिए एक अच्छा पर्याप्त कारण नहीं है।
रॉय

10
@ मैंने इसे दिल से लिया है। अच्छी खबर है, क्योंकि v6.0.0 mark.js ने jQuery की निर्भरता को माफ कर दिया है और अब इसे वैकल्पिक रूप से JQuery प्लगइन के रूप में उपयोग करने के लिए बनाता है।
दोस्त

सभी सत्य, सिवाय: 1 बिंदु संभव नहीं है, क्योंकि आप पंजीकृत ईवेंट हैंडलर प्राप्त नहीं कर सकते हैं, और यहां तक ​​कि अगर आप कर सकते हैं, तो आप अनाम फ़ंक्शंस सेट नहीं कर सकते ... 2nd: mark.js को दो टैग के बीच पाठ नहीं मिलता है, जैसे। <span> s </ span> ed sed नहीं मिलेगा ... 3rd: जब भी कोई ब्राउज़र (नया संस्करण सहित) आता है तो आपने उसे अभी तक परीक्षण नहीं किया है, वह टूट सकता है। यह हमेशा सच है, चाहे आप कितने भी टेस्ट लिखें। 17kb पर, निशान यह क्या करता है के लिए बहुत बड़ा है।
स्टीफन स्टेगर

आप @StefanSteiger का क्या उल्लेख कर रहे हैं? उस जानकारी के बिना पहले बिंदु पर कुछ नहीं कह सकते। हालाँकि, दूसरी टिप्पणी गलत है, mark.js acrossElementsविकल्प का उपयोग करके टैग के बीच मिलान पा सकते हैं । और तीसरी टिप्पणी के लिए; mark.js इसके द्वारा प्रदान की गई कार्यक्षमताओं की तुलना में बड़ा नहीं है। और नहीं, यह संभावना नहीं है कि भविष्य में कुछ टूटता है, क्योंकि mark.js का परीक्षण किया गया था जैसे कि Chrome 30 को शुरू करना और क्रॉस-ब्राउज़र यूनिट परीक्षणों के साथ सभी नए संस्करणों में और आगामी संस्करणों के साथ कभी कोई समस्या नहीं थी।
यार

@ डूड: पहले पैराग्राफ के बाद के तीन अंक। आह, ठीक है, डेमो में उस विकल्प को मैंने देखा। उस मामले में, यह कुछ समझ सकता है। लेकिन फिर भी, मुझे यह बहुत बड़ा लगता है।
स्टीफन स्टीगर

10
function stylizeHighlightedString() {

    var text = window.getSelection();

    // For diagnostics
    var start = text.anchorOffset;
    var end = text.focusOffset - text.anchorOffset;

    range = window.getSelection().getRangeAt(0);

    var selectionContents = range.extractContents();
    var span = document.createElement("span");

    span.appendChild(selectionContents);

    span.style.backgroundColor = "yellow";
    span.style.color = "black";

    range.insertNode(span);
}

3
मोहित, एसओ का स्वागत है। कोड का कुछ विवरण अच्छा होगा!
निप्पी

एक और नोड बनाने के बिना पाठ का चयन करने का एक तरीका होना चाहिए?
डेव ग्रेगोरी

@ user191433 सवाल केवल पाठ का चयन करने का नहीं है, बल्कि शैलियों को लागू करने का भी है। उसके लिए आपको एक नोड की आवश्यकता है।
क्रिस्टोफ

रिमाइंडर / टिप जिसे जावास्क्रिप्ट span.style.backgroundColor = "yellow";सीएसएस में अनुवाद करता है style="background-color: yellow;"- ऊंट के बीच सूक्ष्म अंतर और धराशायी नोटेशन ने मुझे पहली बार में उलझा दिया।
MarkHu

1
पर पी एस मोहित के जवाब stackoverflow.com/questions/7991474/... इस कोड का एक और अधिक-सुव्यवस्थित संस्करण है। (उदाहरण के लिए शुरुआत और अंत चर जो पूरी तरह से नैदानिक ​​/ गैर-कार्यात्मक हैं, को छोड़ देना।)
मार्चु

7

यहाँ मेरा regexp शुद्ध जावास्क्रिप्ट समाधान है:

function highlight(text) {
    document.body.innerHTML = document.body.innerHTML.replace(
        new RegExp(text + '(?!([^<]+)?<)', 'gi'),
        '<b style="background-color:#ff0;font-size:100%">$&</b>'
    );
}

यह मेरे लिए पूरी तरह से काम करता है जब मैं जिस पाठ को हाइलाइट करने का प्रयास कर रहा हूं उसमें HTML टैग शामिल हैं।
जॉन चैपमैन

आप regexp पाइप सिंबल के माध्यम से कई शब्दों को स्वीकार करने के लिए फ़ंक्शन को भी ट्वीक कर सकते हैं, जैसेone|two|three
क्लेमेन तुषार

यदि पाठ के अंत में एक >चरित्र है तो यह पाठ को प्रतिस्थापित नहीं करेगा । (?!([^<]+)?<)काम करने के लिए इसका उपयोग करके रेगेक्स को संशोधित करें ।
आर्ची रेयेस

अनुरोध के अनुसार संशोधित।
क्लेमेन तुषार

उत्तम! यह मेरे लिए सबसे अच्छा है
मार्को बर्मेटो

5

मेरे पास एक ही समस्या है, पाठ का एक गुच्छा एक xmlhttp अनुरोध के माध्यम से आता है। यह पाठ html स्वरूपित है। मुझे हर घटना को उजागर करने की जरूरत है।

str='<img src="brown fox.jpg" title="The brown fox" />'
    +'<p>some text containing fox.</p>'

समस्या यह है कि मुझे टैग में पाठ को उजागर करने की आवश्यकता नहीं है। उदाहरण के लिए मुझे लोमड़ी को उजागर करने की आवश्यकता है:

अब मैं इसे इसके साथ बदल सकता हूं:

var word="fox";
word="(\\b"+ 
    word.replace(/([{}()[\]\\.?*+^$|=!:~-])/g, "\\$1")
        + "\\b)";
var r = new RegExp(word,"igm");
str.replace(r,"<span class='hl'>$1</span>")

अपने प्रश्न का उत्तर देने के लिए: आप regexp विकल्पों में जी छोड़ सकते हैं और केवल पहली घटना को प्रतिस्थापित किया जाएगा लेकिन यह अभी भी img src संपत्ति में एक है और छवि टैग को नष्ट कर देता है:

<img src="brown <span class='hl'>fox</span>.jpg" title="The brown <span 
class='hl'>fox</span> />

इस तरह से मैंने इसे हल किया है, लेकिन सोच रहा था कि क्या कोई बेहतर तरीका है, कुछ मैंने नियमित अभिव्यक्तियों में याद किया है:

str='<img src="brown fox.jpg" title="The brown fox" />'
    +'<p>some text containing fox.</p>'
var word="fox";
word="(\\b"+ 
    word.replace(/([{}()[\]\\.?*+^$|=!:~-])/g, "\\$1")
    + "\\b)";
var r = new RegExp(word,"igm");
str.replace(/(>[^<]+<)/igm,function(a){
    return a.replace(r,"<span class='hl'>$1</span>");
});

यह एकमात्र रेगेक्स समाधान था जिसने मेरे साथ <img src="word">या बिना खिलवाड़ के काम किया <a href="word">
यवसंचरा

1
स्वर्णिम नियम: कभी नहीं। उपयोग। नियमित रूप से। भाव। सेवा। मैस। के बारे में। साथ में। एक्सएमएल।
ScottMcGready

5

अन्य समाधानों में से कोई भी वास्तव में मेरी आवश्यकताओं के अनुरूप नहीं है, और हालांकि स्टीफन स्टीगर के समाधान ने काम किया जैसा कि मैंने उम्मीद की थी कि मुझे यह थोड़ा सा भी मिला।

निम्नलिखित मेरा प्रयास है:

/**
 * Highlight keywords inside a DOM element
 * @param {string} elem Element to search for keywords in
 * @param {string[]} keywords Keywords to highlight
 * @param {boolean} caseSensitive Differenciate between capital and lowercase letters
 * @param {string} cls Class to apply to the highlighted keyword
 */
function highlight(elem, keywords, caseSensitive = false, cls = 'highlight') {
  const flags = caseSensitive ? 'gi' : 'g';
  // Sort longer matches first to avoid
  // highlighting keywords within keywords.
  keywords.sort((a, b) => b.length - a.length);
  Array.from(elem.childNodes).forEach(child => {
    const keywordRegex = RegExp(keywords.join('|'), flags);
    if (child.nodeType !== 3) { // not a text node
      highlight(child, keywords, caseSensitive, cls);
    } else if (keywordRegex.test(child.textContent)) {
      const frag = document.createDocumentFragment();
      let lastIdx = 0;
      child.textContent.replace(keywordRegex, (match, idx) => {
        const part = document.createTextNode(child.textContent.slice(lastIdx, idx));
        const highlighted = document.createElement('span');
        highlighted.textContent = match;
        highlighted.classList.add(cls);
        frag.appendChild(part);
        frag.appendChild(highlighted);
        lastIdx = idx + match.length;
      });
      const end = document.createTextNode(child.textContent.slice(lastIdx));
      frag.appendChild(end);
      child.parentNode.replaceChild(frag, child);
    }
  });
}

// Highlight all keywords found in the page
highlight(document.body, ['lorem', 'amet', 'autem']);
.highlight {
  background: lightpink;
}
<p>Hello world lorem ipsum dolor sit amet, consectetur adipisicing elit. Est vel accusantium totam, ipsum delectus et dignissimos mollitia!</p>
<p>
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam, corporis.
  <small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium autem voluptas perferendis dolores ducimus velit error voluptatem, qui rerum modi?</small>
</p>

मैं भागने-स्ट्रिंग- regexp जैसी किसी चीज़ का उपयोग करने की भी सिफारिश करूंगा यदि आपके कीवर्ड में विशेष वर्ण हो सकते हैं, जिन्हें regexes में बचाना होगा:

const keywordRegex = RegExp(keywords.map(escapeRegexp).join('|')), flags);

यह मेरे लिए अच्छी तरह से काम करता है लेकिन इसे "अनमार्क" करने के लिए एक रास्ता भी चाहिए
jwzumwalt

4

सरल टाइपस्क्रिप्ट उदाहरण

नोट: जब मैं कई बातों में @Stefan से सहमत हूं, तो मुझे केवल एक सरल मैच हाइलाइटिंग की आवश्यकता थी :

module myApp.Search {
    'use strict';

    export class Utils {
        private static regexFlags = 'gi';
        private static wrapper = 'mark';

        private static wrap(match: string): string {
            return '<' + Utils.wrapper + '>' + match + '</' + Utils.wrapper + '>';
        }

        static highlightSearchTerm(term: string, searchResult: string): string {
            let regex = new RegExp(term, Utils.regexFlags);

            return searchResult.replace(regex, match => Utils.wrap(match));
        }
    }
}

और फिर वास्तविक परिणाम का निर्माण:

module myApp.Search {
    'use strict';

    export class SearchResult {
        id: string;
        title: string;

        constructor(result, term?: string) {
            this.id = result.id;
            this.title = term ? Utils.highlightSearchTerm(term, result.title) : result.title;
        }
    }
}

3

HTML5 के बाद से आप <mark></mark>पाठ को हाइलाइट करने के लिए टैग का उपयोग कर सकते हैं । आप इन टैग्स के बीच कुछ टेक्स्ट / कीवर्ड लपेटने के लिए जावास्क्रिप्ट का उपयोग कर सकते हैं। पाठ को कैसे चिह्नित और अचिह्नित किया जाए, इसका एक छोटा सा उदाहरण यहां दिया गया है।

JSFIDDLE DEMO


innerHTMLखतरनाक है। यह घटनाओं को हटा देगा।
यार

2
यह भी ठीक से काम नहीं करता है, उदाहरण के लिए, यदि आप JSFIDDLE "लोरम" में प्रवेश करते हैं, तो यह केवल इसका पहला उदाहरण है।
agm1984

1
आपका स्वागत है आपको केवल कीवर्ड की सभी घटनाओं को बदलने की आवश्यकता है। यहाँ विश्व स्तर पर jsfiddle.net/de5q704L/73
kasper Taeymans

2

2019 के लिए तेजी से आगे, वेब एपीआई को अब हाइलाइटिंग ग्रंथों के लिए मूल समर्थन है:

const selection = document.getSelection();
selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);

और आप जाने के लिए अच्छे हैं! anchorNodeचयन प्रारंभिक नोड focusNodeहै, चयन समाप्ति नोड है। और, यदि वे पाठ नोड्स हैं, offsetतो संबंधित नोड्स में शुरुआत और अंत चरित्र का सूचकांक है। यहाँ प्रलेखन है

उनके पास लाइव डेमो भी है


ओह यह शानदार है। बस इसे इस तरह से उपयोग करें: Selection.setBaseAndExtent (वांछितNode, 0, वांछितNode, 1); केवल वही नोड उजागर करने के लिए जिसकी आपको आवश्यकता है। और यह गुटेनबर्ग के साथ काम करता है
tonyAndr

1

मैं सोच रहा था कि आप भी इस पर क्या सीख सकते हैं पोस्ट ।

मैंनें इस्तेमाल किया:

function highlightSelection() {
			var userSelection = window.getSelection();
			for(var i = 0; i < userSelection.rangeCount; i++) {
				highlightRange(userSelection.getRangeAt(i));
			}
			
		}
			
			function highlightRange(range) {
			    var newNode = document.createElement("span");
			    newNode.setAttribute(
			       "style",
			       "background-color: yellow; display: inline;"
			    );
			    range.surroundContents(newNode);
			}
<html>
	<body contextmenu="mymenu">

		<menu type="context" id="mymenu">
			<menuitem label="Highlight Yellow" onclick="highlightSelection()" icon="/images/comment_icon.gif"></menuitem>
		</menu>
		<p>this is text, select and right click to high light me! if you can`t see the option, please use this<button onclick="highlightSelection()">button </button><p>

आप इसे यहाँ भी आज़मा सकते हैं: http://henriquedonati.com/projects/Extension/extension.html

XC


0

यदि आप चाहते हैं कि आप इसे पृष्ठ लोड पर भी हाइलाइट करें, तो एक नया तरीका है।

बस जोड़ दो #:~:text=Highlight%20These

इस लिंक तक पहुँचने का प्रयास करें

/programming/38588721#:~:text=Highlight%20a%20text


-1

रेंज प्रकार पर चारों ओर का उपयोग कर () विधि । इसका एकमात्र तर्क एक तत्व है जो उस श्रेणी को लपेट देगा।

function styleSelected() {
  bg = document.createElement("span");
  bg.style.backgroundColor = "yellow";
  window.getSelection().getRangeAt(0).surroundContents(bg);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.