Skip to content

Instantly share code, notes, and snippets.

@laobubu
Last active April 10, 2020 11:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laobubu/b633015ae3818e8c9726688da989199a to your computer and use it in GitHub Desktop.
Save laobubu/b633015ae3818e8c9726688da989199a to your computer and use it in GitHub Desktop.
njq (No jQuery) use vanilla DOM API with jQuery-like functions.

njq (No jQuery)

Vanilla JavaScript is good but the function names are too long. Now, you can use vanilla DOM API with jQuery-like functions.

Only ~1kB (without gzip) after uglifying. You can even tailor for yourself to make it much smaller, by deleting/adding modules. A good choice to manipulate DOM for side projects.

Document

njq works with vailla DOMElement. No jQuery collection unless you use $.eachCall to iterate and call functions (see below).

Selector

  • $(selector[, parent]) returns DOMElement
  • $$(selector[, parent]) returns DOMList

Array

  • $.each(array, callback) same as forEach. the callback function accepts two arguments: (index, element) and may return false to interrupt iterating.
  • $.eachCall(func, array, ...args) apply every element of array as the first argument, then call func with rest arguments args
    • this is the current element while iterating.
    • Example:
      • $.eachCall( $.addClass , $$('button') , 'blazing-button' )
      • $.eachCall( $.attr , $$('button') , 'style', 'color: red' )
      • $.eachCall( $.bind , jQuery('.p') , 'click', onClickFunction )
      • $.eachCall( window.alert, [ "Hello", "World" ] )

DOM

  • $.bind(element, eventName, handler[, use_capture])
  • $.unbind(element, eventName, handler[, use_capture])
  • $.attr(element, name) read the attribute name
  • $.attr(element, name, value) set the attribute name value
  • $.create(tagName[, attrs]) createElement and set attributes. attrs is a object
    • Example:
      • var p = $.create('p')
      • var div = $.create('div', {'class': 'blink'})

Style

  • $.addClass(element, className)
  • $.removeClass(element, className)
  • $.toggleClass(element, className) if class is removed, returns false, otherwise, returns true
  • $.hasClass(element, className)

Window

  • $.window.width()
  • $.window.height()
  • $.scrollX([x]) get or set scrollLeft
  • $.scrollY([y]) get or set scrollTop

History State

  • $.history.push(data, title[, url])
  • $.history.replace(data, title[, url])
  • $.history.bind(handler) where handler(ev) is a function. work with ev.state
  • $.history.unbind(handler)
'use strict'
// same as njq.js but only support modern browsers.
function $(selector, parent) { return (parent || document).querySelector(selector) }
function $$(selector, parent) { return (parent || document).querySelectorAll(selector) }
(function ($p) {
/// Array
$p.each = function (arr, cb) { for (var i = 0; i < arr.length; i++) if (cb(i, arr[i]) === false) break }
$p.eachCall = function (fun, arr, arg1, arg2) {
var argc = arguments.length - 2;
var argv = argc == 2 ? [] : argc == 3 ? [arg1] : argc == 4 ? [arg1, arg2] : [].slice.call(arguments, 2);
for (var i = 0; i < arr.length; i++) fun.apply(arr[i], [arr[i]].concat(argv));
}
/// DOM
$p.bind = function (el, ev, fun, capture) { el.addEventListener(ev, fun, !!capture) }
$p.unbind = function (el, ev, fun, capture) { el.removeEventListener(ev, fun, !!capture) }
$p.attr = function (el, name, val) { return (val !== void 0) ? el.setAttribute(name, val) : el.getAttribute(name) }
$p.create = function (tag, attrs) {
var el = document.createElement(tag);
if (attrs) for (var attr in attrs) el.setAttribute(attr, attrs[attr]);
}
/// Style
$p.addClass = function (el, cls) { el.classList.add(cls) }
$p.removeClass = function (el, cls) { el.classList.remove(cls) }
$p.toggleClass = function (el, cls) { return el.classList.toggle(cls) }
$p.hasClass = function (el, cls) { return el.classList.has(cls) }
/// Window
$p.window = {
width: function () { return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth },
height: function () { return wh = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight },
scrollX: function (x) { return (x === void 0) ? (window.scrollX) : (window.scrollTo(x, window.scrollY)) },
scrollY: function (y) { return (y === void 0) ? (window.scrollY) : (window.scrollTo(window.scrollX, y)) },
}
/// History State
$p.history = {
push: function (data, title, url) { history.pushState(data, title, url) },
replace: function (data, title, url) { history.replaceState(data, title, url), document.title = title },
bind: function (fun) { window.addEventListener('popstate', fun, false) },
unbind: function (fun) { window.removeEventListener('popstate', fun, false) },
}
})($.prototype);
// support most browsers. eg. IE 7+
function $(selector, parent) { return (parent || document).querySelector(selector) }
function $$(selector, parent) { return (parent || document).querySelectorAll(selector) }
(function ($p) {
/// Array
$p.each = function (arr, cb) { for (var i = 0; i < arr.length; i++) if (cb(i, arr[i]) === false) break }
$p.eachCall = function (fun, arr, arg1, arg2) {
var argc = arguments.length - 2;
var argv = argc == 2 ? [] : argc == 3 ? [arg1] : argc == 4 ? [arg1, arg2] : [].slice.call(arguments, 2);
for (var i = 0; i < arr.length; i++) fun.apply(arr[i], [arr[i]].concat(argv));
}
/// DOM
$p.bind = function (el, ev, fun, capture) { el.addEventListener(ev, fun, !!capture) }
$p.unbind = function (el, ev, fun, capture) { el.removeEventListener(ev, fun, !!capture) }
$p.attr = function (el, name, val) { return (val !== void 0) ? el.setAttribute(name, val) : el.getAttribute(name) }
$p.create = function (tag, attrs) {
var el = document.createElement(tag);
if (attrs) for (var attr in attrs) el.setAttribute(attr, attrs[attr]);
}
/// Style
$p.addClass = function (el, cls) { el.className += " " + cls }
$p.removeClass = function (el, cls) { el.className = el.className.replace(new RegExp('(?:^|\s+)' + cls + '(?:$|\s+)'), ' ') }
$p.toggleClass = function (el, cls) {
var ev = el.className, ev2 = ev.replace(new RegExp('(?:^|\s+)' + cls + '(?:$|\s+)'), ' ');
var hadClass = ev2 != ev;
if (hadClass) ev = ev2; else ev += ' ' + cls;
el.className = ev;
return !hadClass;
}
$p.hasClass = function (el, cls) {
var re = new RegExp('(?:^|\s+)' + cls + '(?:$|\s+)');
return re.test(el.className)
}
/// Window
$p.window = {
width: function () { return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth },
height: function () { return wh = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight },
scrollX: function (x) { return (x === void 0) ? (window.scrollX || document.documentElement.scrollLeft) : (window.scrollTo && window.scrollTo(x, window.scrollY)) },
scrollY: function (y) { return (y === void 0) ? (window.scrollY || document.documentElement.scrollTop) : (window.scrollTo && window.scrollTo(window.scrollX, y)) },
}
/// History State
$p.history = {
push: function (data, title, url) { history['pushState'] && history.pushState(data, title, url) },
replace: function (data, title, url) { history['replaceState'] && history.replaceState(data, title, url), document.title = title },
bind: function (fun) { window.addEventListener('popstate', fun, false) },
unbind: function (fun) { window.removeEventListener('popstate', fun, false) },
}
})($.prototype);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment