programing

기본 제공 DOM 메서드 또는 프로토타입을 사용하여 HTML 문자열에서 새 DOM 요소 만들기

shortcode 2022. 12. 24. 21:15
반응형

기본 제공 DOM 메서드 또는 프로토타입을 사용하여 HTML 문자열에서 새 DOM 요소 만들기

.HTML 문자열은 다음과 같습니다.'<li>text</li>'의 요소(DOM)에ul방법으로 ?프로토타입 또는 DOM 방법으로 이 작업을 수행하려면 어떻게 해야 합니까?

(jQuery에서는 쉽게 할 수 있지만 안타깝게도 jQuery는 사용하지 않습니다.)

주의: 최신 브라우저는 대부분 HTML을 지원합니다.<template>요소: 문자열에서 생성 요소를 전환하는 보다 안정적인 방법을 제공합니다.자세한 내용은 아래 Mark Amery의 답변을 참조하십시오.

오래된 브라우저 및 노드/jsdom의 경우: (아직 지원하지 않음)<template>작성 시 요소)는 다음 방법을 사용합니다.라이브러리가 HTML 문자열에서 DOM 요소를 가져오기 위해 사용하는 것과 동일합니다(IE가 구현한 버그에 대처하기 위한 추가 작업 있음).innerHTML

function createElementFromHTML(htmlString) {
  var div = document.createElement('div');
  div.innerHTML = htmlString.trim();

  // Change this to div.childNodes to support multiple top-level nodes.
  return div.firstChild;
}

HTML 템플릿과 달리 이 기능은 합법적으로 의 자녀일 수 없는 일부 요소에서는 작동하지 않습니다.<div> 「」, 「」등입니다.<td>s.

이미 라이브러리를 사용하고 있다면 HTML 문자열에서 요소를 만드는 라이브러리가 승인한 방법을 사용하는 것이 좋습니다.

  • 프로토타입에는 이 기능이 내장되어 있습니다.
  • jQuery는 및 메서드에 구현되어 있습니다.

는 HTML 5†를 했습니다.<template>이 목적으로 사용할 수 있는 요소(WhatWG 사양MDN 문서에서 설명)

A <template>요소는 스크립트에서 사용할 수 있는HTML의 fragment를 선언하기 위해 사용됩니다.이 요소는 템플릿의 내용에 대한 액세스를 제공하기 위해 유형 속성을 가진 로 DOM에 표시됩니다.즉, HTML 스트링을 DOM 요소로 변환하려면<template> 그 에 요, 그, 합니다.template의 ».content★★★★★★★★★★★★★★★★★★.

예:

/**
 * @param {String} HTML representing a single element
 * @return {Element}
 */
function htmlToElement(html) {
    var template = document.createElement('template');
    html = html.trim(); // Never return a text node of whitespace as the result
    template.innerHTML = html;
    return template.content.firstChild;
}

var td = htmlToElement('<td>foo</td>'),
    div = htmlToElement('<div><span>nested</span> <span>stuff</span></div>');

/**
 * @param {String} HTML representing any number of sibling elements
 * @return {NodeList} 
 */
function htmlToElements(html) {
    var template = document.createElement('template');
    template.innerHTML = html;
    return template.content.childNodes;
}

var rows = htmlToElements('<tr><td>foo</td></tr><tr><td>bar</td></tr>');

같이 다른 컨테이너 요소를 사용하는 유사한 접근 방식은 제대로 작동하지 않습니다.HTML은 어떤 요소 유형이 다른 요소 유형 내에 존재할 수 있는지에 대한 제한이 있습니다. 예를 들어, 어떤 요소 유형을 포함할 수 없습니다.td divinnerHTMLdiv억제할 수 있습니다.★★<template>에는 내용에 대한 제한이 없습니다.템플릿을 사용할 때는 이 단점이 적용되지 않습니다.

★★★★★★★★★★★★★★.template는 일부 오래된 브라우저에서는 지원되지 않습니다.2021년 4월 현재 사용 가능...세계 사용자의 96%가 를 지원하는 브라우저를 사용하고 있는 것으로 추정됩니다.특히 Internet Explorer 버전은 지원되지 않습니다.Microsoft는 이 버전을 구현하지 않았습니다.template엣지가 출시될 때까지 지원합니다.

