Подтвердить что ты не робот

Селектор jQuery для элемента, который содержит текст?

Мне удалось частично работать с помощью селектора :contains, но моя проблема в том, что элемент содержит элемент, содержащий текст, который он все еще возвращает. Например:

$('div:contains("test")')

Выберем оба divs ниже:

<div>something else
   <div>test</div>
</div>

скрипт: http://jsfiddle.net/TT7dR/

Как я могу выбрать только те div, которые "непосредственно" содержат текст? Это означает, что в приведенном выше примере будет выбран только дочерний div.

UPDATE:

Просто чтобы уточнить, если бы я искал текст "что-то еще" вместо "test", тогда я бы хотел найти только родительский div.

4b9b3361

Ответ 1

$('div>:contains("test")') не является общим решением, оно работает только для вашего конкретного примера. Он по-прежнему соответствует любому элементу, чьи потомки содержат текст test, если его родительский элемент является div.

В настоящее время нет селектора, который будет выбирать только прямых родителей текстовых узлов, содержащих ваш целевой текст. Для этого вам нужно будет пройти дерево DOM, проверяя каждый текст node, который вы найдете для целевого текста, или напишите плагин, чтобы сделать то же самое. Он будет медленным, но не таким медленным, как :contains уже (это не стандартный селектор CSS, поэтому вы не получите поддержку быстрого выбора браузера).

Здесь есть простая функция DOM, которую вы можете использовать в качестве отправной точки. Возможно, было бы лучше найти текст в смежных (ненормированных) текстовых узлах или скрыть его в расширении плагина/селектора.

function findElementsDirectlyContainingText(ancestor, text) {
    var elements= [];
    walk(ancestor);
    return elements;

    function walk(element) {
        var n= element.childNodes.length;
        for (var i= 0; i<n; i++) {
            var child= element.childNodes[i];
            if (child.nodeType===3 && child.data.indexOf(text)!==-1) {
                elements.push(element);
                break;
            }
        }
        for (var i= 0; i<n; i++) {
            var child= element.childNodes[i];
            if (child.nodeType===1)
                walk(child);
        }
    }
}

Ответ 2

Просто заполните базу знаний. Если вам нужно получить все элементы DOM внутри тела (а не только DIV), которые содержат определенный текст или символы, которые вы можете использовать:

function getNodesThatContain(text) {
    var textNodes = $(document).find(":not(iframe, script)")
      .contents().filter( 
          function() {
           return this.nodeType == 3 
             && this.textContent.indexOf(text) > -1;
    });
    return textNodes.parent();
};

console.log(getNodesThatContain("test"));

Надеюсь, что это поможет.

jsfiddle: http://jsfiddle.net/85qEh/2/

Кредиты: DMoses

Ответ 3

Возможно, вам придется выполнить неэффективный запрос. Не используйте это решение, если кто-то найдет селектор, которому удастся отфильтровать дочерние элементы: http://viralpatel.net/blogs/2011/02/jquery-get-text-element-without-child-element.html

$("div:contains('test')")
    .clone()    //clone the element
    .children() //select all the children
    .remove()   //remove all the children
    .end()  //again go back to selected element
    .filter(":contains('test')")

edit: этот фрагмент выше - это просто проверить элемент, в реализации он будет выглядеть примерно так: http://jsfiddle.net/rkw79/TT7dR/6/

$("div:contains('test')").filter(function() {
    return (
    $(this).clone() //clone the element
    .children() //select all the children
    .remove() //remove all the children
    .end() //again go back to selected element
    .filter(":contains('test')").length > 0)
}).css('border', 'solid 1px black');

Ответ 4

попробуйте добавить значение больше:

$('div>:contains("test")')

Ответ 5

Кажется, это работает для меня:

$('div >:contains("test")');

http://jsfiddle.net/TT7dR/1/

Это приводит к тому, что выбранный селектор :contains является прямым потомком элемента <div>

Ответ 6

Попробуйте следующее:

$("div>div:contains(test):only-of-type")

Ответ 7

Находит определенный элемент, но не родители

var elementsContainingText = ($(':contains("' + text + '")', target)).filter(function() {
    return $(this).contents().filter(function() {return this.nodeType === 3 && this.nodeValue.indexOf(text) !== -1; }).length > 0;
});

Ответ 8

Добавьте еще одну альтернативу:

if($(selector).text().trim().length) {
   var thetext = $(selector).contents().filter(function(){
     return this.nodeType === 3;                     
   }).text().trim();    

  console.log(thetext);             

}

Он выберет только текст и удалит любой элемент с тегом!

Ссылка

Ответ 9

Вы можете просто выбрать элемент, у которого нет вашего элемента

$('div:contains("test"):not(:has(> div))')

Ответ 10

меньше кода для написания (но с небольшим ограничением):

let selector = $('div:contains("test")');
selector.not(selector.has('div:contains("test")'))

Просто используйте функцию jQuery (.has), потому что CSS :has является экспериментальным: https://developer.mozilla.org/en-US/docs/Web/CSS/:has#Browser_compatibility


Ограничение:

Когда у вас есть такая структура:

<div>
<div>test</div>
test
</div>

Тогда этим решением будет найден только внутренний элемент div. Это потому, что все еще есть Элемент - Дочерний элемент div, который: содержит строку "test".