2010-02-23 34 views
12

Tôi đang gặp khó khăn khi gói đầu quanh những gì nên là một giải pháp đơn giản. Tôi muốn thay thế văn bản trong một thẻ nhãn, mà không ảnh hưởng đến các 'anh chị em' khác, nếu chúng tồn tại.jQuery thay thế văn bản để lại anh chị em còn nguyên vẹn

đánh dấu mẫu:

<fieldset class="myFieldsetClass"> 
    <legend>Sample Fieldset</legend> 
    <ol> 
     <li> 
      <label> 
       <span class="marker">*</span> 
       Some Label 1 
      </label> 
     </li> 
     <li> 
      <label> 
       Some Label 2 
      </label> 
     </li> 
     <li> 
      <label> 
       Text that doesn't match... 
      </label> 
     </li> 
    </ol> 
</fieldset> 

Mục tiêu:

  • Để thay thế văn bản Some Label X với Some Label (Tức là loại bỏ X từ các văn bản nhãn).
  • thẻ span trong nhãn phải giữ nguyên vẹn nếu chúng tồn tại, chẳng hạn như <span class="marker"> ở trên.
  • Tôi không biết giá trị của X, có thể dài từ 1 ký tự trở lên.

Script hiện tại:

kịch bản jQuery My bên dưới công trình, nhưng tôi biết là rất không hiệu quả. Tôi dường như không thể quấn quanh đầu tôi cái này vì một lý do ...

//for each label in the fieldset that contains text "Some Label " 
$(".myFieldsetClass label:contains('Some Label ')").each(function() { 

    if ($(this).has("span").length > 0) { 

     //if the label has the span tag within, remove it and prepend it back to the replaced text 
     $(this).find("span").remove().prependTo($(this).text(labelText)); 

    } 
    else { 

     //otherwise just replace the text 
     $(this).text('Some Label'); 

    } 

}); 

tôi nghĩ lúc đầu tôi chỉ có thể làm:

$(".myFieldsetClass label:contains('Some Label ')").text("Some Label"); 

Nhưng điều này sẽ xóa tất cả nội dung của nhãn và do đó loại bỏ khoảng thời gian mà tôi không muốn. Tôi không thể sử dụng bất kỳ chức năng thay thế nào để thay thế Some Label X bằng Some Label vì tôi không biết X sẽ là gì.

Có ai có thể đề xuất cách tiếp cận trang nhã/hiệu quả hơn cho vấn đề này không?

Cảm ơn.

EDIT

Sau khi thử nhiều câu trả lời, tôi nghĩ rằng vấn đề có vẻ là rằng ngay cả nếu tôi chọn bộ sưu tập đúng, họ là các nút văn bản, mà jquery dường như không muốn thay đổi .. Tôi đã sử dụng FireBug để chọn bộ sưu tập (nhiều câu trả lời dưới đây đều chọn đúng nhưng theo những cách hơi khác nhau). Trong bảng điều khiển firebug kết quả thiết lập là:

[<TextNode textContent="Some Label 1:">, 
<TextNode textContent="Some Label 2:">, 
<TextNode textContent="Some Label 3:">, 
<TextNode textContent="Some Label 4:">, 
<TextNode textContent="Some Label 5:">] 

Vấn đề dường như là gọi .replaceWith(), .replace(), .text(), vv dường như không ảnh hưởng đến các bộ sưu tập jquery. Nếu tôi cho phép các bộ sưu tập trên để chứa một trong những nhịp, sau đó gọi .replaceWith(), .replace(), vv chức năng một cách chính xác so với khoảng thời gian, nhưng các nút văn bản ở lại như là ..

+1

sẽ 'x' bao giờ được bao bọc trong thẻ của riêng mình, hoặc sẽ nó luôn luôn được văn bản đơn giản? –

+0

Allways plain text, không bao giờ nằm ​​trong một thẻ khác. –

Trả lời

10

Hãy thử:

$(".myFieldsetClass label:contains('Some Label ')").contents().filter(':last-child').text("Some Label"); 

