2009-09-18 2 views
5

Tôi đang cố gắng tìm ra cách thay thế bằng Javascript. Tôi đang xem toàn bộ nội dung của trang và muốn thay thế từ khóa phù hợp KHÔNG trong thẻ HTML.Trong JavaScript, làm thế nào tôi có thể thay thế văn bản trong một trang HTML mà không ảnh hưởng đến các thẻ?

Dưới đây là một ví dụ:

<body> 
    <span id="keyword">blah</span> 
    <div> 
    blah blah keyword blah<br /> 
    whatever keyword whatever 
    </div> 
</body> 

<script type="text/javascript"> 
var replace_terms = { 
    'keyword':{'url':'http://en.wikipedia.org/','target':'_blank'} 
} 

jQuery.each(replace_terms, function(i, val) { 
    var re = new RegExp(i, "gi"); 
    $('body').html(
    $('body').html().replace(re, '<a href="'+ val['url'] +'" target="'+val['target']+'">' + i + '</a>') 
); 
}); 

</script> 

tôi đang tìm để thay thế tất cả các trường hợp của "keyword" đó không phải là trong một thẻ HTML (giữa <>).

Tôi đoán tôi cũng cần bỏ qua nếu "từ khóa" nằm trong thành phần script hoặc style.

+2

Không phải là toàn bộ trang theo định nghĩa bên trong một thẻ HTML? –

+0

Có. HTML tôi đã có trong ví dụ của tôi đã không đi qua. Về cơ bản tôi có nghĩa là tôi không muốn thay thế bất kỳ thuộc tính nào của thẻ. – Phil

+1

Tôi nghĩ rằng anh ấy có nghĩa là trong dấu ngoặc đơn (như tên/giá trị thuộc tính). – Mayo

Trả lời

12

Không sử dụng regex để phân tích cú pháp HTML. [X] [HT] ML không phải là ngôn ngữ thông thường và không thể xử lý một cách đáng tin cậy bằng regex. Trình duyệt của bạn có sẵn trình phân tích cú pháp HTML tốt; hãy để điều đó làm cho sự căng thẳng của việc phát triển các thẻ.

Ngoài ra, bạn không thực sự muốn làm việc trên html()/innerHTML trên cơ thể. Điều này sẽ nối tiếp và phân tích lại toàn bộ trang, sẽ chậm và sẽ mất mọi thông tin không thể được tuần tự hóa trong HTML, chẳng hạn như các trình xử lý sự kiện, các giá trị biểu mẫu và các tham chiếu JavaScript khác.

Dưới đây là một phương pháp sử dụng DOM mà dường như làm việc cho tôi:

function replaceInElement(element, find, replace) { 
    // iterate over child nodes in reverse, as replacement may increase 
    // length of child node list. 
    for (var i= element.childNodes.length; i-->0;) { 
     var child= element.childNodes[i]; 
     if (child.nodeType==1) { // ELEMENT_NODE 
      var tag= child.nodeName.toLowerCase(); 
      if (tag!='style' && tag!='script') // special case, don't touch CDATA elements 
       replaceInElement(child, find, replace); 
     } else if (child.nodeType==3) { // TEXT_NODE 
      replaceInText(child, find, replace); 
     } 
    } 
} 
function replaceInText(text, find, replace) { 
    var match; 
    var matches= []; 
    while (match= find.exec(text.data)) 
     matches.push(match); 
    for (var i= matches.length; i-->0;) { 
     match= matches[i]; 
     text.splitText(match.index); 
     text.nextSibling.splitText(match[0].length); 
     text.parentNode.replaceChild(replace(match), text.nextSibling); 
    } 
} 

// keywords to match. This *must* be a 'g'lobal regexp or it'll fail bad 
var find= /\b(keyword|whatever)\b/gi; 

// replace matched strings with wiki links 
replaceInElement(document.body, find, function(match) { 
    var link= document.createElement('a'); 
    link.href= 'http://en.wikipedia.org/wiki/'+match[0]; 
    link.appendChild(document.createTextNode(match[0])); 
    return link; 
}); 
+1

'i -> 0' Thông minh. Tôi chưa bao giờ thấy điều đó trước đây. –

+2

Tôi không thể yêu cầu tín dụng cho điều đó, đó là thành ngữ cho việc lặp lại ngược trong các ngôn ngữ giống như C! :-) – bobince

+0

Tôi thường chỉ sử dụng 'i -', như trong: 'cho (var i = 100; i--;)' – kangax