How to make Jquery's .html() function in Vanilla JavaScript

Viewed 437

I've been looking all over the web for how to do this. I am trying to make Jquerys .html() function in vanilla JavaScript. I want to recreate so I can understand it better. I've tried the following but nothing seems to work, I just don't understand what I am doing wrong.

let $ = function(ele) {
    if (ele.charAt(0) == '.' || ele.charAt(0) == '#') {
    let newEle = cut(ele,0);
    if (ele.charAt(0) == '#')
        get(newEle);
    else
        return document.getElementsByClassName(newEle);
  } else
    return document.getElementById(ele);
}

$.prototype.html = function(html) {
    this.innerHTML = html;
}

$('test').html('hey');
$('.hey')[0].html('hey');
function cut(string,num) {
    let a = string.slice(0,num);
  let b = string.slice(num + 1,string.length);
  return a + b;
}

It doesn't work, the console log reports this error:

Uncaught TypeError: $(...).html is not a function

Please help and thanks in advance.

2 Answers

The problem here is what you are returning from the $ function. Think about this: document.getElementsByClassName and document.getElementById return dom elements and dom elements don't have a .html function. That is why you are getting the error.

What you need is to return is an object, a wrapper, with a .html function, and a closure over the dom elements that you want to modify.

Because you're returning an object from $, you're overriding the default behavior of new $; instead of resulting in the newly-created object, it results in the object you returned out of $.

Instead, you'd want to remember the results of those getElementsByClassName/getElementById calls in an array or Set you store on this (the newly-created object), and then use that array or Set within html (since you want to loop over all matching elements in the case where you're setting the new HTML).


Side note: Since you're using ES2015+ features anyway (let), you might want to use the simpler class syntax instead of a separate function declaration and assigning to $.prototype:

class $ {
    constructor(ele) {
        // ...
    }

    html(html) {
        // ..
    }
}
Related