최신 브라우저에서만 사용자를 대상으로 하는 코드를 작성할 수 있다면 지금 바로 사용하세요.그렇지 않으면 사용자가 따라잡을 때까지 잠시 기다려야 할 수 있습니다.

insertAdjacent 사용HTML()은 IE11에서도 현재 모든 브라우저에서 작동합니다.

var mylist = document.getElementById('mylist');
mylist.insertAdjacentHTML('beforeend', '<li>third</li>');
<ul id="mylist">
 <li>first</li>
 <li>second</li>
</ul>

변경할 필요가 없습니다.네이티브 API가 준비되어 있습니다.

const toNodes = html =>
    new DOMParser().parseFromString(html, 'text/html').body.childNodes[0]

('html fragment' 등)<td>test</td>, div.disp.disp.gl및 range가 없는 ) 은 HTML, DOMParser.parseFromString의 range.createContextualFragment(「」)는 되지 않습니다<td>★★★★★★ 。

jQuery.parseHTML()은 적절하게 처리합니다(jQuery 2의 해석을 추출했습니다).HTML 함수는 비jquery 코드베이스에서 사용할 수 있는 독립된 함수로 변환됩니다).

Edge 13+만 지원하는 경우 HTML5 템플릿태그만 사용하는 것이 더 간단합니다.

function parseHTML(html) {
    var t = document.createElement('template');
    t.innerHTML = html;
    return t.content;
}

var documentFragment = parseHTML('<td>Test</td>');

새로운 DOM 실장에서는, 프레임워크에 의존하지 않는 방법으로 필요한 것을 실행할 수 있습니다.

그것은 널리 지지를 받고 있다.단, 변경 시 동일한 MDN 링크로 호환성을 체크합니다.2017년 5월 현재 다음과 같습니다.

Feature         Chrome   Edge   Firefox(Gecko)  Internet Explorer   Opera   Safari
Basic support   (Yes)    (Yes)  (Yes)           11                  15.0    9.1.2

간단한 방법은 다음과 같습니다.

String.prototype.toDOM=function(){
  var d=document
     ,i
     ,a=d.createElement("div")
     ,b=d.createDocumentFragment();
  a.innerHTML=this;
  while(i=a.firstChild)b.appendChild(i);
  return b;
};

var foo="<img src='//placekitten.com/100/100'>foo<i>bar</i>".toDOM();
document.body.appendChild(foo);

다음 명령을 사용하여 문자열에서 유효한 DOM 노드를 생성할 수 있습니다.

document.createRange().createContextualFragment()

다음 예제에서는 문자열에서 마크업을 가져오는 페이지에 버튼 요소를 추가하는 방법을 보여 줍니다.

let html = '<button type="button">Click Me!</button>';
let fragmentFromString = function (strHTML) {
  return document.createRange().createContextualFragment(strHTML);
}
let fragment = fragmentFromString(html);
document.body.appendChild(fragment);

IE9만, .<td>" " " 타타효: 。

function stringToEl(string) {
    var parser = new DOMParser(),
        content = 'text/html',
        DOM = parser.parseFromString(string, content);

    // return element
    return DOM.body.childNodes[0];
}

stringToEl('<li>text</li>'); //OUTPUT: <li>text</li>

왜 네이티브 js로 하지 않지?

    var s="<span class='text-muted' style='font-size:.75em; position:absolute; bottom:3px; left:30px'>From <strong>Dan's Tools</strong></span>"
    var e=document.createElement('div')
    var r=document.createRange();
    r.selectNodeContents(e)
    var f=r.createContextualFragment(s);
    e.appendChild(f);
    e = e.firstElementChild;

가 a a a를 .Document문자열에서 요소를 생성하는 프로토타입:

Document.prototype.createElementFromString = function (str) {
   const element = new DOMParser().parseFromString(str, 'text/html');
   const child = element.documentElement.querySelector('body').firstChild;
   return child;
};

사용방법:

document.createElementFromString("<h1>Hello World!</h1>");

다른 장소에서 찾을 수 있는 유용한 .toDOM() 스니펫을 더욱 강화하기 위해 backticks(템플릿 리터럴)를 안전하게 사용할 수 있게 되었습니다.

