我正在创建一个迷你库,试图重建(至少部分地)jQuery
的工作方式,以用于学习目的并更好地理解面向对象编程的工作原理。
我重新创建了 jQuery
方法 click
和 addClass
,但是当我像这样调用它们时:
$(".class1").click(function() {
$(".class1").addClass("class2"); // Works, but it adds class2 to all elements
this.addClass("class2"); // Doesn't work
});
我收到一个未捕获错误
,表示this.addClass
不是一个函数,这是正常的,因为我不应该能够访问另一个对象的方法。
jQuery 中的 $(this)
是如何表示触发事件的 DOM 元素的,因此在我的例子中我可以使用它来添加 class2
仅适用于单击的元素,而不是所有具有类 class1
的元素?
P.S:我尝试阅读 jQuery 文件,但我觉得这些水目前对我来说太深了。
<小时/>编辑:
我一直很感激在 Stack Overflow 上获得的所有答案和帮助,但告诉我使用
$(this)
而不是this
并不适用解决我的问题,因为我的代码中不存在$(this)
。我正在尝试学习如何创建类似 jQuery 的$(this)
及其背后的逻辑。click
方法定义如下:
$.prototype.click = function(callback) {
for (var i = 0; i < this.length; i++) {
this[i].onclick = function(event) {
callback.call(this, event);
}
}
};
最佳答案
有了额外 1.5 年的经验,这个问题就变得相当简单了。
- 更改
$
,以便除了字符串选择器之外,它可以接受HTML
元素。 - 创建包含给定
HTML
元素的对象的新实例。 - 调用
addClass
并将其作为上下文。
代码:
;(function() {
/* The object constructor. */
function ElementList(arg) {
/* Cache the context. */
var that = this;
/* Save the length of the object. */
this.length = 0;
/* Check whether the argument is a string. */
if (typeof arg == "string") {
/* Fetch the elements matching the selector and inject them in 'this'. */
[].forEach.call(document.querySelectorAll(arg), function(element, index) {
that[index] = element;
that.length++;
});
}
/* Check whether the argument is an HTML element and inject it into 'this'. */
else if (arg instanceof Element) {
this[0] = arg;
this.length = 1;
}
}
/* The 'click' method of the prototype. */
ElementList.prototype.click = function(callback) {
/* Iterate over every element and set the 'click' event. */
[].forEach.call(this, function(element) {
element.addEventListener("click", function(event) {
callback.call(this, event);
});
});
}
/* The 'addClass' method of the prototype. */
ElementList.prototype.addClass = function(className) {
/* Iterate over every element. */
[].forEach.call(this, function(element) {
/* Cache the classList of the element. */
var list = element.classList;
/* Add the specified className, if it doesn't already exist. */
if (!list.contains(className)) list.add(className);
});
}
/* The global callable. */
window.$ = function(arg) {
return new ElementList(arg);
}
})();
/* Example */
$("#b1").click(function() {
$(this).addClass("clicked");
console.log(this);
});
<button id="b1">Click</button>
关于javascript - 如何复制 jQuery 的 $(this)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38276530/