[javascript] JQuery를 사용하여 추가 할 HTML 템플릿 정의

반복되는 배열이 있습니다. 조건이 참일 때마다 HTML일부 값이있는 컨테이너 요소에 아래 코드 사본을 추가하고 싶습니다 .

이 HTML을 현명하게 재사용 할 수있는 위치는 어디입니까?

<a href="#" class="list-group-item">
    <div class="image">
         <img src="" />
    </div>
    <p class="list-group-item-text"></p>
</a>

JQuery

$('.search').keyup(function() {
    $('.list-items').html(null);

    $.each(items, function(index) {
        // APPENDING CODE HERE
    });
});



답변

프로젝트에서 다음과 같은 템플릿 엔진을 사용하도록 결정할 수 있습니다.

다른 라이브러리를 포함하지 않으려는 경우 John Resig는 아래와 유사한 jQuery 솔루션을 제공 합니다.


브라우저와 화면 판독기는 인식 할 수없는 스크립트 유형을 무시합니다.

<script id="hidden-template" type="text/x-custom-template">
    <tr>
        <td>Foo</td>
        <td>Bar</td>
    <tr>
</script>

jQuery를 사용하여 템플릿을 기반으로 행을 추가하는 것은 다음과 같습니다.

var template = $('#hidden-template').html();

$('button.addRow').click(function() {
    $('#targetTable').append(template);
});


답변

오래된 질문이지만 “jQuery 사용”이라는 질문이 있기 때문에 공급 업체 종속성을 도입하지 않고도이 작업을 수행 할 수있는 옵션을 제공 할 것이라고 생각했습니다.

많은 템플릿 엔진이 있지만 최근에는 반복 ( <% for), 조건부 ( <% if) 및 변환 ( <%= myString | uppercase %>)이 기껏해야 마이크로 언어로 간주되고, 최악의 경우 안티 패턴으로 간주되는 등 여러 기능이 최근에 불리 해졌습니다. 현대의 템플릿 관행은 단순히 객체를 DOM (또는 기타) 표현에 매핑하도록 장려합니다. 예를 들어 ReactJS의 구성 요소 (특히 상태 비 저장 구성 요소)에 매핑 된 속성으로 보는 것.

HTML 내부 템플릿

당신이 당신의 HTML의 나머지 옆에 템플릿의 HTML을 유지하기 위해 의존 수있는 한 속성은 비 실행 사용하는 것 <script> type, 예 <script type="text/template">. 귀하의 경우 :

<script type="text/template" data-template="listitem">
    <a href="${url}" class="list-group-item">
        <table>
            <tr>
                <td><img src="${img}"></td>
                <td><p class="list-group-item-text">${title}</p></td>
            </tr>
        </table>
    </a>
</script>

문서로드시 템플릿을 읽고 간단한 방법으로 토큰 화합니다. String#split

var itemTpl = $('script[data-template="listitem"]').text().split(/\$\{(.+?)\}/g);

토큰을 사용하면 교대 [text, property, text, property]형식으로 얻을 수 있습니다 . 이렇게하면 Array#map매핑 함수와 함께를 사용하여 멋지게 매핑 할 수 있습니다 .

function render(props) {
  return function(tok, i) { return (i % 2) ? props[tok] : tok; };
}

어디 props처럼 보일 수 { url: 'http://foo.com', img: '/images/bar.png', title: 'Lorem Ipsum' }있습니다.

itemTpl위와 같이 구문 분석하고로드 items했으며 범위 내에 배열 이 있다고 가정하고 모두 합치면 됩니다.

$('.search').keyup(function () {
  $('.list-items').append(items.map(function (item) {
    return itemTpl.map(render(item)).join('');
  }));
});

이러한 접근 방식은 또한에만 겨우 jQuery를 – 당신은 바닐라 자바 스크립트를 사용하여 동일한 접근을 할 수 있어야 document.querySelector하고 .innerHTML.

jsfiddle

JS 내부 템플릿

스스로에게 물어볼 질문은 다음과 같습니다. 템플릿을 HTML 파일로 정의하고 싶습니까 / 필요합니까? 반복하려는 대부분의 항목을 재사용하는 것과 동일한 방식으로 템플릿을 구성 요소 화 및 재사용 할 수 있습니다. 함수를 사용하면됩니다.

es7-land에서는 destructuring, 템플릿 문자열 및 화살표 함수를 사용하여 $.fn.html위 의 방법을 사용하여 쉽게로드 할 수있는 매우보기 좋은 구성 요소 함수를 작성할 수 있습니다 .

const Item = ({ url, img, title }) => `
  <a href="${url}" class="list-group-item">
    <div class="image">
      <img src="${img}" />
    </div>
    <p class="list-group-item-text">${title}</p>
  </a>
`;

그런 다음 쉽게 렌더링 할 수 있으며 다음과 같이 배열에서 매핑 할 수도 있습니다.

$('.list-items').html([
  { url: '/foo', img: 'foo.png', title: 'Foo item' },
  { url: '/bar', img: 'bar.png', title: 'Bar item' },
].map(Item).join(''));

마지막 참고 사항 : DB에서 읽은 속성을 템플릿에 전달한 속성을 삭제하는 것을 잊지 마십시오. 그렇지 않으면 누군가 페이지에서 HTML을 전달할 수 있고 스크립트를 실행할 수 있습니다.


답변

대신 HTML 템플릿을 사용하십시오!

허용되는 답변은 스크립트 오버로딩 방법을 나타내므로 오버로드 스크립트와 함께 제공되는 XSS 위험으로 인해 훨씬 ​​깨끗하고 안전한 다른 방법을 제안하고 싶습니다.