따라서 foo html 선언에는 단일 따옴표와 이중 따옴표를 사용할 수 있습니다.

이것은 이 용어에 익숙한 사람들에게는 유전처럼 행동한다.

이 기능은 변수를 사용하여 더욱 강화되어 복잡한 템플리트를 만들 수 있습니다.

템플릿 리터럴은 이중 따옴표 또는 단일 따옴표 대신 백체크(')(심각한 액센트) 문자로 둘러싸여 있습니다.템플릿 리터럴에는 자리 표시자가 포함될 수 있습니다.이러한 값은 달러 기호와 물결 괄호(${expression})로 표시됩니다.자리 표시자의 표현식과 그 사이의 텍스트가 함수로 전달됩니다.기본 함수는 부품을 하나의 문자열로 연결하기만 하면 됩니다.템플릿 리터럴 앞에 표현식(여기서는 태그 지정)이 있는 경우 이를 "태그 지정 템플릿"이라고 합니다.이 경우 태그 표현식(통상은 함수)은 처리된 템플릿리터럴을 사용하여 호출되며 출력 전에 이를 조작할 수 있습니다.템플릿 리터럴의 백틱을 회피하려면 백 체크 앞에 백슬래시 \를 붙입니다.

String.prototype.toDOM=function(){
  var d=document,i
     ,a=d.createElement("div")
     ,b=d.createDocumentFragment()
  a.innerHTML = this
  while(i=a.firstChild)b.appendChild(i)
  return b
}

// Using template literals
var a = 10, b = 5
var foo=`
<img 
  onclick="alert('The future starts today!')"   
  src='//placekitten.com/100/100'>
foo${a + b}
  <i>bar</i>
    <hr>`.toDOM();
document.body.appendChild(foo);
img {cursor: crosshair}

직접 건 어떨까요?.innerHTML += 이렇게 하면 브라우저에 의해 전체 DOM이 재계산되므로 속도가 훨씬 느려집니다.

https://caniuse.com/template-literals

정답.

  • 작성하다Template
  • 를 합니다.Template's을 너 HTML †string .trim()
  • 작성하다ArrayTemplate's 보호소
  • children,child , 「」

function toElement(s='',c,t=document.createElement('template'),l='length'){
t.innerHTML=s.trim();c=[...t.content.childNodes];return c[l]>1?c:c[0]||'';}



console.log(toElement());
console.log(toElement(''));
console.log(toElement('    '));
console.log(toElement('<td>With td</td>'));
console.log(toElement('<tr><td>With t</td></tr>'));
console.log(toElement('<tr><td>foo</td></tr><tr><td>bar</td></tr>'));
console.log(toElement('<div><span>nested</span> <span>stuff</span></div>'));

프로토타입을 사용하는 방법은 다음과 같습니다.JS(12년 전 OP가 원래 요청한 대로):

HTML:

<ul id="mylist"></ul>

JS:

$('mylist').insert('<li>text</li>');

이것은 jQuery가 아닙니다!

HTML5 및 ES6

<template>

데모

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @description HTML5 Template
 * @augments
 * @example
 *
 */

/*

<template>
    <h2>Flower</h2>
    <img src="https://www.w3schools.com/tags/img_white_flower.jpg">
</template>


<template>
    <div class="myClass">I like: </div>
</template>

*/

const showContent = () => {
    // let temp = document.getElementsByTagName("template")[0],
    let temp = document.querySelector(`[data-tempalte="tempalte-img"]`),
        clone = temp.content.cloneNode(true);
    document.body.appendChild(clone);
};

const templateGenerator = (datas = [], debug = false) => {
    let result = ``;
    // let temp = document.getElementsByTagName("template")[1],
    let temp = document.querySelector(`[data-tempalte="tempalte-links"]`),
        item = temp.content.querySelector("div");
    for (let i = 0; i < datas.length; i++) {
        let a = document.importNode(item, true);
        a.textContent += datas[i];
        document.body.appendChild(a);
    }
    return result;
};

const arr = ["Audi", "BMW", "Ford", "Honda", "Jaguar", "Nissan"];

if (document.createElement("template").content) {
    console.log("YES! The browser supports the template element");
    templateGenerator(arr);
    setTimeout(() => {
        showContent();
    }, 0);
} else {
    console.error("No! The browser does not support the template element");
}
@charset "UTf-8";

/* test.css */

:root {
    --cololr: #000;
    --default-cololr: #fff;
    --new-cololr: #0f0;
}

[data-class="links"] {
    color: white;
    background-color: DodgerBlue;
    padding: 20px;
    text-align: center;
    margin: 10px;
}
<!DOCTYPE html>
<html lang="zh-Hans">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Template Test</title>
    <!--[if lt IE 9]>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
    <![endif]-->
</head>

<body>
    <section>
        <h1>Template Test</h1>
    </section>
    <template data-tempalte="tempalte-img">
        <h3>Flower Image</h3>
        <img src="https://www.w3schools.com/tags/img_white_flower.jpg">
    </template>
    <template data-tempalte="tempalte-links">
        <h3>links</h3>
        <div data-class="links">I like: </div>
    </template>
    <!-- js -->
</body>

</html>

내 코드는 다음과 같습니다.

function parseTableHtml(s) { // s is string
    var div = document.createElement('table');
    div.innerHTML = s;

    var tr = div.getElementsByTagName('tr');
    // ...
}

늦었지만 메모로.

Target 요소에 Target 요소를 컨테이너로 추가하고 사용 후 제거할 수 있습니다.

// Chrome 23.0, Firefox 18.0, 즉 7-8-9 및 Opera 12.11에서 테스트 완료.

<div id="div"></div>

<script>
window.onload = function() {
    var foo, targetElement = document.getElementById('div')
    foo = document.createElement('foo')
    foo.innerHTML = '<a href="#" target="_self">Text of A 1.</a> '+
                    '<a href="#" onclick="return !!alert(this.innerHTML)">Text of <b>A 2</b>.</a> '+
                    '<hr size="1" />'
    // Append 'foo' element to target element
    targetElement.appendChild(foo)

    // Add event
    foo.firstChild.onclick = function() { return !!alert(this.target) }

    while (foo.firstChild) {
        // Also removes child nodes from 'foo'
        targetElement.insertBefore(foo.firstChild, foo)
    }
    // Remove 'foo' element from target element
    targetElement.removeChild(foo)
}
</script>

문자열에서 DOM을 렌더링하는 가장 빠른 솔루션:

let render = (relEl, tpl, parse = true) => {
  if (!relEl) return;
  const range = document.createRange();
  range.selectNode(relEl);
  const child = range.createContextualFragment(tpl);
  return parse ? relEl.appendChild(child) : {relEl, el};
};

여기서 DOM 조작 성능을 확인할 수 있습니다.반응과 네이티브 JS를 비교합니다.

이제 간단하게 다음을 사용할 수 있습니다.

let element = render(document.body, `
<div style="font-size:120%;line-height:140%">
  <p class="bold">New DOM</p>
</div>
`);

물론 가까운 장래에 메모리로부터의 참조를 사용하는 것은, 문서내에 새롭게 작성된 DOM 이 됩니다.

그리고 "내면의"를 기억하라.HTML="가 매우 느립니다:/

이런저런 이유로 복잡하지만 간단한 방법을 생각해냈는데...어쩌면 누군가 유용한 걸 찾을지도 몰라

/*Creates a new element - By Jamin Szczesny*/
function _new(args){
    ele = document.createElement(args.node);
    delete args.node;
    for(x in args){ 
        if(typeof ele[x]==='string'){
            ele[x] = args[x];
        }else{
            ele.setAttribute(x, args[x]);
        }
    }
    return ele;
}

/*You would 'simply' use it like this*/

$('body')[0].appendChild(_new({
    node:'div',
    id:'my-div',
    style:'position:absolute; left:100px; top:100px;'+
          'width:100px; height:100px; border:2px solid red;'+
          'cursor:pointer; background-color:HoneyDew',
    innerHTML:'My newly created div element!',
    value:'for example only',
    onclick:"alert('yay')"
}));

제가 직접 많이 찾아봤는데 깔끔한 해결책을 발견했어요.

const stringToHTML = (str) => {
    var parser = new DOMParser();
    var doc = parser.parseFromString(str, 'text/html');
    return doc.body;
};

변환할 문자열:

'<iframe src="https://player.vimeo.com/video/578680903?h=ea840f9223&amp;app_id=122963" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen title="Total Body Balance"></iframe>'

그 결과:

<body><iframe src="https://player.vimeo.com/video/578680903?h=ea840f9223&amp;app_id=122963" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen="" title="Total Body Balance"></iframe></body>

솔루션 - IE 4.0 이후 모든 브라우저에서 작동

var htmlString = `<body><header class="text-1">Hello World</header><div id="table"><!--TABLE HERE--></div></body>`;
var tableString = `<table class="table"><thead><tr><th>th cell</th></tr></thead><tbody><tr><td>td cell</td></tr></tbody></table>`;


var doc = document.implementation.createHTMLDocument();
    doc.open();
    doc.write(htmlString);
    doc.getElementById('table').insertAdjacentHTML('beforeend', tableString);
    doc.close();

console.log(doc);

또는 DOMParser를 사용할 수 있습니다.

var doc = (new DOMParser).parseFromString(htmlString, "text/html");
    doc.getElementById('table').insertAdjacentHTML('beforeend', tableString);

console.log(doc);

나는 ( Converting HTML string into DOM elements? )이 기사에서 링크했다.

저는 문자열을 HTML 요소로 변환하는 방법을 찾고 싶습니다.이러한 요구가 있는 경우는, 다음을 시험해 주세요.

const frag = document.createRange().createContextualFragment(
`<a href="/link.js">js</a> 
 <a>go</a>
`
) 
const aCollection = frag.querySelectorAll("a")
for (let [key, a] of Object.entries(aCollection)) {
  console.log(a.getAttribute("href"), a.textContent)
}

최신 JS의 예:

<template id="woof-sd-feature-box">
<div class="woof-sd-feature-box" data-key="__KEY__" data-title="__TITLE__" data-data="__OPTIONS__">
    <h4>__TITLE__</h4>
    <div class="woof-sd-form-item-anchor">
        <img src="img/move.png" alt="">
    </div>
</div>

</template>

<script>
create(example_object) {
        let html = document.getElementById('woof-sd-feature-box').innerHTML;
        html = html.replaceAll('__KEY__', example_object.dataset.key);
        html = html.replaceAll('__TITLE__', example_object.dataset.title);
        html = html.replaceAll('__OPTIONS__', example_object.dataset.data);
        //convertion HTML to DOM element and prepending it into another element
        const dom = (new DOMParser()).parseFromString(html, "text/html");
        this.container.prepend(dom.querySelector('.woof-sd-feature-box'));
    }
</script>
function domify (str) {
  var el = document.createElement('div');
  el.innerHTML = str;

  var frag = document.createDocumentFragment();
  return frag.appendChild(el.removeChild(el.firstChild));
}

var str = "<div class='foo'>foo</div>";
domify(str);

https://www.codegrepper.com/code-examples/javascript/convert+a+string+to+html+element+in+js 를 참조해 주세요.

const stringToHtml = function (str) {
    var parser = new DOMParser();
    var doc = parser.parseFromString(str, 'text/html');
    return doc.body;
}

다음 함수를 사용하여 텍스트 "HTML"을 요소로 변환할 수 있습니다.

function htmlToElement(html)
{
  var element = document.createElement('div');
  element.innerHTML = html;
  return(element);
}
var html="<li>text and html</li>";
var e=htmlToElement(html);

여기 작업 코드가 있습니다.

'텍스트' 문자열을 HTML 요소로 변환하고 싶었다.

var diva = UWA.createElement('div');
diva.innerHTML = '<a href="http://wwww.example.com">Text</a>';
var aelement = diva.firstChild;

var msg = "test" jQuery.parseHTML(msg)

var jtag = $j.li({ child:'text' }); // Represents: <li>text</li>
var htmlContent = $('mylist').html();
$('mylist').html(htmlContent + jtag.html());

jnerator 사용

이것도 동작합니다.

$('<li>').text('hello').appendTo('#mylist');

연결된 함수 호출에서는 더 복잡한 방법처럼 느껴집니다.

언급URL : https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro

반응형