querySelector 和 querySelectorAll 别名
querySelector and querySelectorAll alias
为 querySelector
和 querySelectorAll
为 document
和 Element
创建跨浏览器别名的最佳替代方法是什么
最直接的方法可能是
window.$ = function(selector){return document.querySelector(selector)}
window.$$ = function(selector){return document.querySelectorAll(selector)}
当然这不允许链接,因为函数 return 总是引用 document
$('.parent-class').$$('.child-classes')
到目前为止我最好的选择是
window.$ = document.querySelector.bind(document);
window.$$ = document.querySelectorAll.bind(document);
Element.prototype.$ = Element.prototype.querySelector;
Element.prototype.$$ = Element.prototype.querySelectorAll;
这样我们就可以做之前失败的选择器,虽然我不确定这可能带来的不良影响,有没有人有hint/explanation可以提供?
有谁有好的、不显眼的替代品吗?
最好的不显眼的替代方法是不做这样的别名。这是另一回事要记住,对于查看你的代码来学习的人来说是另一回事,它可能会破坏你的 IDE 的自动完成和语法检查功能,并且它会污染原型。
但是,如果您仍然想沿着这条路继续前进,将需要特殊的机器来链接 $$
和 Element.$$
中的任何内容,因为它们 return 节点列表。首先,我们将 $$
return 设为一个数组:
window.$$ = function(sel) {
return Array.prototype.slice.call(document.querySelector(sel));
}
Element.$$
也是如此。现在我们可以扩充 Array
原型:
Array.prototype.$ = function(sel) {
var result = [];
for (var i = 0; i < this.length; i++) {
var sub = this[i].querySelector(sel);
if (sub) result.push(sub);
}
return result;
};
继续使用 map
and/or filter
等重写这个,如果它适合你的喜好。
现在你可以做:
$$('.class1').$('span')
类似地,您可以在 Array
上定义一个版本的 $$
,如下所示:
Array.prototype.$$ = function(sel) {
var result = [];
for (var i = 0; i < this.length; i++) {
var elts = this[i].querySelectorAll(sel);
for (var j = 0; j < elts.length; j++) {
result.push(elts[j]);
}
}
return result;
;
这将对输入节点列表的每个成员进行 querySelectorAll
调用所产生的所有节点列表合并到一个数组中。
如果您想链接 setAttribute
之类的东西,您需要为 Element
和 Array
定义版本:
Element.prototype.setAttributeChainable = function() {
this.setAttribute.apply(this, arguments);
return this;
}
Array.prototype.setAttributeChainable = function() {
for (var i = 0; i < this.length; i++) {
this[i].setAttribute.apply(this[i], arguments);
}
return this;
}
要在 $
什么也没找到时静静地失败,在这种情况下将它安排到 return 一个空数组:
window.$ = function(sel) {
return document.querySelector(sel) || [];
};
Element.$
.
也一样
现在你可以做
$$('.class1') .
$$('span') .
setAttributeChainable('style', 'color:blue') .
$('a') .
setAttributeChainable('href', 'google.com');
现在继续此练习,使用任何其他您想要链接的 API and/or 适用于节点列表。
如果您对添加到 Array
原型有宗教异议,您将不得不寻找其他方法。
我也使用 bind
方法创建别名。
var $ = document.querySelector.bind(document);
var $$ = document.querySelectorAll.bind(document);
对于第一个元素,我使用了一个函数和 apply
,这样它的行为就如同您以 "VanillaJS" 方式调用它一样。
Element.prototype.$ = function() {
return this.querySelector.apply(this, arguments);
};
Element.prototype.$$ = function() {
return this.querySelectorAll.apply(this, arguments);
};
这是一个例子:
var $ = document.querySelector.bind(document);
var $$ = document.querySelectorAll.bind(document);
Element.prototype.$ = function() {
return this.querySelector.apply(this, arguments);
};
Element.prototype.$$ = function() {
return this.querySelectorAll.apply(this, arguments);
};
alert($('.foo').innerHTML);
alert('There are ' + $$('.foo').length + ' `.foo` nodes');
var parent = $('.parent');
alert(parent.$('.child').innerText);
alert('There are ' + parent.$$('.child').length + ' children');
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class=foo>It works!</div>
<div class=foo>It worked again!</div>
<div class=parent>Parent
<div class=child>Child</div>
<div class=child>Another Child</div>
</div>
</body>
</html>
如果您想要链接,则必须创建更精细的东西。您可能想查看 Bliss 支持链接但更像 VanillaJS 的轻量级 (~3kb) 库而不是 jQuery。
unobtrusive alternative
制作一个包装器,这样您就不会扩展 other/native 结构,将其命名为不太可能冲突的东西
var Σ = (function () {
function Found(nodes) {
this.nodes = nodes;
}
function find(selector) {
var nodes;
if (this instanceof Found) {
nodes = Array.prototype.map.call(this.nodes, e => Array.prototype.slice.call(e.querySelectorAll(selector)));
nodes = Array.prototype.concat.apply([], nodes);
return new Found(nodes);
}
if (this === window)
return new Found(Array.prototype.slice.call(document.querySelectorAll(selector)));
return new Found(Array.prototype.slice.call(this.querySelectorAll(selector)));
}
Found.prototype.find = find;
return find;
}());
所以你可以做类似的事情
Σ('.answer').find('pre').nodes;
要在此处获取答案中的所有 <pre>
节点(即代码位)。您可以根据需要链接 .find
。
cross browser
jQuery有什么问题?
为 querySelector
和 querySelectorAll
为 document
和 Element
最直接的方法可能是
window.$ = function(selector){return document.querySelector(selector)}
window.$$ = function(selector){return document.querySelectorAll(selector)}
当然这不允许链接,因为函数 return 总是引用 document
$('.parent-class').$$('.child-classes')
到目前为止我最好的选择是
window.$ = document.querySelector.bind(document);
window.$$ = document.querySelectorAll.bind(document);
Element.prototype.$ = Element.prototype.querySelector;
Element.prototype.$$ = Element.prototype.querySelectorAll;
这样我们就可以做之前失败的选择器,虽然我不确定这可能带来的不良影响,有没有人有hint/explanation可以提供?
有谁有好的、不显眼的替代品吗?
最好的不显眼的替代方法是不做这样的别名。这是另一回事要记住,对于查看你的代码来学习的人来说是另一回事,它可能会破坏你的 IDE 的自动完成和语法检查功能,并且它会污染原型。
但是,如果您仍然想沿着这条路继续前进,将需要特殊的机器来链接 $$
和 Element.$$
中的任何内容,因为它们 return 节点列表。首先,我们将 $$
return 设为一个数组:
window.$$ = function(sel) {
return Array.prototype.slice.call(document.querySelector(sel));
}
Element.$$
也是如此。现在我们可以扩充 Array
原型:
Array.prototype.$ = function(sel) {
var result = [];
for (var i = 0; i < this.length; i++) {
var sub = this[i].querySelector(sel);
if (sub) result.push(sub);
}
return result;
};
继续使用 map
and/or filter
等重写这个,如果它适合你的喜好。
现在你可以做:
$$('.class1').$('span')
类似地,您可以在 Array
上定义一个版本的 $$
,如下所示:
Array.prototype.$$ = function(sel) {
var result = [];
for (var i = 0; i < this.length; i++) {
var elts = this[i].querySelectorAll(sel);
for (var j = 0; j < elts.length; j++) {
result.push(elts[j]);
}
}
return result;
;
这将对输入节点列表的每个成员进行 querySelectorAll
调用所产生的所有节点列表合并到一个数组中。
如果您想链接 setAttribute
之类的东西,您需要为 Element
和 Array
定义版本:
Element.prototype.setAttributeChainable = function() {
this.setAttribute.apply(this, arguments);
return this;
}
Array.prototype.setAttributeChainable = function() {
for (var i = 0; i < this.length; i++) {
this[i].setAttribute.apply(this[i], arguments);
}
return this;
}
要在 $
什么也没找到时静静地失败,在这种情况下将它安排到 return 一个空数组:
window.$ = function(sel) {
return document.querySelector(sel) || [];
};
Element.$
.
现在你可以做
$$('.class1') .
$$('span') .
setAttributeChainable('style', 'color:blue') .
$('a') .
setAttributeChainable('href', 'google.com');
现在继续此练习,使用任何其他您想要链接的 API and/or 适用于节点列表。
如果您对添加到 Array
原型有宗教异议,您将不得不寻找其他方法。
我也使用 bind
方法创建别名。
var $ = document.querySelector.bind(document);
var $$ = document.querySelectorAll.bind(document);
对于第一个元素,我使用了一个函数和 apply
,这样它的行为就如同您以 "VanillaJS" 方式调用它一样。
Element.prototype.$ = function() {
return this.querySelector.apply(this, arguments);
};
Element.prototype.$$ = function() {
return this.querySelectorAll.apply(this, arguments);
};
这是一个例子:
var $ = document.querySelector.bind(document);
var $$ = document.querySelectorAll.bind(document);
Element.prototype.$ = function() {
return this.querySelector.apply(this, arguments);
};
Element.prototype.$$ = function() {
return this.querySelectorAll.apply(this, arguments);
};
alert($('.foo').innerHTML);
alert('There are ' + $$('.foo').length + ' `.foo` nodes');
var parent = $('.parent');
alert(parent.$('.child').innerText);
alert('There are ' + parent.$$('.child').length + ' children');
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class=foo>It works!</div>
<div class=foo>It worked again!</div>
<div class=parent>Parent
<div class=child>Child</div>
<div class=child>Another Child</div>
</div>
</body>
</html>
如果您想要链接,则必须创建更精细的东西。您可能想查看 Bliss 支持链接但更像 VanillaJS 的轻量级 (~3kb) 库而不是 jQuery。
unobtrusive alternative
制作一个包装器,这样您就不会扩展 other/native 结构,将其命名为不太可能冲突的东西
var Σ = (function () {
function Found(nodes) {
this.nodes = nodes;
}
function find(selector) {
var nodes;
if (this instanceof Found) {
nodes = Array.prototype.map.call(this.nodes, e => Array.prototype.slice.call(e.querySelectorAll(selector)));
nodes = Array.prototype.concat.apply([], nodes);
return new Found(nodes);
}
if (this === window)
return new Found(Array.prototype.slice.call(document.querySelectorAll(selector)));
return new Found(Array.prototype.slice.call(this.querySelectorAll(selector)));
}
Found.prototype.find = find;
return find;
}());
所以你可以做类似的事情
Σ('.answer').find('pre').nodes;
要在此处获取答案中的所有 <pre>
节点(即代码位)。您可以根据需要链接 .find
。
cross browser
jQuery有什么问题?