2016-01-22 81 views
3

我有问题让选择器被缓存,所以,基本上我没有使用JQUERY框架。我创建了自己的模仿JQUERY模式的框架。Javascript缓存选择器功能

这是我的代码:

"use strict" 

var $, i; 

(function() { 

    $ = function(el) { 
     return new obj$(el); 
    }; 

    var obj$ = function(el) { 
     var cl = document.getElementsByClassName(el), 
      loop = cl.length; 

     this.length = loop; 

     for (i = 0; i < loop; i++) { 
      this[i] = cl[i]; 
     } 

    }; 

    obj$.prototype = { 

     find : function(el) { 

      if (this.length == 1) { 
       this[0] = this[0].getElementsByClassName(el)[0]; // this is the problem, it's reset everything 
       return this; 
      } 

     }, 
     css : function(obj, data) { 

      if (this.length == 1) { 
       this[0].style[obj] = data; 
       return this; 
      } 

     }, 
     cache : function() { 

      if (this[0].hasOwnProperty("find")) { 
       return this[0]; // reset the selector from $() that has been hook by find function 
      } 
      else { 
       return this[0].find(); // do nothing if $() has not been hook by find function 
      } 

     } 

    }; 


})(); 

var parent = $("parent"), // i want this selector being cache 
    child = parent.find("child"); // but, when i hook this "find" function it's reset parent selector 

child.css("color", "orange"); 
parent.css("color", "purple"); 

<div class="parent">parent 
    <div class="child">child</div> 
</div> 

的jsfiddle:https://jsfiddle.net/k6j70f1h/

输出是:孩子与紫色,但是,为什么不父也成为紫色的?我知道在我的find函数中,我使用这个[0] = this [0] .getElementsByClassName(el)[0];

所以,它重置$()对象选择器。

如何防止此问题发生? 我只是看着hasOwnProperty方法。是否有可能创建另一个函数来检查hasOwnProperty?

我希望$()对象保持它的选择器甚至与查找函数链接?

任何建议家伙?谢谢..

+0

而不是创建自己的framwork一个行为有点像jQuery的,为什么不使用jQuery? (如果你想要一个更小的变体,[zepto.js](http://zeptojs.com/))? – Tomalak

+0

感谢Tomalak的评论,我会采取您的意见。但是,在不知道自己的成就如何不是我的风格的情况下做事。 –

+0

我不知道这意味着什么。如果它的意思是“我想自己写所有的图书馆”,那么我只能说这不是一个非常聪明的位置。 – Tomalak

回答

0

find方法应返回$对象的新实例,而不是修改现有的结果。你的实现也应该像jQuery一样接受第二个参数,它是执行搜索的上下文(默认为document)。

所以你可以find这样实现:

find : function(el){ 
    return $(el, this[0]); 
} 

updated fiddle demo

var $, i; 

(function() { 

$ = function(el, context) { 
     context = context || document; 
     return new obj$(el, context); 
}; 

var obj$ = function(el, context) { 
    var cl = context.getElementsByClassName(el), 
     loop = cl.length; 

    this.length = loop; 

    for (i = 0; i < loop; i++) { 
     this[i] = cl[i]; 
    } 
}; 

obj$.prototype = { 

    find : function(el) { 

     if (this.length == 1) { 
      return $(el, this[0]); 
     } 

    }, 
    css : function(obj, data) { 
     if (this.length == 1) { 
      this[0].style[obj] = data; 
      return this; 
     } 
    } 
}; 
})(); 
+0

感谢pawel回答,我尝试你的方法。有效。但不是如果我把多个父元素?检查了这一点:https://jsfiddle.net/k6j70f1h/2/请帮助 –

+0

这是你的'css'方法的逻辑,它检查'if(this.length == 1)' - 所以你的实现只会在if只有一个元素被找到,因为你明确地添加了这个条件。但是我们不是在这里重新实现整个jQuery,而是为了解决与您的代码有关的具体问题;) – pawel

+0

为了使它与整个集合一起工作,您需要遍历元素:https://jsfiddle.net/k6j70f1h/3/ – pawel