为 document.querySelectorAll 制作一个短别名

IT技术 javascript native-methods
2021-02-24 14:27:10

我将大量运行 document.querySelectorAll() ,并且想要一个速记别名。

var queryAll = document.querySelectorAll

queryAll('body')
TypeError: Illegal invocation

不起作用。然而:

document.querySelectorAll('body')

仍然如此。我怎样才能使别名工作?

6个回答

这似乎有效:

const queryAll = document.querySelectorAll.bind(document);

bind返回一个与函数相同的新函数querySelectorAll,其中方法this内部的querySelectorAll绑定到document对象。

绑定功能仅在 IE9+(和所有其他浏览器)中受支持 - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind


更新:事实上,您可以创建一系列文档方法的快捷方式,如下所示:

const query = document.querySelector.bind(document);
const queryAll = document.querySelectorAll.bind(document);
const fromId = document.getElementById.bind(document);
const fromClass = document.getElementsByClassName.bind(document);
const fromTag = document.getElementsByTagName.bind(document);
我发现这特别有用:const $ = document.querySelector.bind(document); const $$ = document.querySelectorAll.bind(document);.
2021-04-24 14:27:10
forgetElementById不是必需的,因为别名已经存在并且它是 id 本身(例如myid.innerHTML,等于document.getElementById('myid').innerHTML
2021-05-07 14:27:10
是否有一个 ES6 module可以做到这一点并将您的元素作为基础?
2021-05-08 14:27:10
请注意,虽然bindIE9 支持,但const仅 IE11 支持,并不完全支持。参见tc39.es/ecma262/#sec-let-and-const-declarations谢天谢地,没有人在乎了。
2021-05-14 14:27:10
绑定函数 queryAll 在 ES6 中被称为奇异函数对象(ECMAScript 6 中的术语)。该链接有一些很好的例子......应该说有一群人通过The Good Parts 并强烈建议不要在你自己的代码中做“这个”杂耍,它很快就会变得混乱。
2021-05-20 14:27:10

一个常见的答案是使用$and $$for querySelectorand querySelectorAll这个别名模仿了 jQuery 的别名。

例子:

$ = document.querySelector.bind(document)
$$ = document.querySelectorAll.bind(document)

$('div').style.color = 'blue'
$$('div').forEach(div => div.style.background = 'orange')
div {
  margin: 2px;
}
<div>
  test
</div>
<section>
  <div>
    hello
  </div>
  <div>
    foo
  </div>
</section>

JavaScript 解释器抛出错误,因为querySelectorAll()应该在文档上下文中调用。

当您尝试调用console.log()aliased时,会抛出相同的错误

所以你需要像这样包装它:

 function x(selector) {
     return document.querySelectorAll(selector);
 }
一些库和绑定示例有问题:文档上下文冲突,而这似乎总是有效......
2021-05-15 14:27:10

我的解决方案涵盖以下四个用例:

  • document.querySelector(...)
  • document.querySelectorAll(...)
  • element.querySelector(...)
  • element.querySelectorAll(...)

代码:

let doc=document,
    qsa=(s,o=doc)=>o.querySelectorAll(s),
    qs=(s,o=doc)=>o.querySelector(s);

在参数方面,选择器s是必须的,而容器元素对象o是可选的。

用法:

  • qs("div"): 查询整个文档的第一个div,返回那个元素
  • qsa("div"): 查询所有 div 的整个文档,返回所有这些元素的 nodeList
  • qs("div", myContainer): 仅在 myContainer 元素内查询第一个 div,返回该元素
  • qsa("div", myContainer): 只在 myContainer 元素内查询所有 div,返回所有这些元素的 nodeList

为了使代码更短(但效率不高),qs可以将代码编写如下:

let qs=(s,o=doc)=>qsa(s,o)[0];

上面的代码使用 ES6 特性(let、箭头函数和默认参数值)。ES5 等效项是:

var doc=document,
    qsa=function(s,o){return(o||doc).querySelectorAll(s);},
    qs=function(s,o){return(o||doc).querySelector(s);};

或等效的更短但效率较低的 ES5 版本qs

var qs=function(s,o){return qsa(s,o)[0];};

下面是一个工作演示。为了确保它适用于所有浏览器,它使用 ES5 版本,但如果你打算使用这个想法,请记住 ES6 版本更短:

谢谢,您使用let代替 有const什么具体原因吗?并且您可以使用$qsaand $qs,因此 DOM 元素仍然可以使用前缀$- 但这只是一个想法。
2021-05-05 14:27:10

这会起作用,您需要使用call()apply()使用适当的上下文来调用别名

func.call(context, arg1, arg2, ...) 
func.apply(context, [args]) 

var x = document.querySelectorAll;
x.call(document, 'body');
x.apply(document, ['body']);
+1 - 有趣的方法,因为真正的问题x('body')是它缺少this上下文。
2021-05-16 14:27:10