在没有 jQuery 的情况下使用 JavaScript 中的对象创建 html DOM 元素

发布于 2025-01-10 03:21:46 字数 1462 浏览 0 评论 0原文

我想知道是否有一种“简单”的方法通过指定 json 中的属性来创建大 DOM 对象?

我知道可以使用appendChild和/或innerHTML来做到这一点,但是对于这个有问题的对象,它看起来相当混乱。

目标是在 javascript 中从下往上创建这个 HTML 对象:

<div class="p-2">
    <div class="d-flex p-2 bg-dark2-35">
        <div class="Popover h-3">
            <div class="pfp" style="background-image: url('/data/images/PP/1.png')"></div>
        </div>
        <div class="d-grid ms-2 w-100">
            <p><b class="lead text-blue">Username</b> — <i>2020-01-16 19:29:34</i></p>
            <p class="text-white">some comment text</p>
        </div>
    </div>
</div>

我想知道是否可以做这样的事情(我知道它不起作用):

let comment = document.getElementById("comment-section");
let elm = {
    className: "p-2",
    appendChild(node) {
        classList.add("d-flex", "p-2", "bg-dark2-35"),
        appendChild(node2){
            classList.add("Popover", "h-3"),
            // ... and so on
        }
    }
}
comment.appendChild(elm);

有没有一种简单的方法可以在纯 JS 中做到这一点?我必须创建一个函数才能实现此目的吗?或者甚至可以导入一个库?

这个问题有点类似于 Create DOM element from Object in javascript ,但是当涉及到这么多孩子、孩子等等时,我完全迷失了

当谈到 JavaScript 时,我有点新手。这个问题可能会很奇怪

I'm wondering if there is an "easy" way to create a big DOM object by specifying the attributes in a json?

I know it's possible to do this with appendChild and/or innerHTML, but for this object in question, it looks quite messy.

The goal is to create this HTML object from the bottom up in javascript:

<div class="p-2">
    <div class="d-flex p-2 bg-dark2-35">
        <div class="Popover h-3">
            <div class="pfp" style="background-image: url('/data/images/PP/1.png')"></div>
        </div>
        <div class="d-grid ms-2 w-100">
            <p><b class="lead text-blue">Username</b> — <i>2020-01-16 19:29:34</i></p>
            <p class="text-white">some comment text</p>
        </div>
    </div>
</div>

I was wondering if it's possible to do something like this (I know it doesn't work):

let comment = document.getElementById("comment-section");
let elm = {
    className: "p-2",
    appendChild(node) {
        classList.add("d-flex", "p-2", "bg-dark2-35"),
        appendChild(node2){
            classList.add("Popover", "h-3"),
            // ... and so on
        }
    }
}
comment.appendChild(elm);

Is there an easy way to do this in pure JS? Would I have to make a function to achieve this? or maybe go as far as to import a library?

The question is a bit similar to Create DOM element from Object in javascript, but I'm completely lost when it comes to this many childrens, with childrens and so on

I'm a bit of a newbie when it comes to JavaScript. The question might come off as strange

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌化 2025-01-17 03:21:46

您可以使用模板文字Mdn 文档 - 模板文字

const selector = document.getElementById('comment-section');

// By using createElement you can deal with loops, event listener, etc..

const comment = document.createElement('div');
comment.classList.add("p-2");

const username = "TypeWar";

// Template literals

comment.innerHTML = `
  <div class="d-flex p-2 bg-dark2-35">
      <div class="Popover h-3">
          <div class="pfp" style="background-image: url('/data/images/PP/1.png')"></div>
      </div>
      <div class="d-grid ms-2 w-100">
          <p><b class="lead text-blue">${username}</b> — <i>2020-01-16 19:29:34</i></p>
          <p class="text-white">some comment text</p>
      </div>
  </div>
`;

selector.appendChild(comment);
<div id="comment-section">
</div>

You can use template literals Mdn docs - Template Literals

const selector = document.getElementById('comment-section');

// By using createElement you can deal with loops, event listener, etc..

const comment = document.createElement('div');
comment.classList.add("p-2");

const username = "TypeWar";

// Template literals

comment.innerHTML = `
  <div class="d-flex p-2 bg-dark2-35">
      <div class="Popover h-3">
          <div class="pfp" style="background-image: url('/data/images/PP/1.png')"></div>
      </div>
      <div class="d-grid ms-2 w-100">
          <p><b class="lead text-blue">${username}</b> — <i>2020-01-16 19:29:34</i></p>
          <p class="text-white">some comment text</p>
      </div>
  </div>
`;

selector.appendChild(comment);
<div id="comment-section">
</div>

笨死的猪 2025-01-17 03:21:46

回到这个问题,看看这个函数:

/**
 * A "fancier" function to make a HTML element
 * @param nodeName
 * @param elementOptions
 */
