129 votes

Comment mettre du texte en surbrillance à l'aide de javascript

Quelqu'un peut-il m'aider avec une fonction javascript qui peut mettre en évidence du texte sur une page web. L'exigence est de ne mettre en évidence qu'une seule fois, et non pas de mettre en évidence toutes les occurrences du texte comme nous le faisons dans le cas d'une recherche.

5 votes

Si vous postez le code de la fonction, nous pourrons vous aider. Si vous nous demandez de créer une telle fonction pour vous... c'est moins probable. Vous devez faire quelque chose par vous-même. Commencez à faire quelque chose et revenez quand vous êtes bloqué.

7 votes

Oui, j'ai lu How to Ask et j'ai fait quelque chose par moi-même, mais je suis resté bloqué et c'est pourquoi j'ai demandé. Je travaille sur Android et j'ai peu de connaissances en javasript, c'est pourquoi je ne suis pas en mesure de le faire moi-même. Auparavant, j'utilisais un autre javascript qui faisait le travail mais pas sans certaines limitations. Je n'ai peut-être pas utilisé les bons mots en posant cette question et j'en suis désolé, mais s'il vous plaît, ne pensez pas le contraire.

1 votes

Ce plugin peut vous intéresser : github.com/julmot/jmHighlight . Il peut mettre en évidence les mots clés séparément ou en tant que terme, peut mettre en évidence la correspondance avec votre élément personnalisé et votre nom de classe et peut également rechercher les diacritiques. En outre, il vous permet de filtrer le contexte dans lequel vous recherchez des correspondances.

8voto

elclanrs Points 40467

Aucune des autres solutions ne répondait vraiment à mes besoins, et bien que la solution de Stefan Steiger ait fonctionné comme prévu, je l'ai trouvée un peu trop verbeuse.

Voici ma tentative :

/**
 * 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>

Je recommande également d'utiliser quelque chose comme escape-string-regexp si vos mots-clés peuvent comporter des caractères spéciaux qui doivent être échappés dans les regex :

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

0 votes

Cela a bien fonctionné pour moi mais il faut aussi un moyen de "dé-marquer"'.

0 votes

Fonctionne bien. Merci. @param {boolean} caseSensitive est le contraire

8voto

Jovylle Bermudez Points 634

Si vous souhaitez également qu'il soit mis en évidence lors du chargement de la page, il existe un nouveau moyen.

ajoutez simplement #:~:text=Highlight%20These

essayez d'accéder à ce lien dans un nouvel onglet

https://stackoverflow.com/questions/38588721#:~:text=Highlight%20a%20text

qui met en évidence le texte "Mettre un texte en évidence".

De plus, actuellement, il n'est pris en charge que sur Chrome (Merci GitGitBoom ).

2 votes

Pour tous ceux qui souhaitent obtenir plus d'informations, cette fonction s'appelle "Défilement vers le fragment de texte" et n'est actuellement prise en charge que par Chrome. chromestatus.com/feature/4733392803332096

0 votes

7voto

kasper Taeymans Points 2587

Depuis HTML5, vous pouvez utiliser l'option <mark></mark> pour mettre le texte en évidence. Vous pouvez utiliser le javascript pour insérer du texte/mot clé entre ces balises. Voici un petit exemple de la façon de marquer et de dé-marquer du texte.

DEMO DE JSFIDDLE

1 votes

innerHTML est dangereux. Il supprimera les événements.

2 votes

Cela ne fonctionne pas non plus correctement car, par exemple, si vous entrez dans le JSFIDDLE "Lorem", il ne marque que la première instance de celui-ci.

1 votes

Il suffit de remplacer toutes les occurrences du mot clé. Voici un exemple avec regex globalement jsfiddle.net/de5q704L/73

5voto

HMR Points 5459

J'ai le même problème, un tas de texte arrive par une requête xmlhttp. Ce texte est formaté en html. J'ai besoin de mettre en évidence chaque occurrence.

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

Le problème est que je n'ai pas besoin de mettre en évidence le texte dans les balises. Par exemple, j'ai besoin de mettre en évidence le renard :

Maintenant je peux le remplacer par :

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

Pour répondre à votre question : vous pouvez omettre le g dans les options de regexp et seule la première occurrence sera remplacée mais celle-ci reste celle de la propriété img src et détruit la balise image :

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

C'est ainsi que j'ai résolu le problème, mais je me demandais s'il existait une meilleure méthode, quelque chose qui m'aurait échappé dans les expressions régulières :

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

0 votes

C'est la seule solution d'expressions rationnelles qui a fonctionné pour moi sans avoir à manipuler les éléments suivants <img src="word"> o <a href="word"> .

1 votes

Règle d'or : Jamais. Utilisez. d'expressions. Régulières. Pour. Mess. Avec. Avec. XML.

4voto

Slavo Vojacek Points 856

Exemple simple en TypeScript

NOTE : Bien que je sois d'accord avec @Stefan sur de nombreux points, je n'avais besoin que d'une simple mise en évidence du match :

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

Et ensuite construire le résultat réel :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X