Something went wrong. Try again.
home to your local SPACEGIRL 💫 arimelody.space
Something went wrong. Try again.
3.4 kB · 96 lines
JavaScript
at dev
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697/** * Creates a reorderable list from any `container` and viable list item selector. * * This function is absolute magic and I love it * * Example: * ```html * <ul id="list"> * <li>Item 1</li> * <li>Item 2</li> * <li>Item 3</li> * </ul> * ``` * ```js * // javascript * makeMagicList(document.getElementById("list"), "li"); * ``` * * @param {HTMLElement} container The parent container to use as a list. * @param {string} itemSelector The selector name of list item elements. * @param {Function} callback A function to call after each reordering. */export function makeMagicList(container, itemSelector, callback) { if (!container) throw new Error("container not provided"); if (!itemSelector) throw new Error("itemSelector not provided");
container.querySelectorAll(itemSelector).forEach(item => { item.draggable = true; item.addEventListener("dragstart", () => { item.classList.add("moving") }); item.addEventListener("dragend", () => { item.classList.remove("moving") }); // dragging on inputs should take priority item.querySelectorAll("input").forEach(el => { el.addEventListener("mousedown", () => { item.draggable = false }); el.addEventListener("mouseup", () => { item.draggable = true }); el.addEventListener("dragstart", e => { e.stopPropagation() }); }); });
var lastCursorY; container.addEventListener("dragover", event => { const dragging = container.querySelector(itemSelector + ".moving"); if (!dragging) return;
let cursorY = event.touches ? event.touches[0].clientY : event.clientY;
// don't bother processing if we haven't moved if (lastCursorY === cursorY) return lastCursorY = cursorY;
// get the element positioned ahead of the cursor const notMoving = [...container.querySelectorAll(itemSelector + ":not(.moving)")]; const afterElement = notMoving.reduce((previous, current) => { const box = current.getBoundingClientRect(); const offset = cursorY - box.top - box.height / 2; if (offset < 0 && offset > previous.offset) return { offset: offset, element: current }; return previous; }, { offset: Number.NEGATIVE_INFINITY }).element;
if (afterElement) { container.insertBefore(dragging, afterElement); } else { container.appendChild(dragging); }
if (callback) callback(); });}
export function hijackClickEvent(container, link) { container.addEventListener('click', event => { if (event.target.tagName.toLowerCase() === 'a') return; event.preventDefault(); link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window, ctrlKey: event.ctrlKey, metaKey: event.metaKey, shiftKey: event.shiftKey, altKey: event.altKey, button: event.button, })); });}
document.addEventListener("readystatechange", () => { const navbar = document.getElementById("navbar"); document.getElementById("toggle-nav").addEventListener("click", event => { event.preventDefault(); navbar.classList.toggle("open"); })});