0

I am trying to figure out how jQuery is both a function which accepts an argument and returns a value (selector -> array of elements), and also an object that can be extended with new methods:

$.fn.myMethod = function() {//do stuff}

As a company we are moving away from jQuery, because vanilla JS is so useable. However we have some jQuery plugins I wrote that we would like to keep using. I am re-writing them, but would like to keep the syntax for using them similar to how it was in JQ. I don't want to extend the Element object (element.myPlugin()) for obvious reasons, so I was thinking I would create my own wrapper like JQ. Ideally I could define the base/default function that returns an array of DOM elements like so:

const __ = function(element) {
    if (typeof element === 'string') {
        return document.querySelectorAll(element)
    }
    return [element]
}

But then later, this function could be extended with new methods:

__.myNewPlugin = function(text) {
    this.forEach(el => el.innerText = text)
}

Where this is the array of DOM elements returned by the base/default function, so that later the rest of my team could use the new method like so:

__(document.querySelector('.thing')).myNewPlugin('Hi SO')

-or-

__('.thing').myNewPlugin('Hi SO')

If for some reason you think this is a bad idea, I'm happy to hear your reasoning, but please also post an example of how this is achieved. It's obviously possible (because JQ does it), so even if I decide not to go this route, I'd still like to learn how something like this could be implemented.

Chad
  • 21
  • 5
  • You will want to return an instance of a custom class (on whose `.prototype` you can install any methods you want), not an array. jQuery doesn't return arrays, although jQuery instances look a lot like arrays (indexed elements, `.length` property). – Bergi Jul 25 '19 at 18:53
  • take a look at the module pattern. – ThS Jul 25 '19 at 18:55
  • @Bergi thank you! I have a couple more questions. So far I have come up with this https://codepen.io/chadd/pen/pMEEQq?editors=0010. 1) adding the prototype doesnt seem to be working, what am I doing wrong? 2) how does jquery allow you to install methods and reference itself using the same name? – Chad Jul 25 '19 at 21:39
  • @Bergi, it looks like #1 was not working because my class was extending Object, when I get rid of that, it works. However, Im still curious how I can do $.fn.thing = function(){} and $('p') – Chad Jul 25 '19 at 21:49
  • @Chad Drop the unnecessary `extends Object` and `return this`, and `new NodeList` doesn't work, but apart from those your code looks fine. What exactly does not work? – Bergi Jul 25 '19 at 21:49
  • @Chad jQuery just sets `$.fn = Selector.prototype`. Have a look [here](https://stackoverflow.com/a/12143833/1048572) for details (although I would not recommend to follow jQuery's antiquated pattern too closely) – Bergi Jul 25 '19 at 21:51

0 Answers0