Lightweight shorthand JS library Long story short: I wanted some of the time-saving functionality of jQuery without the bulk of the entire library. So, I wrote a lightweight shorthand library inspired by jQuery I'm calling Mozart JS, and I'd like to see how I can further enhance it without major impact on load times.

Thoughts? Full library on GitHub.



Mozart JS

Element Retrieval

Fairly straightforward.

function $get(e, t) {
    if (void 0 === t) t = document;
    if (e.startsWith('#')) return t.getElementById(e.substring(1));
    if (e.startsWith('.')) return t.getElementsByClassName(e.substring(1));
    if (e.startsWith('-')) return t.getElementsByName(e.substring(1));
    return t.getElementsByTagName(e);
}


Example:

var foo = $get('#bar'); //returns element with the Id of "bar"
var zed = $get('.cop'); //returns collection with the classname "cop" 


Element Creation

Slightly more complicated; allows the assignment of common properties and all attributes.

function $make(t, p) {
    var o = document.createElement(t);
    if (p.style) o.style.cssText = p.style;
    if (p.class) o.className = p.class;
    if (p.text) o.textContent = p.text;
    if (p.value) o.value = p.value;
    Object.keys(p).forEach((e) =&gt; {
        if(e.startsWith("@")) {
            o.setAttribute(e.substring(1), p[e]);            
        }        
    });
    return o;
}


Example:

var h = $make('a', {
    'class': 'myClass',
    'text': 'Google',
    '@id': 'googleLink',
    '@href': 'https://google.com',
    '@target': '_blank'
});

//Equivalent to:

var h = document.createElement('a');
h.className = 'myClass';
h.textContent = 'Google';
h.setAttribute('id','googleLink');
h.setAttribute('href', 'https://google.com');
h.setAttribute('target', '_blank');


Element Sibling Insertion

Designed to mimic most of jQuery's insertBefore() method. Equivalent function exists for insertAfter(); omitted here in order to save space. 

function $addBefore(e, t) {
    if (typeof t === 'string' || t instanceof String) {
        if (t.startsWith('#')) {            
            $get(t).parentNode.insertBefore(e, $get(t));
        } else {
            var arr = $get(t);
            for (var i in arr) {
                var f = e.cloneNode(true);
                arr[i].parentNode.insertBefore(f, arr[i]);
            } 
        }
    } else {
        t.parentNode.insertBefore(e, t);
    }        
}


Example:

var foo = $make('div', {'text': 'This is a test'});
$addBefore(foo, '.myClass'); //adds an instance of foo before each myClass


Element Removal

Removes an element. Still uses basic jQuery syntax.

function $remove(e) {    
    if (typeof e === 'string' || e instanceof String) {
        $remove($get(e));
    } else if (e.nodeType === 1 || e.nodeType === 3) {
        e.parentNode.removeChild(e);
    } else {
        for (var i in e) {
            e[i].parentNode.removeChild(e[i]);
        }
    }
}


Example:

$remove('#myId');
$remove('.myClass');

//Equivalent to:

var rem = document.getElementById('myId');
rem.parentNode.remove(rem);
for (var i in document.getElementsByClassName(myClass)) {
    var elm = document.getElementsByClassName(myClass)[i];
    elm.parentNode.remove(elm);
}
I wanted some of the time-saving functionality of jQuery without the bulk of the entire library. 


If you don't look back at older browsers, use version 2.x of jQuery. It's smaller than the 1.x as it has less cross-browser compatibility code (See How 2.0 Changed section). You can also custom-build jQuery to your own spec to include what you need. An even smaller yet jQuery-compatible library is Zepto, just ~9k compressed.


  Element Retrieval


Pretty straightforward. However, there is querySelectorAll which pretty much acts like jQuery's $. A singular version of it is querySelector. It's native, and has been there for quite a while.

One neat thing about jQuery and jQuery-like libraries is that they encapsulate results, single or multiple, into a set. Methods operate by looping through and applying to each item in the set. No items, no loop, thus no throw. 

$('#foo').children().eq().next().remove();


The following example will not throw an error even when there's no #foo in the page.


  Element Creation


var h = $make('a', {
    'class': 'myClass',
    'text': 'Google',
    '@id': 'googleLink',
    '@href': 'https://google.com',
    '@target': '_blank'
});


Not entirely sure what's the difference between class and the other attributes when it's also an attribute. What should be different is text since it doesn't actually describe the element. Also, text nodes can be created separately via createTextNode.


  Element Sibling Insertion


if (t.startsWith('#')) {            
  $get(t).parentNode.insertBefore(e, $get(t));
} else {
  var arr = $get(t);
  for (var i in arr) {
    var f = e.cloneNode(true);
    arr[i].parentNode.insertBefore(f, arr[i]);
  } 
}


This is one case where your code will start to become unmaintainable. This function is making a special case for singular results. If you go with the set-like behavior of jQuery, singular results are still a set. Your code will always assume a set and be more consistent in operation.


  Element Removal


function $remove(e) {    
    if (typeof e === 'string' || e instanceof String) {
        $remove($get(e));
    } else if (e.nodeType === 1 || e.nodeType === 3) {
        e.parentNode.removeChild(e);
    } else {
        for (var i in e) {
            e[i].parentNode.removeChild(e[i]);
        }
    }
}


Again, your code is doing special cases for different things. This could have been easier if you operated with a set of things.

function $remove(input){

  // Building the set
  var set = inputIsAString ? lookForElements(input)
          : inputIsAnElement ? createASet(input)
          : inputIsAlreadyASet ? input
          : [];

  // The actual operation
  set.forEach(function(){
    // element removal code
  });
}