This is a fork of amazing Surreal library, configured for the Webflow no-code environment. For now it is a heavy WIP, so I'll leave the README as it was, and later describe some new features, that I'm planning to add.
🗿 Surreal - Hyper minimalist jQuery alternative
(Art by shahabalizadeh)
For devs who love ergonomics!
If you agree with any of the following, you may appreciate Surreal:
document.querySelector
over.. and over..addEventListener
over.. and over..document.querySelectorAll
had Array functions..this
would work in child <script>
tags.me()
inside <script>
to get an element without a unique id.this
but better.me()
, any()
, HTMLElement
, NodeList
, Array
of HTMLElement
me()
or many elements: any()
me()
or any()
can chain with any Surreal function.me()
can be used directly as a single element (like querySelector()
)any()
can use: for
/ forEach
/ filter
/ map
(like querySelectorAll()
or $()
)class_add
is just an alias of classAdd
camelCase
(Javascript) or snake_case
(Python, Rust, PHP, Ruby, SQL, CSS).Do surreal things with Locality of Behavior like:
<label for="file-input" >
<div class="uploader"></div>
<script>
me().on("dragover", ev => { halt(ev); me(ev).classAdd('.hover'); console.log("Files in drop zone.") })
me().on("dragleave", ev => { halt(ev); me(ev).classAdd('.hover'); console.log("Files left drop zone.") })
me().on("drop", ev => { halt(ev); me(ev).classRemove('.hover').classAdd('.loading'); me('#file-input').attribute('files', ev.dataTransfer.files); me('#form').trigger('change') })
</script>
</label>
Get a taste- see the Showcase! Then view source.
Surreal is a dependency-free, browser-oriented javascript library with zero build steps.
Download Surreal and drag surreal.js
into a directory of your project. Add <script>
to your <head>
.
<script src="surreal.js"></script>
me()
and any()
over $()
and $$()
$()
returns different things depending on context.Select one element: me(...)
me()
The current element.<script>
without an explicit .class or #idme("body")
Gets <body>
me(".button")
Gets the first <div class="button">...</div>
. To get all of them use any()
Select one or more elements (as an array): any(...)
any(".button")
Gets all matching elements, example: <div class="button">...</div>
any(me())
, me(any(".something"))
...
can be any of:".button"
, "#header"
, "h1"
, "body > .block"
body
, elt
, some_element
event.target
will be used.me()
,any()
start=
parameter provides a starting point to select from, default is document
.any('button', start='header').classAdd('red')
me()
and any()
me().classAdd('red')
(⭐ RECOMMENDED STYLE)$.me().classAdd('red')
classAdd(me(), 'red')
$.classAdd($.me(), 'red')
globalsAdd()
will automatically warn about any clobbering issues. If you prefer no conveniences, just delete globalsAdd()
See: Quick Start and Reference and No Surreal Needed
me().classAdd('red')
any("button").classAdd('red')
me().on("click", ev => me(ev).fade_out() )
on(any('button'), 'click', ev => { me(ev).styles('color: red') })
any('button').run(_ => { alert(_) })
me().styles('color: red')
me().styles({ 'color':'red', 'background':'blue' })
me().attribute('active', true)
<div>I change color every second.
<script>
// Locality of Behavior
me().on("click", async ev => {
me(ev).styles({ "transition": "background 1s" })
await sleep(1000)
me(ev).styles({ "background": "red" })
await sleep(1000)
me(ev).styles({ "background": "green" })
await sleep(1000)
me(ev).styles({ "background": "blue" })
await sleep(1000)
me(ev).styles({ "background": "none" })
await sleep(1000)
me(ev).remove()
})
</script>
</div>
<div>I fade out and remove myself.
<script>
// Keepin it simple! Locality of Behavior.
me().on("click", ev => { me(ev).fadeOut() })
</script>
</div>
<div>I change color every second.
<script>
// Run on load.
(async (el = me())=>{
me(el).styles({ "transition": "background 1s" })
await sleep(1000)
me(el).styles({ "background": "red" })
await sleep(1000)
me(el).styles({ "background": "green" })
await sleep(1000)
me(el).styles({ "background": "blue" })
await sleep(1000)
me(el).styles({ "background": "none" })
await sleep(1000)
me(el).remove()
})()
</script>
</div>
<script>
// Keepin it simple! Globally!
(async ()=>{
any("button").fadeOut()
})()
</script>
any('button')?.forEach(...)
any('button')?.map(...)
Looking for DOM Selectors?
🔗 Chainable off me()
and any()
🌐 Global convenience helper.
🏁 Runnable example.
🔌 Built-in Plugin
🔗 run
forEach
but less wordy and works on single elements, too!me().run(el => { alert(el) })
any('button').run(el => { alert(el) })
🔗 remove
me().remove()
any('button').remove()
🔗 classAdd
or class_add
me().classAdd('active')
.
is optional for all class functions, to prevent typical syntax errors with me()
and any()
.me().classAdd('active')
and me().classAdd('.active')
are equivalent.🔗 classRemove
or class_remove
me().classRemove('active')
🔗 classToggle
or class_toggle
me().classToggle('active')
🔗 styles
me().styles('color: red')
Add style.me().styles({ 'color':'red', 'background':'blue' })
Add multiple styles.me().styles({ 'background':null })
Remove style.🔗 attribute
or attributes
or attr
me().attribute('data-x')
any(...).run(...)
or any(...).forEach(...)
.me().attribute('data-x', true)
me().attribute({ 'data-x':'yes', 'data-y':'no' })
me().attribute('data-x', null)
me().attribute({ 'data-x': null, 'data-y':null })
🔗 trigger
me().trigger('hello')
dispatchEvent
🔗 on
me().on('click', ev => { me(ev).styles('background', 'red') })
addEventListener
🔗 off
me().remove('click')
removeEventListener
🔗 offAll
me().offAll()
🌐 sleep
await sleep(1000, ev => { alert(ev) })
async
version of setTimeout
🌐 tick
await tick()
await
version of rAF
/ requestAnimationFrame
.🌐 rAF
rAF(e => { return e })
🌐 rIC
rIC(e => { return e })
🌐 halt
halt(event)
🌐 createElement
or create_element
el_new = createElement("div"); me().prepend(el_new)
document.createElement
🌐 onloadAdd
or onload_add
onloadAdd(_ => { alert("loaded!"); })
ready()
window.onload
window.onload
, also predictable sequential loading!Build your own effects with me().styles({...})
then timelining with CSS transitions using await
or callbacks. We ship some common effects:
🔗 fadeOut
or fade_out
remove=false
.me().fadeOut()
me().fadeOut(ev => { alert("Faded out!") }, 3000)
Over 3 seconds then call function.🔗 fadeIn
or fade_in
opacity: 0
me().fadeIn()
me().fadeIn(ev => { alert("Faded in!") }, 3000)
Over 3 seconds then call function.More often than not, Vanilla JS is the easiest way!
Logging
console.log()
console.warn()
console.error()
monitorEvents(me())
See: Chrome BlogText / HTML Content
me().textContent = "hello world"
me().innerHTML = "<p>hello world</p>"
me().innerText = "hello world"
Children
me().children
me().children.hidden = true
Append / Prepend elements.
me().prepend(el_new)
me().appendChild(el_new)
me().insertBefore(el_new, el.firstChild)
me().insertAdjacentHTML("beforebegin", el_new)
_
= for temporary or unused variables. Keep it short and sweet!e
, el
, elt
= elemente
, ev
, evt
= eventf
, fn
= functionme().styles(...)
with CSS transitions. Use await sleep(...)
for timelining.Surreal is tiny enough to be modified for a particular use-case; but there is a system if you prefer to effortlessly merge with new versions.
Add your function to Surreal
var $thing = {
test(e, name) {
console.log(`Hello ${name} from ${e}`)
return e
}
}
$ = {...$, ...$thing}
Is your function chainable? Add it to Surreal sugar()
$.sugars['test'] = (name) => { return $.test($._e, name) }
Your function will automatically will be added globally by globalsAdd()
If you do not want this (ex: Naming clash), add it to the restricted list in globalsAdd()
Should your function work with both single elements and arrays of elements? Refer to an existing function to see how to make this work.
Make an issue or pull request if you think people would like to use it! If it's useful enough we may want it in the core!
showcase.html
goodies!Author: Purepotential
Source Code: https://github.com/purepotential/surreal-wf
License: MIT license