Javascript:链接jQuery等元素

Javascript:链接jQuery等元素,javascript,method-chaining,Javascript,Method Chaining,我试图在一定程度上复制jQuery的元素操作。现在我发现非常有用的是.first()选择器。我希望能够像这样链接功能 getElement(选择器).first().hasClass(类名) 现在,关于我取得的进展有两个问题(请注意,我的代码示例被最小化了,所以请不要对错误处理发表评论。) 我目前的问题 如果我调用我的函数 var$test=getElement('.something'); //结果:带有.something divs的节点列表 如果我调用结果中的第一个元素 $test.fir

我试图在一定程度上复制jQuery的元素操作。现在我发现非常有用的是
.first()
选择器。我希望能够像这样链接功能
getElement(选择器).first().hasClass(类名)

现在,关于我取得的进展有两个问题(请注意,我的代码示例被最小化了,所以请不要对错误处理发表评论。)

我目前的问题 如果我调用我的函数

var$test=getElement('.something');
//结果:带有.something divs的节点列表

如果我调用结果中的第一个元素

$test.first();
//结果:第一组,完美

但是,现在如果我再次调用
$test
,它将用
first()
的结果替换
elements
属性,这意味着我“丢失”了旧值。我不想丢失它们,我只想要用于特定功能的
first()
函数。然后我希望
$test
再次返回所有元素。 另外,调用
first()
现在将结束
未定义的
,因为
中只剩下1个元素,因为它已从对象中删除了旧元素

又一次尝试 现在,我还试图通过返回第一个子对象而不是整个类对象来扭转这种局面

this.first = function() {
  return this.element[0];
};
不过,我会的
$test.first().hasClass(类名);
//返回错误,方法hasClass未定义

这是因为
.hasClass
存在于原始
this
上,由于我现在返回元素,因此不再返回该元素

this.first = function() {
    return new getElement(this.element[0]);
};
我试图从jQuery的库中获取一些东西,尽管这让我更加困惑

我在谷歌上搜索过这个主题,但我找到的所有“链接方法”解决方案似乎都覆盖了对象的原始值,这不是我想要的。另一个解决方案实际上需要我一次又一次地重新启动对象,这对我来说似乎不是很有效。。。感谢您的帮助。我想我是完全错了


--如果你能帮助我,请解释一下为什么你的解决方案有效。我真的觉得如果我理解了这一点,我对javascript的理解可以进一步扩展。我只需要解决这个结构(?)问题。

您可以更新
getElement
,这样在发送元素时它会再次返回

var getElement=函数(选择器,父级){
var ret=null
如果(选择器的类型==“字符串”){
ret=document.queryselectoral(选择器);
}否则{
ret=选择器
}
this.element=ret;
this.hasClass=函数(类名){
className.replace('.','');
if(this.multiple()){
log('不能在多个元素上使用hasClass函数');
返回false;
}
};
this.first=函数(){
this.element=getElement(this.element[0]);
归还这个;
};
归还这个;
};
var测试=getElement(“.foo”);
console.log(test.first())
console.log(test.first().hasClass)
1
2.
3.

4
您可以使用
.queryselectoral()
、扩展元素和
数组.prototype.find()
,它返回数组中的第一个匹配项或
未定义的

const getElement=(选择器=”,{prop=”,值=”,first=false}={})=>{
const el=[…document.queryselectoral(选择器)];
if(first)返回el.find(({[prop]:match})=>match&&match==value)
否则返回el;
};
让first=getElement(“span”,{prop:“className”,value:“abc”,first:true});
console.log(第一);
let last=getElement(“span”);
控制台日志(全部)
123

456
外部函数中的此
指的是窗口/全局对象

相反,返回
ret
变量本身

在内部函数(成为对象的方法)中,
这个
按照您期望的方式运行

这里有一个替代解决方案,它允许链接,即使在您调用
first
方法之后:

var getElement=函数(选择器,父级){
var ret=typeof selector==“string”?document.queryselectoral(选择器)
:选择器;
ret.hasClass=函数(类名){
如果(!this.classList){
log('不能在多个元素上使用hasClass函数');
返回false;
}否则{
返回此.classList.contains(className);
}
};
ret.first=函数(){
返回新的getElement(此[0]);
};
返回ret;
};
log(getElement('p').length)//2.
log(getElement('p').first().innerHTML)//abc
log(getElement('p').first().hasClass('test')//真的
log(getElement('p').first().hasClass('nope')//法斯
log(getElement('p').hasClass('test'))//false(多个元素)

abc

def

first()
这样的方法不应该修改
这个
,它应该创建一个新对象并返回它。您只能使用
返回此信息

this.first = function() {
    return new getElement(this.element[0]);
};
请注意,您必须使用
newgetelement
来创建对象,而不仅仅是
getElement

这还需要更改构造函数,以便它可以接受选择器字符串或元素:

var getElement = function(selector, parent) {
    var ret = typeof selector == "string" ? document.querySelectorAll(selector) : [selector];
    ...
}

你也应该考虑用适当的面向对象方法来做这件事,把方法放在一个原型中,而不是在每个对象中定义它们。

var getElement = function(selector, parent) {
  var ret = typeof selector == "string" ? document.querySelectorAll(selector) : [selector];
  this.element = ret;
};

getElement.prototype.hasClass = function(className) {
  className.replace('.', '');
  if (this.multiple()) {
    console.log('Cannot use hasClass function on multiple elements');
    return false;
  }
};

getElement.prototype.first = function() {
  return new getElement(this.element[0])
};

我认为最简单的方法是返回一个包含所选节点的新类。这将是最简单的解决方案,因为您实际上不想改变任何以前的选择器

我举了一个小例子,使用一些ES6使一些事情更容易处理