2017-10-19 16 views
1

Disons que nous avons un paragraphe HTML avec un texte:Javascript - Sélectionnez le texte spécifique à l'intérieur d'une chaîne en utilisant la fonction onClick

<p>Hello. This is a random paragraph with some not so random text inside of this paragraph</p> 

Et nous avons un tableau de chaînes:

const highlightThisWords = ['random', 'paragraph', 'inside'] 

Qu'est-ce que J'ai besoin d'une fonction qui va mettre en évidence (changer le style) du texte à l'intérieur du paragraphe qui est inclus dans le tableau. Notez le mot paragraphe est deux fois à l'intérieur de la balise, mais je ne devrais mettre en évidence que celui sur lequel j'ai cliqué. Aussi j'ai besoin de faire un peu de calcul après le clic comme incrémenter un compteur.

Enviroment: React.js sans jquery possible

+0

le tableau est rempli uniquement lorsque vous cliquez sur du texte? _Note le mot paragraphe est deux fois à l'intérieur de la balise mais je devrais mettre en surbrillance seulement celui que j'ai cliqué sur_ n'a pas eu cette partie – Dane

+0

Non. Son tableau premade. Je dois mettre en surbrillance le texte à l'intérieur du paragraphe qui correspond à l'une des chaînes à l'intérieur du tableau –

+0

Dans ce cas, les deux 'paragraphes doivent être mis en évidence n'est-ce pas? – Dane

Répondre

1

const highlightThisWords = ['random', 'paragraph', 'inside']; 
 
const pNode = document.querySelector('p'); 
 

 
// turn pNode into a highlight-aware DOM 
 
pNode.innerHTML = pNode.textContent.split(' ').map(word => { 
 
    return highlightThisWords.includes(word) ? `<span>${word}</span>` : word; 
 
}).join(' '); 
 

 
const potentialHighlights = pNode.querySelectorAll('span'); 
 
potentialHighlights.forEach(highlightableWord => { 
 
    highlightableWord.addEventListener('click', function(e) { 
 
    // dehighlight all the rest 
 
    pNode.querySelectorAll('.highlighted').forEach(highlighted => { 
 
     highlighted.classList.remove('highlighted') 
 
    }); 
 
    // highlight the clicked word 
 
    highlightableWord.classList.add('highlighted'); 
 
    }); 
 
});
.highlighted { 
 
    color: red; 
 
}
<p>Hello. This is a random paragraph with some not so random text inside of this paragraph</p>

Ci-dessus vous trouvez un extrait de l'échantillon dans js de vanille, mettre en œuvre une solution minimale à votre question. Il n'y a pas de manière humaine de déterminer quel mot exact a été cliqué dans le paragraphe, à moins que vous n'embrassiez ce mot dans une balise html. Les réponses proposées jusqu'ici enveloppent chaque mot dans une étiquette. Bien que cela fonctionne, il ne fonctionnerait pas bien si vous avez de longs paragraphes (imaginez des milliers de nœuds DOM dans votre mémoire juste pour un élément de paragraphe). Ce que je propose est d'envelopper seulement les mots "potentiellement surlignables" dans les balises.

+0

A dû le modifier beaucoup pour React.js mais cette idée fonctionne le mieux –

0

Puisque vous utilisez réagissez, vous pouvez utiliser String.prototype.split() pour diviser le texte entier dans un tableau de mots individuels, et ensuite utiliser le rendu conditionnel pour les rendre comme l'a souligné ou non:

class MyComponent extends React.Component { 
    render() { 
    const arrayOfStrings = stringContainingParagraph.split(' '); 

    return (
     <div> 
     {arrayOfStrings.map((elem) => (
      (highlightThisWords.indexOf(elem) !== -1) ? 
      <mark>{elem}</mark> : 
      <span>{elem}</span> 
     ))} 
     </div> 
    ); 
    } 
} 

vous pouvez ensuite personnaliser ce code que vous le souhaitez (incrémenter un compteur, ou en utilisant onClick s pour obtenir votre fonctionnalité désirée).

1

Vous pouvez soit créer un composant personnalisé et utiliser ce composant personnalisé pour les mots fractionnés avec "", j'ai cependant essayé de créer un jsfiddle qui n'est pas très propre, mais montre une démo sur comment cela fonctionnerait. Pour afficher le code sur ce post:

class Hello extends React.Component { 
    constructor() { 
    super(); 
    this.handleClick = this.handleClick.bind(this); 
    } 
    split(str) { 
    return str.split(" "); 
    } 
    make(str, i) { 
    return <span key={i} style={{marginLeft:3}} onClick={this.handleClick}>{str}</span>; 
    } 
    handleClick(e) { 
    console.log(this.props.highlights, e.target.innerText); 
    if (this.props.highlights.indexOf(e.target.innerText) !== -1) { 
     e.target.style.background = "red"; 
    } 
    } 
    render() { 
    const parts = this.split(this.props.name); 
    return <div>{parts.map((d, i) => { 
     return this.make(d, i); 
    })}</div>; 
    } 
} 

ReactDOM.render(
    <Hello highlights={['random', 'paragraph', 'inside']} name="This is a random paragraph with some not so random text inside of this paragraph" />, 
    document.getElementById('container') 
);