An easy Way For You to Manipulate Document Object Model (DOM)
npm i --save @wayfu/wayfu-dom
In your app.js import and initialized the module like normal.
import DOM from "@wayfu/wayfu-dom";
If you wish to skip the modular build and NOT use npm you can use the vanilla build like so:
<script src="https://unpkg.com/@wayfu/wayfu-dom@latest/dist/wayfu-dom.min.js"></script>
This can be used to getting one or multiple elements at the same time.
You can using DOM.get(query:string)
static method to get element from global document.
/** Get an element(s) and then
* manipulate it with built-in DOM method
*/
DOM.get("query");
/**
* You can store it in a variable too.
* This will return a new DOM class Object
*/
let element = DOM.get("query");
Of course you can find and get child element using query. For this you need to set the parent element using DOM.get(query:string)
static method. Then, you can use .get(query:string)
method from your DOM object. For example:
/** Let's find our div container */
let container = DOM.get("div.container");
/** Now, let's find container item from our container parent */
let cont-items = container.get(".cont-item");
/** This will return new DOM object with matched element, not modifying or overriding the parent DOM object.
You can create an element(s) easily using DOM.create()
method.
type elemenOptions = ElementCreationOptions & {
tag: keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap,
namespace?: string,
text?: string,
html?: string,
class?: string,
classid?: string | string[],
append?: String | HTMLElement,
prepend?: String | HTMLElement,
before?: String | HTMLElement,
after?: String | HTMLElement,
replace?: String | HTMLElement,
event?: DocumentEventMap[],
callback?: (node:HTMLElement) => any,
}
/** DOM.create accept 2 params */
/** First param can be string or an object, like */
DOM.create("div"); // this will return new DOM class instance with 1 div element.
let link = DOM.create("a"); // of cource you can also store it into a variable.
/**
* The second param is optional,
* it must be an object contains the `elemenOptions`.
*/
let paragraph = DOM.create("p", {text: "Hello World!"});
// This will return a new DOM class object with 1 paragraph element that contains `Hello World!` text
You can call .create()
method as DOM prototype method from DOM created object too. This method only accept 1 parameter, that is elemenOptions
object.
If you call this method, it will automatically append
the new element into the previous DOM element, and it will return the new DOM object with new created element. For example:
/** Let's find our container */
let container = DOM.get("div.container");
/** Now, let's create new element inside the container */
let cont-item = container.create({tag: "div", classid: "cont-item"});
/**
* The container element now has cont-item child;
* And the `cont-item` value is new DOM object with `div.cont-item` element.
*/
Different between
.create()
and.insert()
is:.create()
will return the new DOM with new created element, instead of return the main DOM object like.insert()
do.
You can modify your element(s) easily. using built-in method. There are some method that can be used to modifying DOM element.
A new DOM class method have built-in .set()
method for setting either Element property or Element styles. This mettod can accept 1 or 2 parameters. The first parameter can be an object or the key (as string
) of the property or style. And the second param can be the value of the key.
// Get the element
let link = DOM.get("a.link");
// Using an object as params
link.set({href: "https://foo.baz"}); // change href property
// Using 2 params
link.set("target", "_blank"); // change target property
link.set("color", "blue"); // change color style property
We also provide some built-in method for manipulating DOM such as inserting, replacing or deleting element.
/** Let's make a container */
let container = DOM.create("div", {classid: "container"});
/** Use .insert(element) to append an element */
// Now add container item inside container
container.insert({tag: "div", classid: "cont-item"});
/** Use .insertTo(target) to inject current element to target */
// This new element will be inserted to main container
DOM.create("div", {classid: "cont-item2"}).insertTo(container);
/** Use .insertBefore(target) to inject current element as first child target element */
DOM.create("p", {id:"ph", text: "Hello World!"}).insertBefore("div.cont-item");
// This paragraph element will be inserted as first child of `cont-item`
/** Use .insertBefore(target, true) to inject current element before the target */
DOM.create("div", {classid: "cont-item0"}).insertBefore("div.cont-item", true);
// A div.cont-item0 will be added before the 'cont-item'.
/** Use .insertAfter(target) to inject current element after the target */
DOM.create("p", {id:"item", text: "Lorem Ipsum"}).insertAfter("p#ph");
/** Use .remove() to remove element */
// If no param, this method will remove current element and all it's children from body.
container.remove();
// Or you can specify the target element.
// The target element must be the children from current element.
// such as
container.remove("div.cont-item0");
/** Use .replace(target) to replace target element with current element */
DOM.create("p", {id: "desc", text: "Foo Baz"}).replace("p#id");
// This new paragraph element will be replacing the p#id element
As an object, DOM provide some properties that can access using getter mettod.
/** Let's get some post item, shall we? */
let postItems = DOM.get("div.post-items");
/**
* .isEmpty return boolean value
* based on any element on this current DOM Object
*/
postItems.isEmpty; // either true or false;
/**
* .first return HTMLElement instance
* for the first matched element
*/
let firstPost = postItems.first; // Will return HTMLElement or undefined
/** We have .last to check last matced element also */
let lastPost = postItems.last; // Will return HTMLElement or undefined
/** This getters bellow will work if there is a `first` element */
// .childNodes get the first element childNodes
postItems.childNodes; // will return DOM or undefined
// .parent to get the first element parent element
postItems.parent; // will return DOM or undefined
// .nextSibling to get next sibling element
postItems.nextSibling; // will return DOM or undefined
// .classList to get all css class from first element
postItems.classList; // will return DOMTokenList or undefined
/** Of course you can deconstruct it to variable */
// for example
let { childNodes, classList } = DOM.get("div.post-header");
As a Class, DOM provide some other static method besides .get()
and .create()
. There are...
This static method accept 2 params. The first one is caled svgElementDetais
or array of it, and the second one is optional, that is an object for element properties.
type svgElementDetails = {
type: keyof SVGElementTagNameMap,
data: SVGElement
}
Usage:
/** Single svgElementDetails */
const check = {
type: "polyline",
data: {
points: "1 1 5 5 9 1",
},
};
/** Array of svgElementDetails */
const download = [
{
type: "path",
data: {
fill: "currentColor",
d: "M18.948 11.112C18.511 7.67 15.563 5 12.004 5c-2.756 0-5.15 1.611-6.243 4.15-2.148.642-3.757 2.67-3.757 4.85 0 2.757 2.243 5 5 5h1v-2h-1c-1.654 0-3-1.346-3-3 0-1.404 1.199-2.757 2.673-3.016l.581-.102.192-.558C8.153 8.273 9.898 7 12.004 7c2.757 0 5 2.243 5 5v1h1c1.103 0 2 .897 2 2s-.897 2-2 2h-2v2h2c2.206 0 4-1.794 4-4a4.008 4.008 0 0 0-3.056-3.888z",
},
},
{
type: "path",
data: {
fill: "currentColor",
d: "M13.004 14v-4h-2v4h-3l4 5 4-5z",
},
},
];
/** Convert to Element */
// Using 1 params
let checkIcon = DOM.createIcon(check);
// Using 2 params to set current svg properties
let downloadIcon = DOM.createIcon(download, {
height: "24", // set the icon height
width: "24", // set the icon width
viewBox: "0 0 128 128", // set svg view-box
classid: "download-ico" // set svg css class
});
/** This static method will return a DOM Object */
// So it can use it's built-in method too, for example
downloadIcon.insertTo("span.btn-download");
// or
checkIcon.insertAfter("span.success-toast-header");
This method accept 3 parameters. The first parameter the item list, it can be an array of string or an array of listElementOptions
.
type listElementOptions = elemenOptions & {
title: string,
type: "ol" | "ul",
content: string | string[] | listElementOptions[],
}
The second parameter is the list type either ul
or ol
, (by default using ol
). And the last parameter is an object of elementOptions
.
Usage:
const item = [
"foo",
"bar",
"baz",
{
title: "main",
type: "ol",
content: [
"foo bar",
"foo baz"
]
}
];
// Support for nasted list
let list = DOM.createList(item, "ul");
/** This static method will return a DOM Object */
// So it can use it's built-in method too, for example
list.insertTo("div.post-body");
This method accept 2 parameter. The first parameter is css stylesheet as string
. And the second parameter is optional, it should be an elementOptions
object.
Usage:
// Custom css
const css = "a.link{color: 'blue'}";
// Inject it to head
DOM.addStyle(css, {id: "custom-css"});
This method accept 2 parameter. The first parameter can be query element as string
and the second parameter is number of the interval (by default is 10
). The interval itself is 1 second.
This method Retrun a Promise
. If the target element is exsist, then return it as HTMLElement
instance, and return false
if the target is not exsist after reaching interval.
Usage:
// Because its a promise, you should use `async ~ await` function to make it syncronous
async someFunction(){
/** Let's check comment container */
let isCommentLoad = await DOM.has("div#comments");
if(isCommentLoad) {
// do something;
} else {
// do something
}
}
This library comes with TypeScript "typings". If you happen to find any bugs in those, create an issue.