如何 return 包装器对象而不是 HTML 元素?

How to return a wrapper Object instead of HTML element?

我正在编写一个微型库,而不是使用 jQuery。我只需要 3-4 个方法(用于 DOM 遍历、添加事件监听器等)。所以我决定自己写它们而不是用 jQuery.

来膨胀网站

这是代码片段:

lib.js


window.twentyFourJS = (function() {

    let elements;

    const Constructor = function(selector) {
        elements = document.querySelectorAll(selector);
        this.elements = elements;
    };

    Constructor.prototype.addClass = function(className) {
        elements.forEach( item => item.classList.add(className));
        return this;
    };

    Constructor.prototype.on = function(event, callback, useCapture = false){
        elements.forEach((element) => {
            element.addEventListener(event, callback, useCapture);
        });
        return this;
    }

  const initFunction = function(selector){
        return new Constructor(selector);
    }
    
    return initFunction;
    
})(twentyFourJS);

script.js

(function($){

  $('.tab-menu li a').on('click', function(event) {

    console.log('I am clicked'); // This works
    
    this.addClass('MyClass'); // This does NOT work (as expected)

    // I want to be able to do this
    $(this).addClass('MyClass');

    event.preventDefault();

  });
})(twentyFourJS);

基本上我希望能够像在 jQuery 中那样使用 $(this)

this.addClass('MyClass')$(this).addClass('MyClass') 将不起作用,这是预期的行为。

据我了解,this 指的是普通的 HTML 元素。因此它无权访问任何构造函数方法。它不会工作。

而且我还没有编写任何代码来将元素包装在 $(this) 的 Constructor 对象中。我将不得不对我的 Constructor 做一些更改,以便我可以使用 $(this) 访问构造函数。那些changes/addition是什么?

请仅推荐 Vanilla JS 方式而不是库。

在您的构造函数中,您需要查看您拥有的内容并以不同的方式处理它。

const Constructor = function(selector) {
    if (typeof selector === 'string') {
        elements = document.querySelectorAll(selector);
    } else {
      // need some sort of check to see if collection or single element
      // This could be improved since it could fail when someone would add a length property/attribute
      elements = selector.length ? selector : [selector]; 
    }
    this.elements = elements;
};

您真正需要做的就是确保您的 Constructor 参数可以区分传入的字符串选择器和对象。

const Constructor = function(selector) {
  if(typeof selector == "string"){
    elements = document.querySelectorAll(selector);
    this.elements = elements;
  }
  else{
    this.elements = selector;
  }
};

您可以更进一步,但至少对于给出的示例有效。

下面的实例:

window.twentyFourJS = (function() {

    let elements;

    const Constructor = function(selector) {
      if(typeof selector == "string"){
        elements = document.querySelectorAll(selector);
        this.elements = elements;
      }
      else{
        this.elements = selector;
      }
    };

    Constructor.prototype.addClass = function(className) {
        elements.forEach( item => item.classList.add(className));
        return this;
    };

    Constructor.prototype.on = function(event, callback, useCapture = false){
        elements.forEach((element) => {
            element.addEventListener(event, callback, useCapture);
        });
        return this;
    }

  const initFunction = function(selector){
        return new Constructor(selector);
    }
    
    return initFunction;
    
})();


(function($){

  $('.btn').on('click', function(event) {

    console.log('I am clicked'); // This works
    
    // I want to be able to do this
    $(this).addClass('MyClass');

    event.preventDefault();

  });
})(twentyFourJS);
.MyClass{
  background-color:red
}
<button class="btn">Click me</btn>

  1. 首先你需要检查一个字符串 案例 1. $("div")
  2. 然后您需要检查它的 NodeType 和 window

案例 1. var elm = document .getElementById("ID") $(榆树) 案例 2. $(this) -- window

function $(selector){
var element; 
 if (typeof selector === 'string') {
element = document.querySelectorAll(selector)
}
if (element.nodeType || element=== window) element= [selector];

return element ; 
}