【问题标题】:Trying to make a jQuery like with multiple selectors尝试使用多个选择器制作 jQuery
【发布时间】:2017-06-22 18:12:03
【问题描述】:

我尝试制作一个非常精简的“类似 jQuery”的选择器,但我无法让它适用于所有类,我尝试使用 for 循环,但由于“return new”它会中断循环。

JS

var $ = function(el){       
  var helpers = {
    css: function(v){
      (this.value).setAttribute('style',v);     
    },
    replace: function(v){
      (this.value).innerHTML = v;
      console.log(this.value);
    },
    append: function(v){
      (this.value).innerHTML =  (this.value).outerHTML + ' ' + v;
    }
  };
  function sel(el){ 
    this.value = document.querySelector(el);
  }
  sel.prototype = helpers;
  return new sel(el);
};

var sel1 = $('.sel1');

sel1.replace('<span>replaced</span>');
sel1.css("color:red");

HTML

<div class="sel1">test</div>
<div class="sel1">test</div>
<div class="sel1">test</div>

【问题讨论】:

  • 不知道你为什么要费心使用一个类,但如果你这样做,请用首字母大写来命名它。
  • 但是sel 被用作构造函数
  • 有多个问题——你使用了css()错误,你覆盖了jQuery而不是扩展它,但你为什么还要尝试扩展它呢?为什么不直接使用$('.sel1').css("color", "red");
  • @AluanHaddad—嗯,格式让我错过了 new,已修复。虽然找不到 for 循环...
  • 要选择多个匹配项,请使用querySelectorAll。这意味着this.value 将是类似数组的,您需要将其作为类似数组的对象来处理。此外,您的append 函数正在使用outerHTML,它应该(大概)使用innerHTML

标签: javascript helpers


【解决方案1】:

jQuery 的强大功能之一是可以链接命令,这实际上是通过保存对初始选择器查询的引用来完成的。为了得到基本的想法,一个简单的启动实现可能如下所示:

$$$ = function(selector) {
  var Handler = function(selector) {
    var elements = document.querySelectorAll(selector);
    this.css = function(options) {
      for (var i=0; i<elements.length; i++) {
        for (var property in options) {
          elements.item(i).style[property] = options[property];
        }
      }
      return this;
    };
    this.hide = function() {
      return this.css({display: 'none'});
    };
    this.show = function() {
      return this.css({display: ''});
    };
    this.replace = function(html) {
      for (var i=0; i<elements.length; i++) {
        elements.item(i).innerHTML = html;
      };
      return this;
    };
  };
  return new Handler(selector);
};

上面代码的一个简单的工作示例如下所示:

$$$('div').css({border: '1px solid red', background: 'green'}).hide().show();

由于所有内部函数都返回当前实例 (return $this),因此启用了对不同操作的链接调用。

【讨论】:

【解决方案2】:

您想使用Document.querySelectorAll() 来获取所有匹配项,而不仅仅是第一个匹配项。这就是 jQuery 所做的。

显然,这意味着“值”不是节点,而是NodeList(或null)。这会改变函数,因为它们都必须处理一个列表,所以你必须有某种形式的 foreach() 才能将你的函数应用于每个节点(这也是 jQuery 所做的,请参阅 get() 函数作为一个很好的证明这一点。)

最后,如果没有匹配项,jQuery 会得到一个 null 并且函数仍然可以工作。这是因为每个函数都使用foreach() 函数,而在null 上,foreach() 什么也不做。所以你必须实现foreach()。也许是这样的:

function foreach(list, func)
{
   var max, i, n;

   if(list) // make sure list is not 'null'
   {
       max = list.length;
       for(i = 0; i < max; ++i) // go through the elements
       {
           n = list[i];
           func(n);   // call user function
       }
   }
}

那么css 函数会变成这样:

css: function(v)
{
  foreach(this.value, function(n) { n.setAttribute('style', v); });
}

注意:如果你将foreach()作为助手的一部分,请确保使用this.foreach()来调用它。

【讨论】:

  • 好答案。请考虑修改您的代码样式,将左大括号与需要它们的构造放在同一行。这是 JavaScript 中的标准,不这样做会导致问题,例如返回对象字面量时会失败。
  • @AluanHaddad,我的项目有 45,000 行 JavaScript,我对放置它们的 { 很好...我不太确定为什么你的东西会失败,JavaScript 不是完全与行无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 2015-07-01
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 2011-07-14
相关资源
最近更新 更多