액션에서 사용하는 방법과 한 템플릿을 다른 템플릿에 삽입하고 문서 DOM에 추가하는 방법을 보여주는 데모 를 만들었습니다 .

예제 html

<template id="mytemplate">
  <style>
     .image{
        width: 100%;
        height: auto;
     }
  </style>
  <a href="#" class="list-group-item">
    <div class="image">
      <img src="" />
    </div>
    <p class="list-group-item-text"></p>
  </a>
</template>

예 js

// select
var t = document.querySelector('#mytemplate');

// set
t.content.querySelector('img').src = 'demo.png';
t.content.querySelector('p').textContent= 'demo text';

// add to document DOM
var clone = document.importNode(t.content, true); // where true means deep copy
document.body.appendChild(clone);

HTML <템플릿>

  • + 그 내용은 활성화 될 때까지 효과적으로 비활성 상태입니다. 기본적으로 마크 업은 숨겨진 DOM이며 렌더링되지 않습니다.

  • + 템플릿 내의 모든 콘텐츠에는 부작용이 없습니다. 템플릿이 사용될 때까지 스크립트가 실행되지 않고 이미지가로드되지 않으며 오디오가 재생되지 않습니다.

  • + 콘텐츠는 문서에없는 것으로 간주됩니다. 사용 document.getElementById()하거나 querySelector()메인 페이지에 템플릿의 자식 노드를 반환하지 않습니다.

  • + 템플릿 내부의 어딘가에 배치 될 수있다 <head>, <body>또는 <frameset>그러한 소자에 허용되는 모든 유형의 콘텐츠를 포함 할 수있다. “anywhere” <template>는 HTML 파서가 허용하지 않는 위치에서 안전하게 사용할 수 있음을 의미합니다 .

폴백

브라우저 지원은 문제가되지 않지만 모든 가능성을 다루고 싶다면 쉽게 확인할 수 있습니다.

감지 기능을 <template>사용하려면 DOM 요소를 만들고 .content 속성이 있는지 확인하세요.

function supportsTemplate() {
  return 'content' in document.createElement('template');
}

if (supportsTemplate()) {
  // Good to go!
} else {
  // Use old templating techniques or libraries.
}

오버로딩 스크립트 방법에 대한 몇 가지 통찰력

  • + 아무것도 렌더링되지 않습니다- <script>태그가 display:none기본적으로 가지고 있기 때문에 브라우저는이 블록을 렌더링하지 않습니다 .
  • + Inert-브라우저가 스크립트 내용을 JS로 구문 분석하지 않습니다. 유형이 "text/javascript".
  • -보안 문제- .innerHTML. 사용자가 제공 한 데이터의 런타임 문자열 구문 분석은 쉽게 XSS 취약성을 유발할 수 있습니다.

전체 기사 : https://www.html5rocks.com/en/tutorials/webcomponents/template/#toc-old

유용한 참조 :
https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode
http://caniuse.com/#feat=queryselector

웹 구성 요소 만들기 Trawersy Media의 HTML 템플릿을 사용하여 사용자 정의 웹 구성 요소 만들기 자습서 :
https://youtu.be/PCWaFLy3VUo


답변

본문에 추가

<div class="hide">
<a href="#" class="list-group-item">
    <table>
        <tr>
            <td><img src=""></td>
            <td><p class="list-group-item-text"></p></td>
        </tr>
    </table>
</a>
</div>

그런 다음 CSS를 만듭니다.

.hide { display: none; }

js에 추가하십시오.

$('#output').append( $('.hide').html() );


답변

다른 대안 : 순수

나는 그것을 사용하고 그것은 나를 많이 도왔습니다. 웹 사이트에 표시된 예 :

HTML

<div class="who">
</div>

JSON

{
  "who": "Hello Wrrrld"
}

결과

<div class="who">
  Hello Wrrrld
</div>


답변

이 문제를 해결하기 위해 두 가지 해결책을 알고 있습니다.

  • 첫 번째는 AJAX와 함께 사용되며 다른 파일에서 템플릿을로드하고 .clone().

    $.get('url/to/template', function(data) {
        temp = data
        $('.search').keyup(function() {
            $('.list-items').html(null);
    
            $.each(items, function(index) {
                 $(this).append(temp.clone())
            });
    
        });
    });

    데이터를 사용할 수 있는지 확인하려면 ajax가 완료되면 이벤트를 추가해야합니다.

  • 두 번째는 원본 html의 아무 곳에 나 직접 추가하고 선택하여 jQuery에서 숨기는 것입니다.

    temp = $('.list_group_item').hide()

    다음을 사용하여 템플릿의 새 인스턴스를 추가 한 후

    $('.search').keyup(function() {
        $('.list-items').html(null);
    
        $.each(items, function(index) {
            $(this).append(temp.clone())
        });
    });
  • 이전의 것과 동일하지만 템플릿이 그대로 유지되는 것을 원하지 않지만 자바 스크립트에서만 .detach()숨기는 대신 사용할 수 있다고 생각합니다 (테스트하지 않았습니다!) .

    temp = $('.list_group_item').detach()

    .detach() 데이터와 이벤트를 유지하면서 DOM에서 요소를 제거합니다 (.remove ()는 그렇지 않습니다!).


답변

네이티브 HTML5 템플릿 요소 사용에 대한 DevWL의 매우 좋은 답변 입니다 . OP의이 좋은 질문에 기여하기 위해 다음과 같이 jQuery 를 사용하여이 요소 를 사용하는 방법을 추가하고 싶습니다 .template

$($('template').html()).insertAfter( $('#somewhere_else') );

의 내용은 templatehtml이 아니라 데이터로 취급되므로 내용을 jQuery 객체로 래핑 한 다음 jQuery의 메서드에 액세스해야합니다.