At the moment, I add elements to the DOM with append with html inside of double quotes, this can become incredibly messy and very hard to read especially if you have variables inside of it, in React you would use JSX which is clean, is there a way to use JSX in an normal JQuery script or something like JSX?
Yes, two options:
Template literals
JSX
In modern JavaScript, you can use template literals rather than string literals, and they can include placeholders with JavaScript expressions in them:
let counter = 0;
$(`<table class="main">
<tbody>
<tr>
<td>Cell ${counter++}</td>
<td>Cell ${counter++}</td>
</tr>
<tr>
<td>Cell ${counter++}</td>
<td>Cell ${counter++}</td>
</tr>
</tbody>
</table>`).appendTo(document.body);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
There's still some awkwardness, definitely, but it's a lot better than string literals.
More on template literals on MDN.
JSX is not limited to React. It has its own specification and multiple implementations, such as jsx-transform
.
For instance, here's a simple Node.js wrapper that uses it to transpile a file:
var jsx = require('jsx-transform');
console.log(jsx.fromFile("input.jsx", {
factory: 'be'
}));
If input.jsx
were:
let counter = 0;
let table =
<table class="main">
<tbody>
<tr>
<td>Cell {counter++}</td>
<td>Cell {counter++}</td>
</tr>
<tr>
<td>Cell {counter++}</td>
<td>Cell {counter++}</td>
</tr>
</tbody>
</table>;
table.appendTo(document.body);
(Note that that's class="main"
, not className="main"
. Using className
instead is a React thing, to avoid an issue that hasn't been a problem since ES5 came out in 2009.)
The output would be:
let counter = 0;
let table =
be('table', {class: "main"}, [
be('tbody', null, [
be('tr', null, [
be('td', null, ["Cell ", counter++]),
be('td', null, ["Cell ", counter++])
]),
be('tr', null, [
be('td', null, ["Cell ", counter++]),
be('td', null, ["Cell ", counter++])
])
])
]);
table.appendTo(document.body);
Notice how the JSX expressions have been converted into calls to the factory function (be
in that example; React's factory function is React.createElement
). All you have to do is supply the be
function and integrate the transformer into your build chain (jsx-transform
comes prebaked with the ability to plug into Browserify).
Your be
using jQuery might look something like this:
function be(tagName, attributes, children) {
const result = $("<" + tagName + "/>");
if (attributes) {
result.attr(attributes);
}
if (children) {
if (Array.isArray(children)) {
for (const child of children) {
result.append(child);
}
} else {
result.append(child);
}
}
return result;
}
Live Example of the be function using the transformed result:
let counter = 0;
let table =
be('table', {class: "main"}, [
be('tbody', null, [
be('tr', null, [
be('td', null, ["Cell ", counter++]),
be('td', null, ["Cell ", counter++])
]),
be('tr', null, [
be('td', null, ["Cell ", counter++]),
be('td', null, ["Cell ", counter++])
])
])
]);
table.appendTo(document.body);
function be(tagName, attributes, children) {
const result = $("<" + tagName + "/>");
if (attributes) {
result.attr(attributes);
}
if (children) {
if (Array.isArray(children)) {
for (const child of children) {
result.append(child);
}
} else {
result.append(child);
}
}
return result;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Surprisingly, it really is about that simple.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With