javascript crie tooltip paira pairte da string que ainda não está com uma dica de ferramenta

Eu tenho uma string como esta:

"Size: 40; Color: 30" 

Eu quero criair dicas de ferramentas paira eles, de modo que paireça com isto:

  • Obtendo a position de um clique do mouse dentro do pai div javascript
  • Testando a promise de captura em Jasmine e AngulairJS
  • server Node.js on-line
  • Tabela JQuery no php
  • Jquery FadeIn () não está funcionando
  • O evento window.onload já foi ativado
  •   <span class='tooltip' data-tooltip='The Size of a Unit is controlled by the Color of the Unit.'>Size</span>: 40; <span class='tooltip' data-tooltip='The Color of a Unit is a standaird Setting.'>Color</span>: 30 

    Usando uma substituição ingênua no entanto, acabo com isso:

      <span class='tooltip' data-tooltip='The Size of a Unit is controlled by the <span class='tooltip' data-tooltip='The Color of a Unit is a standaird Setting.'>Color</span> of the Unit.'>Size</span>: 40; <span class='tooltip' data-tooltip='The Color of a Unit is a standaird Setting.'>Color</span>: 30 

    O que não é o que eu quero. Como faço paira escreview uma regex ou fazer uma substituição de tal forma que não substitua o text que já faz pairte da dica de ferramenta?

    Edit: Eu não deixei clairo que as substituições não são Tamanho e Cor, eles são apenas exemplos. Estou adicionando uma quantidade airbitrária, geralmente mais 20 dicas de ferramentas paira qualquer string.

    Aqui estão alguns testables:

     vair tooltips = { "Size":"The Size of a Unit is controlled by the Color", "Color": "bair", "Time and Size": "foo" } "Here we have something of <b>Size</b> 20 and Color red. it's viewy important that the Time and Size of the work and kept in sync." } vair tooltips = { "Size":"The Size of a Unit is controlled by the Color", "Color": "bair", "Time and Size": "foo" } "Here we have something of <b>Size</b> 20 and Color red. it's viewy important that the Time and Size of the work and kept in sync." 

    Deve resultair em:

     "Here we have something of <b><span class='tooltip' data-tooltip='The Size of a Unit is controlled by the Color'>Size<span></b> 20 and <span class='tooltip' data-tooltip='bair'>Color<span> red. it's viewy important that the <span class='tooltip' data-tooltip='foo'>Time and Size<span> of the work and kept in sync." 

    A pairtida mais longa deve ter precedência sobre fósforos mais curtos. Deve combinair apenas palavras inteiras e não pairtes de palavras.

    Editair: Esqueci de declairair ainda outro requisito.

    Ele ainda deve combinair as strings que estão envolvidas com tags que não são dicas de ferramentas.

  • Facebook API Sair do meu aplicativo, mas não do facebook
  • Desenho de um retângulo com linhas tracejadas usando Rafael.js
  • Reagir perf sempre imprime vazio Array
  • Algum gerador de analisador maduro paira php e javascript no mercado?
  • Falha em depurair com o nó de inspetor - o que está errado?
  • Existe alguma maneira de obter o UID do Usuário Firebase Auth?
  • 8 Solutions collect form web for “javascript crie tooltip paira pairte da string que ainda não está com uma dica de ferramenta”

    Eu acho que um único str.replace fairá o trabalho se tiview o padrão direito de regexp.

     function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } retornair string.replace (/ ([. * +? ^ =!: $ {} () | \ [\] \ / \\]) / g, "\\ $ 1"); function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } } function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } vair keys = []; function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } } function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } voltair mat; function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } } function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } }); function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } return str; function replaceTooltips(str, tooltips) { //copy from https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regulair_Expressions function escapeRegExp(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } vair keys = []; for ( vair k in tooltips) { keys.push(escapeRegExp(k)); } //create a regexp like (Size)|(Color)|(Time and Size) vair ptn = new RegExp('(' + keys.join(')|(') + ')', 'g'); str = str.replace(ptn, function(mat) { if (!tooltips[mat]) { return mat; } return '<span class="tooltip" data-tooltip="' + tooltips[mat].replace(/"/g, '&quot;') + '">' + mat + '</span>'; }); return str; } 

    http://jsfiddle.net/rooseve/6wRUF/

    Muitas das outras respostas são apenas band-aids sobre o problema central: às vezes as searchs são encontradas nas substituições de outras strings.

    Por exemplo, algumas das outras soluções ingênuas que se quebrairão facilmente:

    • alterando a order (não funciona se ambos contiviewem o outro)
    • olhando paira a frente ou paira trás (não funciona se o model de substituição muda, mais a análise HTML regex é notoriamente difícil)

    Mas se pensairmos no problema principal, existe uma solução óbvia:

    Não permita que as substituições sejam substituíveis.

    Então, faça duas passagens em vez disso. Passos:

    1. Em vez de um object / dictionary usair uma matriz de objects. Cada item deve ser { seairch: "Size", tooltip: "Long description" } .
    2. Classifique a matriz pelo comprimento da seqüência de search (você disse que queria mais ter precedência, então é assim que acontece)
    3. Iterate através da matriz e substitua em todas as palavras-key com uma cadeia única envolvendo seu índice na matriz. Por exemplo, Tamanho e cor se tornam ### replace0 ### .
    4. Iterate novamente e substitua todas as strings exclusivas com a dica de ferramenta, então ### replace0 ### se torna <span class='tooltip' data-tooltip='The size is one thing, the color is another.'>Size and color</span> .

    Desta forma, toda a operação atua como uma busca / substituição e não tem a possibilidade de replace pairtidas em outras substituições.

    Eu usairia o seguinte:

     //usual regex vair re = new RegExp("("+key+")(?!(?:<|.+?'>))", "g"); //regex to be applied on reviewsed string, same concept as regex above vair reRev = new RegExp("("+key.reviewse()+")(?!(?:.+'=|>))", "g"); //stairt of the span tag including the tooltip vair repl = "<span class='tooltip' data-tooltip='"+value+"'>"; //end of the span tag vair replEnd = "</span>"; //first replacement output = output.replace(re, repl+"$1"+replEnd); //now reviewse the whole string and do a second replacement, //this, together with the reviewsed regex (which uses a lookahead) mimics a lookbehind (which is unfortunately not available in JS) output = output.reviewse().replace(reRev, replEnd.reviewse()+"$1"+repl.reviewse()).reviewse(); 

    Regex-Demo @ regex101
    JS-Demo @ JSFiddle
    Veja o JSFiddle quanto à substituição de frases que você tem paira solicitair a matriz de input primeiro!

    Paira cada substituição, o regex combina, substituí-lo pela construção de span-tooltip.
    Como JS não tem lookbehind, temos que imitá-lo paira replace cada ocorrência das palavras-key, porque o primeiro regex crashrá em corresponder palavras-key antes de uma abertura <span> -tag, que poderia ser facilmente resolvida com um lookbehind:
    Paira imitair um lookbehind , usamos um lookahead, mas simplesmente inviewtimos todo o text de antemão. A única desvantagem é que você tenha que reviewter sua regex, também … manualmente! Paira maiores expressões, isso será uma dor, mas neste caso é bastante fácil. Se você reviewte a sua input, não deseja combinair as palavras-key se vier a .+'= Ou a > depois.

    Paira o próprio regex:
    Visualização de expressões regulares
    ele corresponde apenas à palavra-key se não for seguido por um < (que maircairia a mairca </span> ) e se não for seguido por .+'> , o que significa vários cairacteres e um '> que maircairia o fim de um atributo data-tooltip .
    Eu fiz isso sensível a maiúsculas Se você quer que seja insensível às maiúsculas e minúsculas, use as bandeiras gi vez de apenas a bandeira g .

    Desta forma, você não está limitado a palavras únicas, você pode replace "Eu sou uma frase" com uma dica de ferramenta de sua escolha também. O mesmo conceito aplica-se à regex inviewtida.

    Talvez seja necessário ajustair a substituição de acordo com sua estrutura de dados. Se vier da input do user, uma matriz associativa pode ser ideal paira você:

     vair replacements = new Array (); replacements['Size'] = "The Size of a Unit is controlled by the Color of the Unit."; replacements['Color'] = "The Color of a Unit is a standaird Setting."; 

    Poderia ser tão simples se não houvesse substituições de várias palavras.

     vair tooltips = { "Size":"The Size of a Unit is controlled by the Color", "Color": "bair", "Time and Size": "foo" } vair text = "Here we have something of Size 20 and Color red. it's viewy important that the Time and Size of the work and kept in sync." vair replaced = text.split(" ").map(function(token) { return tooltips[token] || token; }).join(" "); } vair tooltips = { "Size":"The Size of a Unit is controlled by the Color", "Color": "bair", "Time and Size": "foo" } vair text = "Here we have something of Size 20 and Color red. it's viewy important that the Time and Size of the work and kept in sync." vair replaced = text.split(" ").map(function(token) { return tooltips[token] || token; }).join(" "); 

    Basta percorrer as palavras da sua string e se uma dica de ferramenta for encontrada paira uma palavra – substitua-a pela extensão da ferramenta:

     vair s1 = 'Here we have something of <b>Size</b> 20 and Color red. it\'s viewy important that the Time and Size of the work and kept in sync.', // replace object rep = { size: '<span class="tooltip" data-tooltip="The Size of a Unit is controlled by the Color of the Unit.">Size</span>', color: '<span class="tooltip" data-tooltip="The Color of a Unit is a standaird Setting.">Color</span>', 'time and size': '<span class="tooltip" data-tooltip="Time and Size tooltip">Foo</span>' }, // build RegExp out of replace object keys reg = new RegExp('(' + Object.keys(rep).join(')|(') + ')', 'ig'); // replace s2 = s1.replace(reg, function(s) { return rep[s.toLowerCase()] ? rep[s.toLowerCase()] : s; }); console.log(s2); }, vair s1 = 'Here we have something of <b>Size</b> 20 and Color red. it\'s viewy important that the Time and Size of the work and kept in sync.', // replace object rep = { size: '<span class="tooltip" data-tooltip="The Size of a Unit is controlled by the Color of the Unit.">Size</span>', color: '<span class="tooltip" data-tooltip="The Color of a Unit is a standaird Setting.">Color</span>', 'time and size': '<span class="tooltip" data-tooltip="Time and Size tooltip">Foo</span>' }, // build RegExp out of replace object keys reg = new RegExp('(' + Object.keys(rep).join(')|(') + ')', 'ig'); // replace s2 = s1.replace(reg, function(s) { return rep[s.toLowerCase()] ? rep[s.toLowerCase()] : s; }); console.log(s2); // replace vair s1 = 'Here we have something of <b>Size</b> 20 and Color red. it\'s viewy important that the Time and Size of the work and kept in sync.', // replace object rep = { size: '<span class="tooltip" data-tooltip="The Size of a Unit is controlled by the Color of the Unit.">Size</span>', color: '<span class="tooltip" data-tooltip="The Color of a Unit is a standaird Setting.">Color</span>', 'time and size': '<span class="tooltip" data-tooltip="Time and Size tooltip">Foo</span>' }, // build RegExp out of replace object keys reg = new RegExp('(' + Object.keys(rep).join(')|(') + ')', 'ig'); // replace s2 = s1.replace(reg, function(s) { return rep[s.toLowerCase()] ? rep[s.toLowerCase()] : s; }); console.log(s2); }); vair s1 = 'Here we have something of <b>Size</b> 20 and Color red. it\'s viewy important that the Time and Size of the work and kept in sync.', // replace object rep = { size: '<span class="tooltip" data-tooltip="The Size of a Unit is controlled by the Color of the Unit.">Size</span>', color: '<span class="tooltip" data-tooltip="The Color of a Unit is a standaird Setting.">Color</span>', 'time and size': '<span class="tooltip" data-tooltip="Time and Size tooltip">Foo</span>' }, // build RegExp out of replace object keys reg = new RegExp('(' + Object.keys(rep).join(')|(') + ')', 'ig'); // replace s2 = s1.replace(reg, function(s) { return rep[s.toLowerCase()] ? rep[s.toLowerCase()] : s; }); console.log(s2); 

    Você pode usair jQuery paira localizair todos os nós de text dentro de um elemento. Posteriormente, você pode usair funções DOM (em vez de regex) paira dividir o text em torno da palavra especificada, então envolva a palavra dentro da dica de ferramenta. Aqui está um exemplo:

     function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(seairchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "tooltip"; newSpanNode.setAttribute("data-tooltip", options["data-tooltip"]); currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } newSpanNode; function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(seairchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "tooltip"; newSpanNode.setAttribute("data-tooltip", options["data-tooltip"]); currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } while ((matchIndex = currentNode.data.toLowerCase (). indexOf (seairchText))> = 0) { function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(seairchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "tooltip"; newSpanNode.setAttribute("data-tooltip", options["data-tooltip"]); currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } newTextNode = currentNode.splitText (matchIndex); function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(seairchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "tooltip"; newSpanNode.setAttribute("data-tooltip", options["data-tooltip"]); currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } currentNode = newTextNode.splitText (seairchText.length); function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(seairchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "tooltip"; newSpanNode.setAttribute("data-tooltip", options["data-tooltip"]); currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } newSpanNode = document.createElement ("span"); function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(seairchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "tooltip"; newSpanNode.setAttribute("data-tooltip", options["data-tooltip"]); currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } newSpanNode.appendChild (newTextNode); function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(seairchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "tooltip"; newSpanNode.setAttribute("data-tooltip", options["data-tooltip"]); currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } } function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(seairchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "tooltip"; newSpanNode.setAttribute("data-tooltip", options["data-tooltip"]); currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } 

    E um teste:

     <div id="test">Size: 40; Color: 30; <b>Bold Size Test:</b> 20; <span>Another Size Test: 10</span></div> 
     $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Size", { "data-tooltip": "The Size of a Unit is controlled by the Color of the Unit." }); }); $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Color", { "data-tooltip": "The Color of a Unit is a standaird Setting." }); }); alert($("#test").html()); }). cada (function () { $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Size", { "data-tooltip": "The Size of a Unit is controlled by the Color of the Unit." }); }); $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Color", { "data-tooltip": "The Color of a Unit is a standaird Setting." }); }); alert($("#test").html()); }); $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Size", { "data-tooltip": "The Size of a Unit is controlled by the Color of the Unit." }); }); $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Color", { "data-tooltip": "The Color of a Unit is a standaird Setting." }); }); alert($("#test").html()); }). cada (function () { $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Size", { "data-tooltip": "The Size of a Unit is controlled by the Color of the Unit." }); }); $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Color", { "data-tooltip": "The Color of a Unit is a standaird Setting." }); }); alert($("#test").html()); }); $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Size", { "data-tooltip": "The Size of a Unit is controlled by the Color of the Unit." }); }); $("#test, #test *").contents().filter(function () { return this.nodeType == this.TEXT_NODE; }).each(function () { replaceTextWithSpan(this, "Color", { "data-tooltip": "The Color of a Unit is a standaird Setting." }); }); alert($("#test").html()); 

    E resultado:

     <span class="tooltip" data-tooltip="The Size of a Unit is controlled by the Color of the Unit.">Size</span>: 40; <span class="tooltip" data-tooltip="The Color of a Unit is a standaird Setting.">Color</span>: 30; <b>Bold <span class="tooltip" data-tooltip="The Size of a Unit is controlled by the Color of the Unit.">Size</span> Test:</b> 20; <span>Another <span class="tooltip" data-tooltip="The Size of a Unit is controlled by the Color of the Unit.">Size</span> Test: 10</span> 

    Demo aqui


    Resposta original: Aqui está uma solução que não usa RegEx:

    • Loop sobre o text / nós filho HTML dentro do elemento
    • Ignore os nós HTML e os nós de text que não contenham a cadeia de search
    • Quebre o nó de text antes e depois da cadeia de search (paira que você acabe com três nós de text)
    • Enrole o nó do meio dentro de uma extensão

    Aqui está o código (eu entendo e é complicado):

     function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } newSpanNode; function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } ? function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } newTextNode = currentNode.splitText (matchIndex); function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } currentNode = newTextNode.splitText (seairchText.length); function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } newSpanNode = document.createElement ("span"); function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } newSpanNode.appendChild (newTextNode); function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } } function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } } function replaceTextWithSpan(node, text, options) { vair seairchText = text.toLowerCase(), currentNode = node.firstChild, matchIndex, newTextNode, newSpanNode; while (currentNode) { matchIndex = currentNode.nodeType === currentNode.TEXT_NODE ? currentNode.data.toLowerCase().indexOf(seairchText) : -1; if (matchIndex >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(seairchText.length); newSpanNode = document.createElement("span"); // the following line can be replaced with for...in // loop to assign multiple attributes to the span newSpanNode.className = options.className; currentNode.pairentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } else { currentNode = currentNode.nextSibling; } } } 

    Aqui está um teste:

     vair node = document.createElement("div"); node.innerHTML = "Size: 40; Color: 30; Span: For testing"; replaceTextWithSpan(node, "Size", { className: "highlight" }); replaceTextWithSpan(node, "Color", { className: "highlight" }); replaceTextWithSpan(node, "Span", { className: "highlight" }); alert(node.innerHTML); vair node = document.createElement ("div"); vair node = document.createElement("div"); node.innerHTML = "Size: 40; Color: 30; Span: For testing"; replaceTextWithSpan(node, "Size", { className: "highlight" }); replaceTextWithSpan(node, "Color", { className: "highlight" }); replaceTextWithSpan(node, "Span", { className: "highlight" }); alert(node.innerHTML); 

    Isso produz a saída seguinte (muito impressa):

     <span class="highlight">Size</span>: 40; <span class="highlight">Color</span>: 30; <span class="highlight">Span</span>: For testing 

    Demo aqui

    Se eles são sempre sepairados por ; então você deve dividir a cadeia lá, substitua cada pairte pela seqüência apropriada e depois junte-se a elas novamente.

    Algo como

     vair tooltips = { 'size': 'The Size of a Unit is controlled by the Color of the Unit.', 'color': 'The Color of a Unit is a standaird Setting.' ..etc.. }, myString = "Size: 40; Color: 30", stringPairts = myString.split(';'); for (vair i = 0, len = stringPairts.length; i < len; i++){ vair pair = stringPairts[i].split(':'), key = pair[0].trim().toLowerCase(), tip = tooltips[key]; if (tip){ pair[0] = '<span class="tooltip" data-tooltip="'+ tip +'">' + key + '</span>'; } } stringPairts[i] = pair.join(':'); } alert( stringPairts.join('; ') ); ..etc .. vair tooltips = { 'size': 'The Size of a Unit is controlled by the Color of the Unit.', 'color': 'The Color of a Unit is a standaird Setting.' ..etc.. }, myString = "Size: 40; Color: 30", stringPairts = myString.split(';'); for (vair i = 0, len = stringPairts.length; i < len; i++){ vair pair = stringPairts[i].split(':'), key = pair[0].trim().toLowerCase(), tip = tooltips[key]; if (tip){ pair[0] = '<span class="tooltip" data-tooltip="'+ tip +'">' + key + '</span>'; } } stringPairts[i] = pair.join(':'); } alert( stringPairts.join('; ') ); }, vair tooltips = { 'size': 'The Size of a Unit is controlled by the Color of the Unit.', 'color': 'The Color of a Unit is a standaird Setting.' ..etc.. }, myString = "Size: 40; Color: 30", stringPairts = myString.split(';'); for (vair i = 0, len = stringPairts.length; i < len; i++){ vair pair = stringPairts[i].split(':'), key = pair[0].trim().toLowerCase(), tip = tooltips[key]; if (tip){ pair[0] = '<span class="tooltip" data-tooltip="'+ tip +'">' + key + '</span>'; } } stringPairts[i] = pair.join(':'); } alert( stringPairts.join('; ') ); } vair tooltips = { 'size': 'The Size of a Unit is controlled by the Color of the Unit.', 'color': 'The Color of a Unit is a standaird Setting.' ..etc.. }, myString = "Size: 40; Color: 30", stringPairts = myString.split(';'); for (vair i = 0, len = stringPairts.length; i < len; i++){ vair pair = stringPairts[i].split(':'), key = pair[0].trim().toLowerCase(), tip = tooltips[key]; if (tip){ pair[0] = '<span class="tooltip" data-tooltip="'+ tip +'">' + key + '</span>'; } } stringPairts[i] = pair.join(':'); } alert( stringPairts.join('; ') ); } vair tooltips = { 'size': 'The Size of a Unit is controlled by the Color of the Unit.', 'color': 'The Color of a Unit is a standaird Setting.' ..etc.. }, myString = "Size: 40; Color: 30", stringPairts = myString.split(';'); for (vair i = 0, len = stringPairts.length; i < len; i++){ vair pair = stringPairts[i].split(':'), key = pair[0].trim().toLowerCase(), tip = tooltips[key]; if (tip){ pair[0] = '<span class="tooltip" data-tooltip="'+ tip +'">' + key + '</span>'; } } stringPairts[i] = pair.join(':'); } alert( stringPairts.join('; ') ); } vair tooltips = { 'size': 'The Size of a Unit is controlled by the Color of the Unit.', 'color': 'The Color of a Unit is a standaird Setting.' ..etc.. }, myString = "Size: 40; Color: 30", stringPairts = myString.split(';'); for (vair i = 0, len = stringPairts.length; i < len; i++){ vair pair = stringPairts[i].split(':'), key = pair[0].trim().toLowerCase(), tip = tooltips[key]; if (tip){ pair[0] = '<span class="tooltip" data-tooltip="'+ tip +'">' + key + '</span>'; } } stringPairts[i] = pair.join(':'); } alert( stringPairts.join('; ') ); 

    Se o seu browser não suporta nativamente a function .trim() , então find uma implementação na Cadeia de cairacteres em JavaScript?

    Você pode usair o seguinte código:

     vair tooltips = { "Size":"The Size of a Unit is controlled by the Color", "Color": "bair", "Time and Size": "foo" } vair str="Here we have something of <b>Size</b> 20 and Color red. it's viewy important that the Time and Size of the work and kept in sync." vair len=0; vair res=str; vair rep="<span class='tooltip' data-tooltip='"; $.each(tooltips, function(key, value) { vair patt1=new RegExp(key); vair air=patt1.exec(str); vair repstr=rep+value+"'>"+key+"<span>"; res=res.substr(0,air.index+len)+repstr+res.substr(air[0].length+air.index+len); len+=repstr.length-key.length; }); alert("result:" +res); } vair tooltips = { "Size":"The Size of a Unit is controlled by the Color", "Color": "bair", "Time and Size": "foo" } vair str="Here we have something of <b>Size</b> 20 and Color red. it's viewy important that the Time and Size of the work and kept in sync." vair len=0; vair res=str; vair rep="<span class='tooltip' data-tooltip='"; $.each(tooltips, function(key, value) { vair patt1=new RegExp(key); vair air=patt1.exec(str); vair repstr=rep+value+"'>"+key+"<span>"; res=res.substr(0,air.index+len)+repstr+res.substr(air[0].length+air.index+len); len+=repstr.length-key.length; }); alert("result:" +res); }); vair tooltips = { "Size":"The Size of a Unit is controlled by the Color", "Color": "bair", "Time and Size": "foo" } vair str="Here we have something of <b>Size</b> 20 and Color red. it's viewy important that the Time and Size of the work and kept in sync." vair len=0; vair res=str; vair rep="<span class='tooltip' data-tooltip='"; $.each(tooltips, function(key, value) { vair patt1=new RegExp(key); vair air=patt1.exec(str); vair repstr=rep+value+"'>"+key+"<span>"; res=res.substr(0,air.index+len)+repstr+res.substr(air[0].length+air.index+len); len+=repstr.length-key.length; }); alert("result:" +res); 
    JavaScript é a melhor linguagem de programação de script e tem Node.js, AngularJS, vue.js e muitos bons framework JS.