Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do you create a wrapper object that acts as a function like jquery

I don't know where to start but what I want or need is a wrapper function for HTMLElement so I don't extend HTMLElement class but etend my own object and then check has class to see if the element has a class etc etc but my code doesn't work at all it says $(...).hasClass is not a function

$ = function(a, b) {
  this.$el = document.querySelector(a);
  return this;
}

Object.assign($.prototype, {
  hasClass: function(selector) {
    return this.$el.classList.contains(selector);
  }
})

console.log($('#list').hasClass('list'));
like image 532
ONYX Avatar asked Apr 15 '19 03:04

ONYX


2 Answers

You're almost there - the issue is that the standalone expression

$('#list')

will have the default calling context of window (the this value inside the $ function). If you want to create an instance which can use prototype methods, put new before the call to $:

const $ = function(a, b) {
  this.$el = document.querySelector(a);
}

Object.assign($.prototype, {
  hasClass: function(selector) {
    return this.$el.classList.contains(selector);
  }
})

console.log(new $('#list').hasClass('list'));
console.log(new $('#list2').hasClass('foo'));
<div id="list"></div>
<div id="list2" class="foo"></div>

If you don't want to put new before every call, you can use Object.create inside $:

const $ = function(a, b) {
  const $obj = Object.create(proto);
  $obj.$el = document.querySelector(a);
  return $obj;
}

const proto = {
  hasClass: function(selector) {
    return this.$el.classList.contains(selector);
  }
};

console.log($('#list').hasClass('list'));
console.log($('#list2').hasClass('foo'));
<div id="list"></div>
<div id="list2" class="foo"></div>

I think the way jQuery does it is, the returned object's internal prototype is $.fn, eg:

const $ = function(a, b) {
  const $obj = Object.create($.fn);
  $obj.$el = document.querySelector(a);
  return $obj;
};
$.fn = {
  hasClass: function(selector) {
    return this.$el.classList.contains(selector);
  }
};

console.log($('#list').hasClass('list'));
console.log($('#list2').hasClass('foo'));
<div id="list"></div>
<div id="list2" class="foo"></div>
like image 98
CertainPerformance Avatar answered Nov 14 '22 23:11

CertainPerformance


Alternate Method do with return function inside the function

const $ = function(a, b) {
  var elem = document.querySelector(a);
  return {
    hasClass: function(selector) {
      return elem.classList.contains(selector);
    },
    addClass:function(cls){
      elem.classList.add(cls)
    }
  }
};

console.log($('#list').hasClass('list'));
console.log($('#list2').hasClass('foo'));
$('#list2').addClass('color_red');
.color_red{
  color:red
}
<div id="list"></div>
<div id="list2" class="foo">hello</div>
like image 20
prasanth Avatar answered Nov 14 '22 23:11

prasanth