Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

104
Views
How to return a wrapper Object instead of HTML element?

I am writing a micro-library instead of using jQuery. I need only 3-4 methods ( for DOM traversal, Adding Eventlisteners etc). So I decided to write them myself instead of bloating the site with 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.

this.addClass('MyClass') and $(this).addClass('MyClass') won't work and this is the expected behaviour.

As per my understanding this is referring to the plain HTML element. 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). I will have to do some changes to my Constructor so that I can access the Constructor functions using $(this). What are those changes/addition to it?

Kindly recommend only Vanilla JS ways instead of libraries.

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

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;
};
about 4 years ago · Juan Pablo Isaza Report

0

  1. first You Need to Check for a string case 1. $("div")
  2. Then You need to Check for it's NodeType and for a window

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

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

return element ; 
}
about 4 years ago · Juan Pablo Isaza Report

0

All you really need to do is make sure your Constructor argument can distinguish between a string selector being passed in, and an 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.

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>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!