我正在尝试编写自己的自定义纯JavaScript插件
这是我的示例插件代码:
(function() {
var pMethods = {
append: function(text) {
var node = this.node;
node.innerHTML += text;
},
click: function(fn) {
if (this.node instanceof Array) {
this.node.forEach(function(e) {
e.addEventListener('click', function() {
fn();
});
}, this);
} else {
this.node.addEventListener('click', function(e) {
fn(e);
});
}
}
};
myPlugin = function(selector) {
this.node = document.querySelectorAll(selector);
if (this.node.length === 1) {
this.node = this.node[0];
}
return this.node;
};
myPlugin.prototype = pMethods;
this.r = function(selector) {
return new myPlugin(selector);
};
}());
只有两个函数追加并单击
这是我的HTML
<div class="close"></div>
现在我尝试在close div上添加click事件,如下所示:
r('.close').click(function() {
alert('Hi')
});
但它没有按预期工作我不知道我在这里失踪
答案 0 :(得分:1)
您的代码无效,因为您明确检查了元素集合是否为Array
。返回的任何元素集合都是NodeList
,它是一个类似于object的数组,但不是数组。
if (this.node instanceof Array)
应该是
if (this.node instanceof NodeList)
或者您可以使用Array.prototype.slice
将NodeList
转换为Array
this.node = Array.prototype.slice.call(
document.querySelectorAll(selector)
)
以下是一些优化措施。
(function() {
var pMethods = {
append: function(text) {
// iterate over the collection
this.nodes.forEach(function(node) {
node.innerHTML += text;
})
// return this for chaining
return this
},
click: function(fn) {
// iterate over the collection
this.nodes.forEach(function(e) {
e.addEventListener('click', fn);
});
// return this for chaining
return this
},
find: function(selector) {
return new myPlugin(
// flat map over each of the nodes in the collection
this.nodes.reduce(function(nodes, node) {
return [].concat.apply(nodes, node.querySelectorAll(selector))
}, [])
)
}
};
myPlugin = function(nodes) {
// changed constructor to recievea array of elemnets only
// it's private so won't affect anything else
this.nodes = nodes
};
myPlugin.prototype = pMethods;
this.r = function(selector) {
var nodes = null
// handle creating the object with normal elements
if (selector instanceof HTMLElement) {
nodes = [selector]
}
else {
nodes = [].slice.call(
document.querySelectorAll(selector)
);
}
return new myPlugin(nodes);
};
}());
r('.close')
.click(function(e) {
console.log('alerts suck! ' + e.target.textContent)
r(e.target).find('.child').append(' appended child!')
})
.append(' append works!')
<div class="close">
close
<div class="child">this is the child</div>
</div>
答案 1 :(得分:0)
您的构造函数(例如myPlugin = function(selector) {
)应该返回this
而不是this.node