Điều này có tác dụng giả định rằng văn bản sẽ được thay thế sẽ luôn ở cuối. Hàm contents() chọn tất cả các nút, bao gồm các nút văn bản.

http://api.jquery.com/contents/

EDIT: Tôi đã sử dụng bộ lọc() thay vì tìm().Đã sửa.

EDIT: Hoạt động ngay bây giờ. Đây là một cách.

// Store proper labels in a variable for quick and accurate reference 
var $labelCollection = $(".myFieldsetClass label:contains('Some Label ')"); 

// Call contents(), grab the last one and remove() it 
$labelCollection.each(function() { 
    $(this).contents().last().remove() 
}); 

// Then simply append() to the label whatever text you wanted. 
$labelCollection.append('some text') 
+0

Cảm ơn bạn đã đề xuất. Tôi tìm thấy một vấn đề, trong đó '.contents(). Filter (': last')' chỉ trả về mục cuối cùng trong toàn bộ tập hợp, trong đó tập hợp nội dung chứa nhiều nút văn bản nhãn. Ngoài ra, .text() áp dụng cho các nút này dường như không ảnh hưởng đến ... –

+0

Nhưng nếu bạn đang gọi nó trên nhãn, 'nội dung()' chỉ nên trả lại nội dung của nhãn đó. Theo như 'text()' có liên quan, bạn có thể chỉ đơn giản là 'remove()' là nút văn bản và 'append()' văn bản mới. – user113716

+0

Tôi hiểu. Tôi sẽ đặt cược 'đứa con cuối cùng' là cần thiết. – user113716

7

Khi patrick chỉ ra, bạn có thể sử dụng contents() để chọn văn bản một mình, sau đó thay thế tất cả. Thích ứng với ví dụ đưa ra ở đó, bạn cũng có thể thử:

$(".myFieldsetClass label:contains('Some Label ')").contents().filter(function() { 
    return this.nodeType == 3 && $(this).is(":contains('Some Label ')"); 
}) 
.replaceWith("Some Label"); 

Tuy nhiên, nếu bạn biết rằng "Một số Label" sẽ luôn luôn là yếu tố cuối cùng trong <label> sau đó phương pháp patrick của sẽ nhanh hơn tôi tin.

+0

Điều kỳ lạ nhất. Nó tìm thấy tập hợp các nút, nhưng '.replaceWith (" Some Label ");' gọi thực sự xóa tất cả các giá trị nút văn bản (nhãn văn bản trở nên trống rỗng, kéo dài ở nguyên vẹn) ... –

+0

@KP; Tôi đã cập nhật nó - sử dụng 'is()' trong điều kiện bộ lọc cho phép bạn có nhiều nút văn bản và chỉ thay đổi một nút có chứa "Some Label" ... cho tôi biết nếu điều này không khắc phục được sự cố –

+0

@KP, được sử dụng trong IE và nó hoạt động tốt (trước khi thay đổi bộ lọc .is). Ngoài ra, bạn luôn có thể quay lại POJ và gọi ... nodeType == 3) .each (function() {$ (this) [0] .data = "Some Label";}); – Marc

2

Tại sao không thực hiện thay thế toàn bộ bằng regex?

$(".myFieldsetClass label:contains('Some Label ')") 
    .each(function() { 
      $(this).html($(this).html().replace(/Some Label ./, "Some Label")); 
     }); 
+0

Không phải là một ý tưởng tồi. Thay thế không hoạt động? '.replace ("/Một số Nhãn ./ "," Một số Nhãn "))' không khớp với văn bản. Tôi đảm bảo bộ chọn tổng thể '$ (". MyFieldsetClass label: contains ('Some Label') ")' đang lấy các phần tử mong muốn .. –

+0

+1 cho ý tưởng tốt để sử dụng regex. Mẫu không khớp và regex không phải là sức mạnh của tôi nên tôi đã chọn một câu trả lời khác .. –

0

Một one-liner:

$('.myFieldsetClass label').contents().last().remove().end().first().after('New Label') 
Các vấn đề liên quan