2009-06-21 36 views
15

Tôi đã điều sau đây:jQuery: Tìm nội dung của một mục danh sách có chứa một ul lồng nhau

<ul id="list"> 
<li>item1 
    <ul> 
     <li>sub1</li> 
     <li>sub2</li> 
    </ul>  
</li> 
</ul> 

Tôi muốn để đáp ứng với một sự kiện li nhấp chuột và sử dụng nội dung của li nơi khác. Tuy nhiên, nếu bấm vào một li có chứa một ul lồng nhau, tôi tất nhiên có được văn bản của tất cả các yếu tố.

$("#list li").click(function() { 
    alert($(this).text()); 
}); 

trả về mục1sub1sub2, như mong đợi.

Tôi không thể tìm ra cách chỉ nhận 'item1' nếu nhấn li mục 1. Tôi đã thử những điều sau (trong số những thứ khác) mà không có may mắn:

$("#list li").click(function() { 
    alert($(this).filter("ul").text()); 
}); 

Bất kỳ ý tưởng nào?

EDIT

Đây là một ví dụ - nó có thể là nhiều cấp độ sâu. Tôi cũng không muốn bọc văn bản của mục danh sách trong một khoảng thời gian hoặc đánh dấu khác.

Trả lời

14

Còn cách tiếp cận này thì sao? Sao chép đối tượng, xóa con của bản sao và rồi tìm nội dung văn bản.

$("#list li").click(function() { 
    alert($(this).clone().children().remove().end().text()); 
} 

Có lẽ không phải là cách tiếp cận hiệu quả nhất, nhưng nó hoàn toàn trực quan, khá gọn gàng và bạn không phải muck với html của mình.

phương pháp
+0

Cảm ơn, điều này hoạt động tốt. Tôi đã chọn đây là câu trả lời đúng, nhưng tôi có thể thêm một khoảng xung quanh văn bản để làm cho điều này một chút sạch hơn trong trường hợp này. Vẫn là một mẹo tốt cho các tình huống tương tự. – ScottE

7

bạn đang gặp khó khăn vì text() sẽ làm gì - trả về văn bản của điều này và tất cả các phần tử con. Điều dễ nhất cần làm là thêm một thẻ khác vào mỗi <li> và sử dụng thẻ này.
Ví dụ:

<ul id="list"> 
<li><span>item1</span> 
    <ul> 
     <li><span>sub1</span></li> 
     <li><span>sub2</span></li> 
    </</ul>  
</li> 
</ul> 

Và sau đó bạn có một selector đơn giản:

$("#list li").click(function() { 
    alert($(this).find("span").eq(0).text()); 
}); 

hoặc, nếu possilbe (tùy thuộc vào phong cách của bạn), bạn có thể thêm sự kiện vào khoảng:

$("#list span").click(function() { 
    alert($(this).text()); 
}); 

Nếu bạn không thể thêm <span> s (như bạn nói), bạn có thể sử dụng .contents() của jQuery để thêm chúng cho bạn, tương tự như những gì đã được thực hiện tại đây:

Hide B in <x>A<br/>B</x>

+0

Cảm ơn bạn đã nói về '.contents()', điều đó đã giúp tôi giải quyết một vấn đề tương tự! – thebrokencube

+0

Thêm s loại bỏ các khối có thể nhấp từ các mục danh sách – Shenaniganz

0

Vì vậy, cơ chế này kéo ra html từ phần tử con, thay thế các dòng mới với không có gì, và sau đó trả về chuỗi chỉ lên đến ký tự đầu tiên "<". Tôi cũng đã thêm event.stopPropagation để tránh kêu gọi sự kiện nhấp chuột phát ra từ cha mẹ.

<script type="text/javascript"> 
$("#list li").click(function(event) { 
    var sourceHTML = $(this).html().replace(/\n/g,'').replace(/<.*/,''); 
    alert(sourceHTML); 
    event.stopPropagation(); 
}); 
</script> 
0

Tôi nghĩ bạn cần sử dụng từng phương pháp. vì vậy hãy thử kịch bản sau đây:

$(document).ready(function() { 
     $('ul').each(function() { 
      $(this).find('li').click(function() { 
       var listItem = this; 
       alert($(listItem).text()); 
      }); 
     }) 
    }); 

với đánh dấu sau

<ul> 
    <li>1</li> 
    <li>2</li> 
    <li>3</li> 
    <li>4</li> 
</ul> 
+1

Xin chào. văn bản() trên một phần tử li sẽ vẫn trả lại toàn bộ văn bản của tất cả các trẻ em. Trong thực tế, mỗi() là dư thừa ở đây, nó giống như '$ (ul li) .click' – Kobi

1

kiểm tra này, nếu mục danh sách có bất kỳ trẻ em và nếu như vậy nó lọc ra chỉ các nút văn bản và concatenates kết quả (trong này trường hợp nó sẽ làm việc cho các yếu tố văn bản bất cứ nơi nào họ đang đặt trong li). Nếu bạn chỉ muốn kiểm tra các phần tử ngay từ đầu, bạn có thể tránh vòng lặp for và chỉ làm việc với nó.firstChild

$("#list li").click(function(e) { 
    if ($(this).children().length > 0) { 
     var text = ""; 
     for (var i = 0; i < this.childNodes.length; i++) { 
      var node = this.childNodes[i]; 
      if (node.nodeType === 3 && $.trim(node.nodeValue).length > 0) { 
       text += $.trim(node.nodeValue); 
      } 
     } 
     alert(text); 
    } 
    else { 
     alert($(this).text()); 
    } 
    e.stopPropagation(); 
}); 
9

Bình thường DOM cho phép để truy cập vào nội dung văn bản cho chỉ là một yếu tố, chứ không phải là jquery:

$("#list li").click(function() { 
    alert($(this)[0].firstChild.textContent) 
}); 

firstChild trong trường hợp này là textNode dưới các yếu tố li

+0

Tôi thích phương pháp này vì bạn cũng có thể sử dụng nó để đặt văn bản, mà không làm mất bất kỳ phần tử được bao bọc nào, không giống như phiên bản khác. (Trong phạm vi của câu hỏi, tôi biết, nhưng tôi cần cả hai.) – Archer

0

Một cách khác để đạt được cùng một

$("#list li").click(function() { 
    alert($(this).contents().not('ul,ol').text()); 
}); 
Các vấn đề liên quan