2015-11-19 13 views
7

Ich muss ein Dokument mit jQuery suchen, um ein bestimmtes Wort zu finden. Es ist eigentlich ein Markenname, der überall fett und kursiv sein muss.Body nach String suchen und dann style

Ich kann dies mit :contain aber nur auf einer einzelnen Elementbasis tun. Ich muss in der Lage sein, Anker, Listen divs usw. zu durchlaufen.

$("a:contains('brand name')").html().replace('brand name'.... 

Irgendwelche Ideen würden geschätzt.

Update: Ich habe so weit, was funktioniert und ersetzt alles auf einer Seite, aber ich muss jetzt in eine Spanne mit einer Klasse wickeln. So nah, aber ratlos. Wieder würden Ideen geschätzt werden.

$("body *").contents().each(function() { 
    if(this.nodeType==3){ 
    this.nodeValue = this.nodeValue.replace(/brandname/g, 'colour'); 

    } 
}); 
+2

$ (": enthält ('Markenname')") gibt alle Elemente zurück. –

+0

'Es ist tatsächlich ein Markenname, der überall fett und kursiv sein muss ** und **' Ich kann dies tun mit: enthalten, aber nur auf einer einzelnen Elementbasis. Ich muss in der Lage sein, durch Anker zu gehen, listet divs usw. auf. Aber das Umschließen von z. B. "div" in "b" -Element ist kein gültiges HTML-Markup. Nicht wirklich klar, was du erwartest? –

+0

@ A.Wolff - erwartet das Wort und nur das Wort "BrandName" in jedem Fall in einen Span eingeschlossen werden.Nicht

BrandName
, aber
BrandName
ShambalaG

Antwort

2

$.fn.ignore = function(sel){ 
 
    return this.clone().find(sel||">*").remove().end(); 
 
}; 
 

 
function rebrand(el, word){ 
 
    if (!word.length && !el) return; 
 
    var $el = $(el), html = $el.ignore("script").html(), 
 
     rgx = new RegExp("(?![^<]+>)("+ word +")", "g"); 
 
    $el.html(html.replace(rgx, "<span class='brand'>$1</span>")); 
 
} 
 

 
$(function() { // DOM ready 
 

 
    // !!! IMPORTANT: REBRAND FIRST !!! 
 
    rebrand("body", "Brand Name"); 
 
    // so the following code will not break on lost events, data bindings etc... 
 

 
    // Other DOM ready code here like: 
 
    $("button").click(function(){ $(this).css({color:"red"}); }); 
 
    
 
}); 
 

 
// Other JS, jQ code here...
.brand{ 
 
    color: rgba(255,0, 100,0.4); 
 
    font: italic normal bold 1em/1 sans-serif; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div> 
 
    <h1>Title with Brand Name!</h1> 
 
    <p> 
 
    Change styles only to Brand Name!<br> 
 
    but don't mess with <a href="#">links to Brand Name are cool</a><br> 
 
    <button>Button with Brand Name works!</button> 
 
    </p> 
 
    <ul> 
 
    <li>Other Brand</li><li>Brand Name</li><li>Brandy</li> 
 
    </ul> 
 
</div> 
 
<div> 
 
    <h2>Subtitle <i>and italic Brand Name</i></h2> 
 
    <p>The HTML will not get messed cause of Brand Nameing<br> 
 
    Paragraph with a &lt;b&gt; tag <b>bold Brand Name actually</b></p> 
 
    <code>This is a code tag with a Brand Name :)</code> 
 
</div>

Ein großes Lob an die beiden Antworten:
jQuery.ignore Plugin
Highlight Words (Ignoring names of HTML tags)

1

ist meine Lösung ein wenig anders als die vorherigen, aber in jedem Fall immer gültig, ich annehmen.

Im Anschluss an meiner jQuery-Funktion:

function replaceBrand(brandName) { 
    $('body').find(":not(iframe)").contents().filter(function(index, element) { 
    if (element.nodeType == 3 && element.nodeValue.indexOf(brandName) != -1) { 
     var newInnerValue = element.nodeValue.replace(brandName, '<div><span class="brand">' + brandName + '</span></div>'); 
     $(element).replaceWith(newInnerValue); 
    } 
}); 

}

replaceBrand ('Markenname', 'neue Marke');

2

, wenn Ihr Code funktioniert, fügen Sie einfach eine so ähnliche Zeile des Codes:

this.nodeValue.wrap("<span class='new'></span>"); 
3

Sie können die textNodes mit einem Dokumentfragment ersetzen. Auf diese Weise können Sie Text und formatierte Knoten gruppieren und mit dem vorhandenen textNode austauschen.

var x = 0; 
 
$("body *").contents().each(function() { 
 

 
    if (this.nodeType == 3 && this.parentElement.tagName != "SCRIPT") { 
 

 
    var text = this.nodeValue; 
 
    var i = 0, lastIndex = 0; 
 
    var search = /brandname/ig; 
 
    var result; 
 
    var parent = this.parentNode; 
 
    var textNode = null; 
 
    var highlight = null; 
 
    var textRange = ""; 
 
    var fragment = document.createDocumentFragment(); 
 

 
    // Do search 
 
    while ((result = search.exec(text)) !== null) { 
 
    
 
     // add plain text before match 
 
     textRange = text.substring(lastIndex, result.index); 
 
     if (textRange != '') { 
 
     textNode = document.createTextNode(textRange); 
 
     fragment.appendChild(textNode); 
 
     } 
 
     
 
     // add highlight elements 
 
     highlight = document.createElement('span'); 
 
     highlight.innerHTML = result[0]; 
 
     highlight.className = "hi"; 
 
     fragment.appendChild(highlight); 
 
     lastIndex = search.lastIndex; 
 
    } 
 

 
    // Add trailing text 
 
    textRange = text.substring(lastIndex); 
 
    if (textRange != '') { 
 
     textNode = document.createTextNode(textRange); 
 
     fragment.appendChild(textNode); 
 
    } 
 
     
 
    // Replace textNode with our text+highlight 
 
    if(fragment.children.length > 0) { 
 
     this.parentNode.replaceChild(fragment, this); 
 
    } 
 
    } 
 

 
});
span.hi { 
 
    background-color: #FFCC00; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<p> 
 
    Hello world this is my brandname. The BrAnDNAMe is regex matched and we can change subelements like "<a href=''>Brandname</a>." It should not replace <b>elements</b> that don't match. 
 
</p>

1
var rgx_BRAND = /(foo)/ig; 
$("*") 
    .contents() 
    .filter(function() { 
     return this.nodeType === Node.TEXT_NODE && this.textContent.search(rgx_BRAND) > -1; 
    }) 
    .each(function(){ 
     var html = this.textContent.replace(rgx_BRAND, '<b class="-my-brand">$1</b>'); 
     $(this).before(html).remove(); 
    }); 

hoffe, das hilft, Prost

1

von Ihrem Snippet Going:

$(function() { 
    var parent, needle = 'brandname', 
     regex = new RegExp(needle, 'g'); 
    $("body *").contents().each(function() { 
     if(this.nodeType==3 && ((parent = $(this.parentNode)).length > 0) { 
      parent.html(parent.html().replace(
       regex, '<span class="brand-name">' + needle + '</span>')); 
     } 
    } 
}); 

Es kann nicht der effizienteste Ansatz sein, aber recht einfach und die bekommen die Arbeit in meinen Tests gemacht. Das Nachschlagen der Eigenschaft parentNode sollte in all browsers funktionieren.

+1

seien Sie vorsichtig, dies ersetzt auch alle Klassennamen oder andere Attributwerte innerhalb des übergeordneten Elements, die mit dem Markennamen übereinstimmen. Dies ist wahrscheinlich der Grund, warum nodeValue vom OP verwendet wurde. –

Verwandte Themen