JQuery: найдите текст элемента списка, который содержит вложенный ul
У меня есть следующее:
<ul id="list">
<li>item1
<ul>
<li>sub1</li>
<li>sub2</li>
</ul>
</li>
</ul>
Я бы хотел ответить на событие щелчка li и использовать текст li в другом месте. Однако, если щелчок находится на ли, который содержит вложенную ul, я, конечно, получаю текст всех элементов.
$("#list li").click(function() {
alert($(this).text());
});
возвращает item1sub1sub2, как ожидалось.
Я не могу понять, как получить только "item1", если щелкнуть элемент 1 li. Я пробовал следующее (между прочим) без везения:
$("#list li").click(function() {
alert($(this).filter("ul").text());
});
Любые идеи?
ИЗМЕНИТЬ
Это фрагмент примера - это может быть несколько уровней. Я также не хочу обертывать текст элемента списка в промежутке или другой разметке.
Ответы
Ответ 1
Как насчет этого подхода? Выполните клонирование объекта, удалите дочерние клоны и найдите текстовое содержимое.
$("#list li").click(function () {
alert($(this).clone().children().remove().end().text());
}
Возможно, это не самый эффективный подход, но он полностью интуитивно понятный, довольно аккуратный, и вам не нужно гадать с вашим html.
Ответ 2
Обычные DOM-методы позволяют получать текстовое содержимое только для одного элемента, а не для jquery:
$("#list li").click(function() {
alert($(this)[0].firstChild.textContent)
});
firstChild в этом случае является textNode под элементом li
Ответ 3
вам тяжело, потому что text()
делает то, что должен - возвращает текст этого и всех дочерних элементов. Самое простое - добавить еще один тег к каждому <li>
и использовать этот тег.
Например:
<ul id="list">
<li><span>item1</span>
<ul>
<li><span>sub1</span></li>
<li><span>sub2</span></li>
</</ul>
</li>
</ul>
И у вас есть простой селектор:
$("#list li").click(function() {
alert($(this).find("span").eq(0).text());
});
или, если возможно (в зависимости от вашего стиля), вы можете добавить событие в диапазон:
$("#list span").click(function() {
alert($(this).text());
});
Если вы не можете добавить эти <span>
(как вы говорите), вы можете использовать jQuery .contents()
, чтобы добавить их для вас, аналогично тому, что было сделано здесь:
Скрыть B в <x> A < br/ > B </x>
Ответ 4
Это проверяет, есть ли у элемента списка какие-либо дочерние элементы, и если он отфильтровывает только текстовые узлы и объединяет результат (в этом случае он будет работать для текстовых элементов, где бы они не были помещены в ли). Если вы только хотите проверить элементы в начале, вы можете избежать цикла for и просто работать с этим. 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();
});
Ответ 5
Таким образом, этот механизм вытаскивает html из дочернего элемента, заменяет новые строки ничем, а затем возвращает строку только до первого символа "<
". Я также добавил event.stopPropagation
, чтобы избежать нажатия на событие click bubbling до родителя.
<script type="text/javascript">
$("#list li").click(function(event) {
var sourceHTML = $(this).html().replace(/\n/g,'').replace(/<.*/,'');
alert(sourceHTML);
event.stopPropagation();
});
</script>
Ответ 6
Я думаю, вам нужно использовать каждый метод. поэтому попробуйте выполнить script:
$(document).ready(function() {
$('ul').each(function() {
$(this).find('li').click(function() {
var listItem = this;
alert($(listItem).text());
});
})
});
со следующей разметкой
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
Ответ 7
Другой способ добиться того же
$("#list li").click(function() {
alert($(this).contents().not('ul,ol').text());
});