function createElement(nodeName, elementOptions) {
    if (!nodeName && !elementOptions) return;
    if (!nodeName) nodeName = elementOptions.nodeName;

    // Defining the new element
    let elm = document.createElement(nodeName);

    if(elementOptions?.href){
        elm.setAttribute("href", elementOptions.href); // Use setAttribute to set the href attribute
    }

    // Assign classes if defined
    if (elementOptions?.classList)
        for (let i = 0; i < elementOptions.classList.length; i++)
            if (elementOptions.classList[i] && elementOptions.classList[i]?.trim() !== "")
                elm.classList.add(elementOptions.classList[i]);

    // Assign id if defined
    if (elementOptions?.id) elm.id = elementOptions["id"];

    // Assign title if defined
    if (elementOptions?.title) elm.title = elementOptions["title"];

    // Assign tabIndex if defined
    if (elementOptions?.tabIndex) elm.tabIndex = elementOptions["tabIndex"];

    // Assign innerHTML if defined
    if (elementOptions?.innerHTML) elm.innerHTML = elementOptions["innerHTML"];

    // Assign style if defined
    if (elementOptions?.style) {
        Object.entries(elementOptions.style).forEach(([property, value]) => {
            elm.style[property] = value;
        });
    }

    if (elementOptions?.events) {
        for (const [eventName, eventListener] of Object.entries(elementOptions.events)) {
            if (eventName in elm) {
                elm.addEventListener(eventName, eventListener);
            }else{
                console.warn(`Invalid event name: ${eventName}`);
            }
        }
    }

    // Assign attributes if defined
    if (elementOptions?.attributes) {
        Object.entries(elementOptions.attributes).forEach(([property, value]) => {
            elm.setAttribute(property, value);
        });
    }

    // Lastly do recursion to create children
    if (elementOptions?.children){
        for (let i = 0; i < elementOptions.children.length; i++) {
            let child = createElement(null, elementOptions.children[i])
            if (child) elm.appendChild(child)
        }
    }

    return elm;
}

它可以像这样创建:

const myElm = createElement("DIV", {
    classList: ["p-2"],
    children: [{
        nodeName: "DIV",
        classList: ["d-flex", "p-2", "bg-dark2-35"],
        children: [
            {
                nodeName: "DIV",
                classList: ["Popover", "h-3"],
                children: [{
                    nodeName: "DIV",
                    classList: ["pfp"],
                    style: {
                        backgroundImage: "url('/data/images/PP/1.png')"
                    }
                }]
            },
            {
                nodeName: "DIV",
                classList: ["d-grid", "ms-2", "w-100"],
                children: [
                    {
                        nodeName: "P",
                        innerHTML: `<b class="lead text-blue">${username}</b> — <i>${timestamp}</i>`
                    },
                    {
                        nodeName: "P",
                        classList: ["text-white"],
                        innerHTML: "some comment text"
                    }
                ]
            }
        ]
    }]
})

总的来说,与 React 可以实现或仅使用模板文字相比,这有点混乱。

Coming back to this question, check out this function:

/**
 * A "fancier" function to make a HTML element
 * @param nodeName
 * @param elementOptions
 */
function createElement(nodeName, elementOptions) {
    if (!nodeName && !elementOptions) return;
    if (!nodeName) nodeName = elementOptions.nodeName;

    // Defining the new element
    let elm = document.createElement(nodeName);

    if(elementOptions?.href){
        elm.setAttribute("href", elementOptions.href); // Use setAttribute to set the href attribute
    }

    // Assign classes if defined
    if (elementOptions?.classList)
        for (let i = 0; i < elementOptions.classList.length; i++)
            if (elementOptions.classList[i] && elementOptions.classList[i]?.trim() !== "")
                elm.classList.add(elementOptions.classList[i]);

    // Assign id if defined
    if (elementOptions?.id) elm.id = elementOptions["id"];

    // Assign title if defined
    if (elementOptions?.title) elm.title = elementOptions["title"];

    // Assign tabIndex if defined
    if (elementOptions?.tabIndex) elm.tabIndex = elementOptions["tabIndex"];

    // Assign innerHTML if defined
    if (elementOptions?.innerHTML) elm.innerHTML = elementOptions["innerHTML"];

    // Assign style if defined
    if (elementOptions?.style) {
        Object.entries(elementOptions.style).forEach(([property, value]) => {
            elm.style[property] = value;
        });
    }

    if (elementOptions?.events) {
        for (const [eventName, eventListener] of Object.entries(elementOptions.events)) {
            if (eventName in elm) {
                elm.addEventListener(eventName, eventListener);
            }else{
                console.warn(`Invalid event name: ${eventName}`);
            }
        }
    }

    // Assign attributes if defined
    if (elementOptions?.attributes) {
        Object.entries(elementOptions.attributes).forEach(([property, value]) => {
            elm.setAttribute(property, value);
        });
    }

    // Lastly do recursion to create children
    if (elementOptions?.children){
        for (let i = 0; i < elementOptions.children.length; i++) {
            let child = createElement(null, elementOptions.children[i])
            if (child) elm.appendChild(child)
        }
    }

    return elm;
}

And it can be created like so:

const myElm = createElement("DIV", {
    classList: ["p-2"],
    children: [{
        nodeName: "DIV",
        classList: ["d-flex", "p-2", "bg-dark2-35"],
        children: [
            {
                nodeName: "DIV",
                classList: ["Popover", "h-3"],
                children: [{
                    nodeName: "DIV",
                    classList: ["pfp"],
                    style: {
                        backgroundImage: "url('/data/images/PP/1.png')"
                    }
                }]
            },
            {
                nodeName: "DIV",
                classList: ["d-grid", "ms-2", "w-100"],
                children: [
                    {
                        nodeName: "P",
                        innerHTML: `<b class="lead text-blue">${username}</b> — <i>${timestamp}</i>`
                    },
                    {
                        nodeName: "P",
                        classList: ["text-white"],
                        innerHTML: "some comment text"
                    }
                ]
            }
        ]
    }]
})

Overall this is a bit messy compared to something that React can achieve or just using template literals.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文