2013-05-21 37 views
18

Tôi đã có một chút nút văn bản:Chèn HTML vào nút văn bản với Javascript

var node 

Và tôi muốn quấn một khoảng xung quanh mỗi lần xuất hiện của "lol".

node.nodeValue = node.nodeValue.replace(/lol/, "<span>lol</span>") 

Nó in ra "<span>lol<span>" khi tôi muốn "lol" làm yếu tố nhịp.

+0

trong trường hợp đó bạn sẽ phải repace nút văn bản với nội dung html –

+0

@ArunPJohny Làm thế nào để làm điều đó? – alt

+0

@ JacksonGariety — bạn cần thay thế nút văn bản bằng phần tử span và các nút văn bản DOM mới hoặc sửa đổi thuộc tính innerHTML của cha mẹ. Có một chuyến đi, đăng những gì bạn thử. – RobG

Trả lời

3

Bạn có thể cần node là nút cha, như vậy bạn chỉ có thể sử dụng innerHTML:

node.innerHTML=node.childNodes[0].nodeValue.replace(/lol/, "<span>lol</span>"); 

Đây node.childNodes[0] đề cập đến nút văn bản thực tế, và node là yếu tố chứa của nó.

+6

Được cảnh báo thay thế innerHTML của nút chứa có khả năng phá hoại các nút con có thể có các trình nghe sự kiện được thêm thông qua các tập lệnh. – ccjuju

+0

Tính năng này không hoạt động đối với tôi (Chrome 50); không có thay đổi trực quan. Tôi có thể thấy trong giao diện điều khiển mà 'node.innerHTML' đã thay đổi, nhưng không có thay đổi đối với giao diện người dùng. Ngoài ra, 'node.parentNode.innerHTML' không chứa thay đổi mới. – Jeff

15

Bài viết sau đây sẽ cho bạn mã để thay thế văn bản với các yếu tố HTML:

http://blog.alexanderdickson.com/javascript-replacing-text

Từ bài viết:

var matchText = function(node, regex, callback, excludeElements) { 

    excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']); 
    var child = node.firstChild; 

    do { 
     switch (child.nodeType) { 
     case 1: 
      if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1) { 
       continue; 
      } 
      matchText(child, regex, callback, excludeElements); 
      break; 
     case 3: 
      child.data.replace(regex, function(all) { 
       var args = [].slice.call(arguments), 
        offset = args[args.length - 2], 
        newTextNode = child.splitText(offset); 

       newTextNode.data = newTextNode.data.substr(all.length); 
       callback.apply(window, [child].concat(args)); 
       child = newTextNode; 
      }); 
      break; 
     } 
    } while (child = child.nextSibling); 

    return node; 
} 

Cách sử dụng:

matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) { 
    var span = document.createElement("span"); 
    span.className = "search-term"; 
    span.textContent = match; 
    node.parentNode.insertBefore(span, node.nextSibling); 
}); 

Và lời giải thích :

Về cơ bản, đúng cách để làm điều đó là ...

  1. lặp qua tất cả các nút văn bản.
  2. Tìm chuỗi con trong các nút văn bản.
  3. Tách tại giá trị bù trừ.
  4. Chèn phần tử span ở giữa phần tách.
13

Câu trả lời được trình bày bởi Andreas Josas khá tốt. Tuy nhiên, mã có một số lỗi khi cụm từ tìm kiếm xuất hiện nhiều lần trong cùng một nút văn bản. Đây là giải pháp với những lỗi đó được sửa và bổ sung thêm phần thừa vào trong matchText để sử dụng và hiểu dễ dàng hơn. Bây giờ chỉ có thẻ mới được tạo trong hàm gọi lại và được trả lại cho matchText bằng cách trả về.

Cập nhật matchText chức năng với sửa lỗi:

var matchText = function(node, regex, callback, excludeElements) { 

    excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']); 
    var child = node.firstChild; 

    while (child) { 
     switch (child.nodeType) { 
     case 1: 
      if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1) 
       break; 
      matchText(child, regex, callback, excludeElements); 
      break; 
     case 3: 
      var bk = 0; 
      child.data.replace(regex, function(all) { 
       var args = [].slice.call(arguments), 
        offset = args[args.length - 2], 
        newTextNode = child.splitText(offset+bk), tag; 
       bk -= child.data.length + all.length; 

       newTextNode.data = newTextNode.data.substr(all.length); 
       tag = callback.apply(window, [child].concat(args)); 
       child.parentNode.insertBefore(tag, newTextNode); 
       child = newTextNode; 
      }); 
      regex.lastIndex = 0; 
      break; 
     } 

     child = child.nextSibling; 
    } 

    return node; 
}; 

Cách sử dụng:

matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) { 
    var span = document.createElement("span"); 
    span.className = "search-term"; 
    span.textContent = match; 
    return span; 
}); 

Nếu bạn mong muốn để chèn anchor (liên kết) thẻ thay cho các thẻ span, thay đổi tạo ra yếu tố là "một "thay vì" span ", thêm một dòng để thêm thuộc tính href vào thẻ và thêm 'a' vào danh sách excludeElements để các liên kết sẽ không được tạo bên trong các liên kết.

+1

Tôi thêm một sửa chữa 'regex.lastIndex = 0' để thiết lập lại regex khi tái sử dụng nó. Xem http://stackoverflow.com/questions/1520800/why-regexp-with-global-flag-in-javascript-give-wrong-results – Jeff

2

Không nói đây là câu trả lời hay hơn, nhưng tôi đăng những gì tôi đã làm để hoàn thành. Trong trường hợp của tôi, tôi đã tra cứu hoặc xác định các khoảng trống của văn bản mà tôi cần làm nổi bật trong một nút #text cụ thể. Điều này cũng làm rõ các bước.

//node is a #text node, startIndex is the beginning location of the text to highlight, and endIndex is the index of the character just after the text to highlight  

var parentNode = node.parentNode; 

// break the node text into 3 parts: part1 - before the selected text, part2- the text to highlight, and part3 - the text after the highlight 
var s = node.nodeValue; 

// get the text before the highlight 
var part1 = s.substring(0, startIndex); 

// get the text that will be highlighted 
var part2 = s.substring(startIndex, endIndex); 

// get the part after the highlight 
var part3 = s.substring(endIndex); 

// replace the text node with the new nodes 
var textNode = document.createTextNode(part1); 
parentNode.replaceChild(textNode, node); 

// create a span node and add it to the parent immediately after the first text node 
var spanNode = document.createElement("span"); 
spanNode.className = "HighlightedText"; 
parentNode.insertBefore(spanNode, textNode.nextSibling); 

// create a text node for the highlighted text and add it to the span node 
textNode = document.createTextNode(part2); 
spanNode.appendChild(textNode); 

// create a text node for the text after the highlight and add it after the span node 
textNode = document.createTextNode(part3); 
parentNode.insertBefore(textNode, spanNode.nextSibling); 
+0

Cảm ơn vì điều đó, đó là câu trả lời hay nhất cho tôi – romuleald

Các vấn đề liên quan