htmlhammer
Write HTML with JavaScript using real HTML tag names.
Why?
- String literals tend to get messy and unreadable
- Maybe you don’t want or need JSX
- HyperScript is ok but you would like to avoid manually writing HTML tag names
- Make writing HTML in JavaScript feel almost like writing it in .html file
- Make writing HTML in JavaScript dead simple and intuitive but keeping all of the JavaScript’s power
Install
github
Latest version:
npm install git+https://github.com/vsmid/htmlhammer.git --saveSpecific version:
npm install git+https://github.com/vsmid/htmlhammer.git\#1.0.0 --save
npmjs
npm i htmlhammer
unpkg
<!-- Latest version CJS -->
<script src="https://unpkg.com/htmlhammer"></script>
<!-- Version 1.0.1 CJS -->
<script src="https://unpkg.com/htmlhammer@1.0.1"></script>
<!-- Latest version ESM -->
<script type="module">
import { div } from "https://unpkg.com/htmlhammer?module";
</script>
<!-- Latest version single file IIFE -->
<script src="https://unpkg.com/htmlhammer/htmlhammer.js"></script>
<!-- Latest version minified single file IIFE -->
<script src="https://unpkg.com/htmlhammer/htmlhammer.min.js"></script>For specific versions use url format: unpkg.com/:package@:version/:file. See UNPKG for more info.
Including htmlhammer
Script tag
<script src="./htmlhammer.js"></script>
<!-- script src="./htmlhammer.min.js"></script -->
<script>
const { div, a, h1 } = htmlhammer;
</script>Import as cjs
import { div, a, h1 } from "htmlhammer";Import as esm
<script type="module">
import { div, a, h1 } from "./node_modules/htmlhammer/esm/index.js";
</script>Using htmlhammer
Supported HTML tags/elements
See the list on MDN. Tags/elements marked as obsolete/deprecated are not supported.
Signature
// Function name htmltagname is one of supported HTML tag/elements, e.g. div, a, h1, table etc.
htmltagname((attributes = {}), ...children);Parameters:
- attributes - JSON object where key is the name of the element’s attribute and value is the new attribute value. See reserved attributes.
- children - element or elements to be appended to parent element. Can be string, number, another HTMLElement created in a regular way or by htmlhammer, function returning one of the previously stated types etc.
Returns:
- An array of HTMLElement or a single HTMLElement.
Code sample
let items = [{ value: 1 }, { value: 2 }];
document.body.append(
div(
{ style: { color: "red" } },
h1({}, "I am the title"),
a({ href: "#" }, "Click me!"),
table(
{},
tr({ $for: items }, (item) => td({}, item.value))
)
)
);String as HTML
If you have HTML in string format and you would like for it to be added to element as HTML you should wrap it in HTMLString class. This is useful when you want to inject already generated HTML in string format to an element (e.g. HTML content received from REST service).
import { div, HTMLString } from "./esm/index.js";
const html = "<h1>Hello World!</h1>";
document.body.append(
div({}, new HTMLString(html)) // Without HTMLString wrapper, html content would be treated as text content hence text node would be created
);Version 2.1.0 introduced a new attribute handler $apply which alows you to create element inline in any way you like.
const RawHtml = (data) => (el) => (el.innerHTML = data);
document.body.append(
div({},
span({ $apply: RawHtml("<h1>Hello World!</h1>") })
)
);For more complex and complete example check index.html.
Reserved element attributes
$for - creating multiple elements of the same type
// Creates three elements of type div, <div>1</div>, <div>2</div>, <div>3</div>
div({ $for: [1, 2, 3] }, (item) => item);$if - conditionally create element
div({ $if: true }, "I am created");
div({ $if: () => true }, "I am created");
// Create only items with value > 2
div({ $for: [1, 2, 3], $if: (item) => item > 2 }, (item) => item);$ref - reference created element
A key under which element will be stored must be an object!
const { div, ref, setRef } = htmlhammer;
// Reference by object
let obj = {};
// Prior to 2.2.0
let element = div({ $ref: setRef(obj) }, "Hello World!");
// Version 2.2.0 allows ref to be set just by passing an object reference
let element = div({ $ref: obj }, "Hello World!");
console.log(ref(obj) === element);
// Manually assigning id if the same object is used for multiple references
let person = new Person("Lena", 0);
div({ $ref: setRef(person, "name") }, person.name);
div({ $ref: setRef(person, "age") }, person.age);
console.log(ref(person, "name"));
console.log(ref(person, "age"));
// If used in combination with $for do not set object reference manually because it will automatically be set to the list item value
element = div(
{ $for: [{ v: 1 }, { v: 2 }, { v: 3 }], $ref: setRef },
"Hello World!"
);$apply - apply anything to an element
Use this attribute to apply anything to an element. This gives you the full power of JavaScript Element API mixed within htmlhammer's inline element creation. This can also be ideal for sharing style, logic, event handlers etc. across multiple components/elements.
$apply can be given as a function which receives element or an array of such functions.
const RedText = (el) => (el.style.color = "red");
// Function which can replace new HtmlString("<h1>Hello</h1>")
const HTMLContent = (data) => (el) => (el.innerHTML = data);
// Valid usages
div({ $apply: RedText });
div({ $apply: [RedText, HTMLContent("<h1>Hello</h1>")] } );Setting on-event actions
Event names are case sensitive. For each event use corresponding element’s attribute name.
a({ onclick: (e) => alert("Clicked!") }, "Click me");Setting CSS
CSS is given in the form of JSON object when using element’s style attribute or HTMLStyleElement when using HTML tag style.
// Global, using HTMLStyleElement
document.head.append(
style(
{},
`
body {
font-size: 12px;
}
`
)
);
// Inline, using style attribute
div({ style: { color: "red", fontSize: "12px" } }, "Hello World!");When setting style attribute values, use corresponding JavaScript CSS property names. See MDN.
Custom child appender
Version 2.0.0 introduced option to provide a custom way of how child element is appended to parent element.
Use case for this can be seen in HtmlString appender where raw html in the form of string needs to inserted to DOM element.
For this to happen, element’s insertAdjacentHTML method is used instead of default append method.
See how HtmlString appender is implemented in appenders.js.
Project’s NPM scripts
test - run tests
npm testcoverage - create and print test coverage report to console
npm run coveragecoverage:file - create and print test coverage report to test-coverage-report.txt file
npm run coverage:filebuild - build project
npm run build