Ответ 1
Это явно ошибка, а не то, как она должна работать.
Источником closest()
является
function (selectors, context) {
var cur,
i = 0,
l = this.length,
matched = [],
pos = rneedsContext.test(selectors) || typeof selectors !== "string"
?
jQuery(selectors, context || this.context)
:
0;
for (; i < l; i++) {
for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
// Always skip document fragments
if (cur.nodeType < 11 && (pos ? pos.index(cur) > -1 :
// Don't pass non-elements to Sizzle
cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {
matched.push(cur);
break;
}
}
}
return this.pushStack(matched.length > 1 ? jQuery.unique(matched) : matched);
}
Что примечательно, так это способ pos
, он ищет коллекцию для ближайшего родительского элемента, а rneedsContext
- это регулярное выражение
/^[\x20\t\r\n\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\([\x20\t\r\n\f]*((?:-\d)?\d*)[\x20\t\r\n\f]*\)|)(?=[^-]|$)/i
Если переданный в селекторе не соответствует этому регулярному выражению, контекст не используется вообще, pos
будет равен 0
, а проверка для cur
в этой коллекции просто пропущена вместе, что кажется странным странным.
Быстрый тест показывает
var reg = /^[\x20\t\r\n\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\([\x20\t\r\n\f]*((?:-\d)?\d*)[\x20\t\r\n\f]*\)|)(?=[^-]|$)/i;
reg.test('#outer'); // false, no context used
reg.test('#outer:first'); // true, context used
reg.test('#outer:eq(0)'); // true, context used
Итак, если вы добавляете псевдоселектор, он неожиданно использует контекст?
Я сомневаюсь, что это то, что было предназначено, и это кажется странным делом, и, конечно же, он не делает то, что говорит в документации.