简体   繁体   English

如何返回包装 Object 而不是 HTML 元素?

[英]How to return a wrapper Object instead of HTML element?

I am writing a micro-library instead of using jQuery.我正在编写一个微库而不是使用 jQuery。 I need only 3-4 methods ( for DOM traversal, Adding Eventlisteners etc).我只需要 3-4 个方法(用于 DOM 遍历、添加事件监听器等)。 So I decided to write them myself instead of bloating the site with jQuery.所以我决定自己写它们,而不是用 jQuery 来膨胀网站。

Here is the snippet from the code:以下是代码片段:

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);

Basically I want to be able to use $(this) like we use it in jQuery.基本上我希望能够像我们在 jQuery 中使用它一样使用$(this)

this.addClass('MyClass') and $(this).addClass('MyClass') won't work and this is the expected behaviour. this.addClass('MyClass')$(this).addClass('MyClass')不起作用,这是预期的行为。

As per my understanding this is referring to the plain HTML element.据我了解this是指普通的 HTML 元素。 So it does not have access to any Constructor methods.因此它无法访问任何构造函数方法。 it won't work.它行不通。

And I have not written any code that will wrap element in Constructor object in $(this) .而且我还没有编写任何代码来将 Constructor object 中的元素包装在$(this)中。 I will have to do some changes to my Constructor so that I can access the Constructor functions using $(this) .我将不得不对我的Constructor函数进行一些更改,以便我可以使用$(this)访问构造函数。 What are those changes/addition to it?这些变化/补充是什么?

Kindly recommend only Vanilla JS ways instead of libraries.请仅推荐 Vanilla JS 方式而不是库。

in your constructor you need to see what you have and handle it in different ways.在您的构造函数中,您需要查看您拥有的内容并以不同的方式处理它。

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;
};

All you really need to do is make sure your Constructor argument can distinguish between a string selector being passed in, and an object.您真正需要做的就是确保您的Constructor参数可以区分传入的字符串选择器和 object。

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

You can go further than this, but at a very minimum for the example given that works.您可以 go 比这更进一步,但对于给出的示例来说,至少是最低限度的。

Live example below:下面的实时示例:

 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. first You Need to Check for a string case 1. $("div")首先你需要检查一个字符串大小写 1. $("div")
  2. Then You need to Check for it's NodeType and for a window然后您需要检查它的 NodeType 和 window

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

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

return element ; 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM