Что такое ванильный JS-эквивалент jQuery $ (документ)?

Я пытаюсь выяснить ванильный эквивалент следующего кода:

$(document).attr('key', 'value');

До сих пор я изучал

  • document - это не элемент, поэтому вы не можете называть setAttribute на нем
  • document.documentElement - возвращает тег html. Это не тот "элемент", который нацелен на jquery.
  • $(document)[0] похоже, возвращает теневой элемент в Chrome Inspector
  • $(document).attr('key', 'somethingUnique') не существует в Chrome Inspector

Является ли jQuery, создавая свой собственный элемент теневого элемента в документе, чтобы он мог рассматривать его как настоящий элемент? Какой элемент jQuery действительно ссылается, когда вы делаете $(document)?

Ответ 1

Набор результатов jQuery представляет собой массив, подобный объекту, который в общем случае содержит DOMElement, но jQuery действительно не заботится о том, какие объекты имеют объекты в наборе результатов. Ни DOMElements ни какой-либо другой элемент, который хранится в наборе результатов jQuery, каким-то образом издеваются/завернуты, они непосредственно хранятся в наборе результатов. jQuery пытается выяснить, что он должен делать с этими объектами, глядя на их доступные функции.

Когда вы вызываете .attr, jQuery проверяет каждый объект в наборе, если он имеет функцию getAttribute если это так, предполагается, что он также имеет функцию setAttribute.

Если у него нет функции getAttribute, он переадресует вызов функции функции .prop(), и prop внутренне сделает это:

elem[name] = value

Поэтому, если вы передадите простой объект jQuery, он просто установит его свойство.

var a = {  
}

$(a).attr('test', 'hello world');

console.dir(a) // for 'a'  the property 'test' is set
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Ответ 2

Я считаю, что вы неверны в отношении $(document) не ссылающегося на document, поэтому ответ (довольно просто):

document['key']  = 'value'

Например, в Chrome:

> $(document)[0] === document
true

> $(document).attr('blarg', 'narf')
n.fn.init [document, context: document]

> document.blarg
"narf"

> document.foo = 'bar'
"bar"

> document.foo
"bar"

Ответ 3

jQuery просто присваивает значение document напрямую.

$(document).attr('test', 'hello world');
console.log(document['test']); // prints "hello world"

Ответ 4

Я действительно думал, что jQuery будет обертывать элементы DOM, так как по какой-то причине я никогда не пишу var x = $('#x') чтобы повторно использовать его позже, но напомнить $.

Вот почему я написал:

Да, это завернуто

Но после прочтения @t.niese ответ здесь я попробовал

var x = $('#x')
var y = $('#y')

var ref = x[0]
x[0] = y[0] // hack jQuery Object reference to DOM element

setTimeout(() => x.html('1'), 1000) // actually writes in #y
setTimeout(() => x.html('2'), 2000) // actually writes in #y
setTimeout(() => { x.push(ref) }, 2500) // hack jQuery Object reference to DOM element
setTimeout(() => x.html('3'), 3000) // actually writes in both #x and #y

И понял, что я не пишу var x = $('#x') не потому, что это обернутый объект, а именно потому, что он не является обернутым объектом.

Я думал, что точкой входа API было $, но я вижу API как var api = $(), а точка входа as (el) => api.push(el) или (sel) => api.push(document.querySelector(sel))

Я могу $().push но я не могу $().forEach ни сдвига, ни сдвига, но да удалить индекс, также

В примере

setTimeout(() => { x.map((item) => {console.log(item)}) }, 3500)

log 0 и 1, а не элементы. Протестировано с использованием jQuery версии 3.3.1