为了账号安全,请及时绑定邮箱和手机立即绑定

在 Plain Vanilla Javascript 中创建 .hide()

在 Plain Vanilla Javascript 中创建 .hide()

阿波罗的战车 2023-12-14 16:26:15
完全避免使用 jQuery,我今天开始尝试让自己变得像这样:$('#myDiv').hide();目标是它将适用.style.display = 'none'于#myDiv.因此,我们了解到以下内容是一个与 jQuery 稍微相似的选择器:var $ = s => document.querySelectorAll.bind(document)(s).length > 1 ?   document.querySelectorAll.bind(document)(s) : document.querySelector.bind(document)(s);使用它时要小心,因为它可以返回多个元素,您可能需要使用其中的.forEach(function(el,i){el.doSomething();});语法。所以,我尝试创建一个简单的$(...).hide()函数,如下所示:$.__proto__.hide = function(){this.forEach(function(el,i){el.style.display='none';});};不幸的是,__proto__现在已被弃用,即使您忽略这一点,除非您执行以下操作,否则上述内容也不会起作用:$('#myDIV').__proto__.hide = function(){this.forEach(function(el,i){el.style.display='none';});};使用普通 Javascript 通过函数扩展我的$对象的技术是什么?.hide()
查看完整描述

2 回答

?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

这里的主要问题是您直接返回querySelectororquerySelectorAll结果。您可以将其包装在您自己的类中,您可以使用方法轻松扩展该类。


class ElementsHelper {

  constructor(elements) {

    this.elements = elements;

  }


  // helper to simplify iterating `this.elements` and returning `this`

  forEach(fn) {

    this.elements.forEach(fn);

    return this;

  }


  hide() {

    return this.forEach(element => element.style.display = "none");

  }


  click(fn) {

    return this.forEach(element => element.addEventListener("click", fn));

  }


}


function $(selector) {

  return new ElementsHelper(document.querySelectorAll(selector));

}

通过上述操作,您现在可以执行以下操作:


$('#myDiv').hide();


查看完整回答
反对 回复 2023-12-14
?
MM们

TA贡献1886条经验 获得超2个赞

你基本上有两个选择:

  1. 像 jQuery 一样使用你自己的对象,或者

  2. 扩展内置原型。

  3. 返回每个单独的结果对象时对其进行扩展

我可能会使用方法#1,也许是扩展Array(或通过组合使用数组)。

你似乎更喜欢方法#2。通常不建议这样做,因为一旦开始组合来自多个位置的脚本,就会遇到潜在的冲突。但在应用程序(而不是库)内,这不一定不合理。

在您的情况下,如果您的$函数返回 的结果querySelectorAll,它将返回 a NodeList,并且您可以扩展NodeList.prototype。每当扩展原型时,始终使用Object.defineProperty(或类似的)来定义不可枚举的属性。例如:

Object.defineProperty(NodeList.prototype, "hide", {

    value() {

        this.forEach(/*...*/);

        return this;

    },

    writable: true,

    configurable: true

});

实例:

Object.defineProperty(NodeList.prototype, "hide", {

    value() {

        // This isn't a great "hide", it's just for

        // the purposes of showing the plumbing

        this.forEach(el => el.style.display = "none");

        return this;

    },

    writable: true,

    configurable: true

});


const $ = selector => document.querySelectorAll(selector);


setTimeout(() => {

    $(".a").hide();

    console.log("Hid .a elements");

}, 800);

<div class="a">a</div>

<div class="b">b</div>

<div class="c">c</div>

不幸的是,__proto__现在已被弃用

这是真的,但Object.getPrototypeOf不是,只是__proto__访问器属性(它只是为了向后兼容而添加到规范中)。


查看完整回答
反对 回复 2023-12-14
  • 2 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信