like bling.js, but more bling
npm i blingblingjs
// import the blingbling y'all
import $ from 'blingblingjs' // es6 module
const $ = require('blingblingjs') // commonjs
// or from Pika CDN! https://cdn.pika.dev/blingblingjs/v2
javascript: fetch('https://cdn.jsdelivr.net/npm/blingblingjs@latest/dist/index.min.js').then((x) => x.text()).then((x) => {
eval(x); $ = $.default;
console.log("💲 BlingBlingJS ready 💲");
});
$() // select nodes in document or pass nodes in
$().on // add multiple event listeners to multiple nodes
$().off // remove multiple event listeners from multiple nodes
$().attr // CRUD attributes on nodes
$().map // use native array methods
// get nodes from the document
const btns = $('button') // blingbling always returns an array
const [first_btn] = $('button[primary]') // destructure shortcut for 1st/only match
const btn_spans = $('span', btns) // provide a query context by passing a 2nd param of node/nodes
// cover DOM nodes in bling
const [sugared_single] = $(document.querySelector('button'))
const sugared_buttons = $(document.querySelectorAll('button'))
$('button').forEach(...)
$('button').map(...)
const btns = $('button')
btns.filter(...)
btns.reduce(...)
btns.flatMap(...)
...
// single events
first_btn.on('click', ({target}) => console.log(target))
$('button[primary]').on('click', e => console.log(e))
// single events with options
first_btn.on('click', ({target}) => console.log(target), {once: true})
$('button[primary]').on('click', e => console.log(e), true) // useCapture
// multiple events
$('h1').on('click touchend', ({target}) => console.log(target))
// remove events
const log_event = e => console.warn(e) // must have a reference to the original function
main_btn.on('contextmenu', log_event)
main_btn.off('contextmenu', log_event)
// set an attribute
$('button.rad').attr('rad', true)
// set multiple attributes
const [rad_btn] = $('button.rad')
rad_btn.attr({
test: 'foo',
hi: 'bye',
})
// get an attribute
rad_btn.attr('rad') // "true"
rad_btn.attr('hi') // "bye"
// get multiple attributes
$('button').map(btn => ({
tests: btn.attr('tests'),
hi: btn.attr('hi'),
}))
// remove an attribute
rad_btn.attr('hi', null) // set to null to remove
rad_btn.attr('hi') // attribute not found
// remove multiple attributes
btns.attr({
test: null,
hi: null,
})
import {rIC, rAF} from 'blingblingjs'
// requestAnimationFrame
rAF(_ => {
// animation tick
})
// requestIdleCallback
rIC(_ => {
// good time to compute
})
Developer ergonomics! If you agree with any of the following, you may appreciate this micro library:
document.querySelector
over.. and over.. addEventListener
over.. and over..document.querySelectorAll
had array methods on it..node.setAttributes({...})
or even better nodeList.setAttributes({...})