Почему метод jQuery.not() удаляет текстовые узлы?

Метод .not() принимает либо селектор, либо объект, с помощью которого можно фильтровать.

Метод .contents() возвращает объект jQuery, содержащий дочерние элементы и текстовые узлы элемента.

Когда селектор используется как аргумент для .not(), он удаляет выбранные элементы, а также все текстовые узлы.

Когда объект используется как аргумент для .not(), он удаляет объект, но не текстовые узлы.

Пример:

<p>This is a <span id="aSpan">paragraph</span> tag</p>

$("p").contents().not("span");
> []

Но!

var $sp = $("p span");
$("p").contents().not($sp);
> ["This is a ", " tag"]

и

var sp = document.getElementById("aSpan");
$("p").contents().not(sp);
> ["This is a ", " tag"]

Почему текстовые узлы выбраны селектором "span" (или любым другим селектором), но не экземпляром объекта?

Ответы

Ответ 1

Причина, по которой это происходит, можно проследить до данного конкретного редактирования, сделанного 3 года назад. Он объединяет методы .filter() и .not(), значительно упрощая их, поскольку они эффективно друг друга противоположны.

Перед тем, как это сделать, .not() вызвал бы .filter() внутренне, если селектор был чем-то вроде строки, поэтому он работал бы на отфильтрованной коллекции (т.е. .nodeType === 1), начиная с эта версия, сделанная 4 года назад.

Это означает, что - на основе вашего примера кода - до того, как edit .not(object) вернет пустую коллекцию, что кажется более логичным, чем его текущее поведение.

Теперь оба .not(object) и .filter(object) работают с нефильтрованной коллекцией, хотя только первый метод будет демонстрировать поведенческую разницу.