使用JQuery将HTML元素优雅地添加到DOM中

5

目前,我使用带有双引号的html附加元素到DOM中,这可能会变得非常混乱和难以阅读,特别是如果其中包含变量,在React中,您可以使用干净的JSX,是否有一种方法在普通的JQuery脚本中或类似JSX的东西中使用JSX?


你到目前为止尝试了什么?请分享一下。 - Bhushan Kawadkar
1
@bhushan kawadkar,目前还没有找到解决方案,除了使用混乱的HTML和变量字符串。 - Elliott Coe
@BhushanKawadkar 并不是所有没有代码的问题都是糟糕的。实际上,这是一个非常有趣的主题。如果还没有类似的插件,编写一个能够实现这个功能的jQuery插件可能会很有趣。 - Mark Baijens
当你使用API端点获取帖子对象时,这个问题非常恼人,然后你需要构建帖子而不是使用JQuery来将其附加到帖子容器中。 - Elliott Coe
1个回答

3

是的,有两个选项:

  1. 模板字面量

  2. JSX

模板字面量

在现代JavaScript中,您可以使用模板字面量而不是字符串字面量,并且它们可以包含带有JavaScript表达式的占位符:

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>

虽然还有一些尴尬的地方,但它比字符串字面量要好得多。

在MDN上了解更多关于模板字面量的信息。

JSX

JSX并不局限于React。 它有自己的规范和多个实现,例如jsx-transform

例如,这里是一个简单的Node.js包装器,使用它来转换文件:

var jsx = require('jsx-transform');

console.log(jsx.fromFile("input.jsx", {
  factory: 'be'
}));

如果 input.jsx 是这样的:
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);

(请注意,这里的类名应该是class="main"而不是className="main"。使用className是React的一个特性,旨在避免自从2009年ES5发布以来就不存在的问题。)

输出结果将如下:

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);

请注意,JSX表达式已转换为调用工厂函数(在该示例中是be;React的工厂函数是React.createElement)。您只需要提供be函数并将转换器集成到构建链中(jsx-transform预先内置了插入Browserify的功能)。
使用jQuery的be可能看起来像这样:
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;
}

使用转换后的结果的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);

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>

惊人的是,这确实就是那么简单。

模板字面量似乎是我前进的道路,但JSX实现看起来很有趣。谢谢! - Elliott Coe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接