NexaKit — manipulasi DOM
Toolkit selektor dan manipulasi DOM lewat NX.id, NX.class,
NX.selector, dan method berantai (gaya jQuery, ES6+). Ini berbeda dari
NX.Event() — NexaEvent
(delegasi global & audit). Urutan baca disarankan setelah route/grid/event, sebelum
NX.NexaDom.
Instalasi & akses
Pada bundel NXDOM, API umumnya sudah terpasang di NX. Bila memuat modul terpisah:
import { NexaKit } from "./NexaKit.js";
const UI = new NexaKit();
NX.id("myElement").innerHTML = "Hello World";Element selection
Selektor dasar
NX.id("elementId");
NX.class("className");
NX.classAll("className");
NX.selector("#myId .myClass");
NX.selectorAll("div.container p");Content manipulation
Konten dasar
NX.id("element").innerHTML = "<strong>Bold text</strong>";
const content = NX.id("element").innerHTML;
NX.id("element").textContent = "Plain text only";
const text = NX.id("element").textContent;
NX.id("element").clear();Penyisipan & struktur
NX.id("element").append("<p>New paragraph</p>");
NX.id("element").prepend("<h2>Title</h2>");
NX.id("element").before("<div>Before element</div>");
NX.id("element").after("<div>After element</div>");
NX.id("element").replaceWith("<span>New element</span>");
NX.id("element").wrap('<div class="wrapper"></div>');
NX.id("element").unwrap();
NX.id("element").empty();Style & classes
Kelas CSS
NX.id("element").addClass("newClass");
NX.id("element").removeClass("oldClass");
NX.id("element").toggleClass("activeClass");
const hasClass = NX.id("element").hasClass("someClass");
NX.id("element").replaceClass("oldClass", "newClass");
NX.id("element").setClasses("class1 class2 class3");
const classes = NX.id("element").getClasses();Style inline & computed
NX.id("element").setStyle("color", "red");
NX.id("element")
.setStyle("width", "200px")
.setStyle("height", "100px")
.setStyle("background", "blue");
const color = NX.id("element").css("color");
const allStyles = NX.id("element").css();Visibility
NX.id("element").show();
NX.id("element").hide();
const isVisible = NX.id("element").isVisible();
const inViewport = NX.id("element").isInViewport();Event handling (per elemen)
Listener pada node yang dipilih. Untuk delegasi terpusat seperti klik document + fungsi di
window, pakai NexaEvent.
Mouse & klik
NX.id("button").on("click", function (e) {
console.log("Button clicked!");
});
NX.id("element").on("dblclick", function (e) {
console.log("Double clicked!");
});
NX.id("element").on("contextmenu", function (e) {
e.preventDefault();
console.log("Right clicked!");
});
NX.id("element")
.on("mouseenter", () => console.log("Mouse entered"))
.on("mouseleave", () => console.log("Mouse left"))
.on("mousedown", () => console.log("Mouse pressed"))
.on("mouseup", () => console.log("Mouse released"));Keyboard
NX.id("input").on("keydown", function (e) {
console.log("Key pressed:", e.key);
if (e.key === "Enter") {
console.log("Enter was pressed!");
}
if (e.ctrlKey && e.key === "s") {
e.preventDefault();
console.log("Ctrl+S — save");
}
});
NX.id("input").on("keyup", function (e) {
console.log("Key released:", e.key, "value:", e.target.value);
});Form events
NX.id("input").on("input", function (e) {
console.log("Input value changed:", e.target.value);
});
NX.id("select").on("change", function (e) {
console.log("Selection changed:", e.target.value);
});
NX.id("checkbox").on("change", function (e) {
console.log("Checkbox state:", e.target.checked);
});
NX.id("input")
.on("focus", () => console.log("Input focused"))
.on("blur", () => console.log("Input lost focus"));
NX.id("form").on("submit", function (e) {
e.preventDefault();
const formData = NX.id("form").serialize();
console.log("Form submitted:", formData);
});Window & dokumen
NX.selector("document").on("DOMContentLoaded", function () {
console.log("DOM fully loaded");
});
NX.selector("window").on("load", function () {
console.log("Page fully loaded");
});
NX.selector("window").on("resize", function () {
console.log("Window resized");
});
NX.selector("window").on("scroll", function () {
console.log("Page scrolled");
});Touch & drag-and-drop
NX.id("element")
.on("touchstart", (e) => console.log("Touch started"))
.on("touchmove", (e) => console.log("Touch moved"))
.on("touchend", (e) => console.log("Touch ended"));
NX.id("draggable").on("dragstart", function (e) {
e.dataTransfer.setData("text/plain", "Hello World");
});
NX.id("dropzone")
.on("dragover", function (e) {
e.preventDefault();
})
.on("drop", function (e) {
e.preventDefault();
const data = e.dataTransfer.getData("text/plain");
console.log("Dropped:", data);
});Custom event & delegasi
NX.id("element").trigger("customEvent", {
detail: { message: "Hello from custom event!" },
});
NX.id("element").on("customEvent", function (e) {
console.log("Custom event received:", e.detail);
});
NX.id("container").on("click", function (e) {
if (e.target.matches(".dynamic-button")) {
console.log("Dynamic button clicked!");
}
});
NX.id("email").on("keyup", function (e) "invalid"););Attributes & data
Atribut HTML
NX.id("element").attr("title", "Tooltip text");
const title = NX.id("element").attr("title");
NX.id("element").removeAttr("old-attr");
const hasAttr = NX.id("element").hasAttr("data-id");
const allAttrs = NX.id("element").getAllAttrs();
const attrNames = NX.id("element").getAttrNames();data-*
NX.id("element").data("userId", "12345");
const userId = NX.id("element").data("userId");
const allData = NX.id("element").getAllData();Form handling
Nilai field
NX.id("input").val("New value");
const value = NX.id("input").val();
NX.id("input").placeholder("Enter your name");
const placeholder = NX.id("input").placeholder();
NX.id("checkbox").checked(true);
const isChecked = NX.id("checkbox").checked();
NX.id("input").disabled(true);
const isDisabled = NX.id("input").disabled();Operasi form
NX.id("form").submit();
NX.id("form").reset();
const formData = NX.id("form").serialize();
NX.id("input").focus();
NX.id("input").blur();
NX.id("input").select();Animations
Fade
NX.id("element").fadeIn();
NX.id("element").fadeIn(500);
NX.id("element").fadeOut(300);
NX.id("element")
.fadeOut()
.then(() => {
NX.id("element").innerHTML = "New content";
NX.id("element").fadeIn();
});Slide
NX.id("element").slideUp();
NX.id("element").slideDown();
NX.id("element").slideUp(500);Dimensions & position
NX.id("element").width(200);
const width = NX.id("element").width();
NX.id("element").height("50%");
const height = NX.id("element").height();
const pos = NX.id("element").position();
NX.id("element").scrollIntoView();
NX.id("element").scrollIntoView({
behavior: "smooth",
block: "center",
});
NX.id("element").scrollTo(100, 50);DOM traversal
const parent = NX.id("element").parent();
const children = NX.id("element").children();
const child = NX.id("element").find(".child-class");
const allChildren = NX.id("element").findAll("p");
const next = NX.id("element").next();
const nextDiv = NX.id("element").next("div");
const prev = NX.id("element").prev();
const allNext = NX.id("element").nextAll();
const allPrev = NX.id("element").prevAll();
const siblings = NX.id("element").siblings();Element inspection
const props = NX.id("element").getProperties();
const structure = NX.id("element").getStructure();
const tagName = NX.id("element").tagName();
const matches = NX.id("element").is(".my-class");
const hasContent = NX.id("element").hasContent();
const inspection = NX.id("element").inspect();
NX.id("element").debug();
const dataAttrs = NX.id("element").getAttrs("data-");Utilities
const cloned = NX.id("element").clone();
NX.id("element").remove();
NX.id("element").detach();
const outerHTML = NX.id("element").outerHTML();
NX.id("element").outerHTML("<div>New element</div>");
if (NX.id("element").element) {
/* elemen ada */
}
const hasRequired = NX.id("input").hasAttrs(["name", "id", "data-required"]);
const element = NX.id("button");
if (element.isVisible() && !element.disabled()) {
element.trigger("click");
}Method chaining
NX.id("element")
.addClass("active")
.setStyle("color", "blue")
.attr("title", "Active element")
.fadeIn(300)
.on("click", function () {
console.log("Element clicked!");
});Contoh praktis
Validasi form login
const form = NX.id("loginForm");
const email = NX.id("email");
const password = NX.id("password");
form.on("submit", function (e) {
e.preventDefault();
if (!email.val().includes("@")) {
email.addClass("error").focus();
return;
}
if (password.val().length < 6) {
password.addClass("error").focus();
return;
}
const formData = form.serialize();
console.log("Submitting:", formData);
});Muat konten dinamis (fade)
function loadContent(url) {
const container = NX.id("content");
container.fadeOut(200).then(() => {
container.innerHTML = '<div class="loading">Loading...</div>';
container.fadeIn(200);
setTimeout(() => {
container.fadeOut(200).then(() => {
container.innerHTML = "<h2>New Content Loaded!</h2>";
container.fadeIn(300);
});
}, 1000);
});
}Error handling
Jika elemen tidak ada, NexaKit mengembalikan objek dummy aman sehingga rantai method tidak melempar error (biasanya ada peringatan di konsol).
NX.id("nonExistentElement").addClass("test");
const width = NX.id("nonExistent").width();
const attrs = NX.id("nonExistent").getAllAttrs();Best practices
- Gunakan method chaining untuk beberapa operasi berturut-turut.
- Periksa keberadaan elemen sebelum operasi kritis (atau andalkan dummy + log konsol).
- Manfaatkan method inspeksi (
debug,inspect) saat debugging. - Padukan dengan fitur ES modern (
async/await, destrukturisasi).
Browser support
- Browser modern dengan dukungan ES6+.
- Garis besar: Chrome 60+, Firefox 55+, Safari 10.1+, Edge 79+.
Berkas implementasi
Logika utama ada di assets/modules/Dom/NexaKit.js, diekspos melalui bundel
nxdom.js sebagai NX / NexaKit sesuai konfigurasi proyek Anda.