JQuery का उपयोग करने के लिए HTML टेम्पलेट को परिभाषित करना


125

मुझे एक सरणी मिली है जिसके माध्यम से मैं लूप कर रहा हूं। हर बार एक शर्त सही होने पर, मैं 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
    });
});

2
यदि आप एक स्मार्ट तरीके की तलाश कर रहे हैं, तो अपनी सभी जानकारी को एक ही DIV में डालें और इसे स्टाइल करें। केवल दो कोशिकाओं के साथ कई तालिकाओं का निर्माण न करें, उन्हें लंगर में न लपेटें।
सेर्गेई स्नेग्रीव

3
ओपी स्पष्ट रूप से उचित कोडिंग प्रथाओं (कुडोस!) में रुचि रखते हैं, इसलिए मैं मदद करना चाहता था। अगर मैं वास्तविक समस्या में योगदान करना चाहता था, तो मैं एक उत्तर पोस्ट करता। मुझे यकीन है कि कोई भी इस बात से सहमत है कि एक छवि की स्थिति के लिए पूर्ण-विकसित दो-कक्ष तालिका का उपयोग करना और कुछ पाठ को वास्तव में विदेशी आवश्यकताओं (IE4?) के अलावा कुछ हद तक उचित ठहराया जाता है
सर्गेई स्नेग्रीव

1
@BrianG। एक टिप्पणी पोस्टिंग वास्तव में मतलब नहीं है कि आप एक स्पर्शरेखा पर जा रहे हैं। हालांकि मैं मानता हूं कि टिप्पणियाँ उन लोगों के लिए एक उपयुक्त स्थान हैं (जब तक वे अभी भी प्रासंगिक हैं), वे उन लोगों द्वारा ड्राइव-बाय संकेत के लिए भी उपयुक्त हैं जिनके पास अभी तक एक उत्तर में विस्तार करने का समय नहीं है। यह ओपी के लिए यह स्पष्ट करने में मददगार है कि आप क्या कर रहे हैं।
14

किसी ने आपके सवाल का जवाब नहीं दिया, पैट्रिक?
सेबेस्टियन नीरा

जवाबों:


164

आप अपनी परियोजना में एक अस्थायी इंजन का उपयोग करने का निर्णय ले सकते हैं, जैसे:

यदि आप किसी अन्य पुस्तकालय को शामिल नहीं करना चाहते हैं, तो जॉन रेजिग एक 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);
});

@MaksimLuzik सही है। मूंछें (ट्रेडमार्क वर्तनी पर ध्यान दें) हल्का-वजन है और ओपी कोड में प्लग करेगा, लेकिन हैंडलबार्स में सरणियों को संभालने के लिए अधिक विशेषताएं हैं, और अंत में अधिक पर्याप्त समाधान प्रदान कर सकता है। यहाँ एक अच्छा तुलनात्मक लेख है: blog.cubettech.com/…
माइकल शेपर

13
यहाँ टेम्प्लेट संपादित करने का उदाहरण: jsfiddle.net/meehanman/7vw8bc84
डीन मीहान

175

पुराना प्रश्न है, लेकिन चूंकि प्रश्न "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

जेएस के अंदर टेम्पलेट

अपने आप से पूछने के लिए एक प्रश्न है: क्या आप वास्तव में HTML फ़ाइलों के रूप में टेम्पलेट्स को परिभाषित करना चाहते हैं / चाहते हैं? आप एक टेम्पलेट को हमेशा उसी तरह से पुन: उपयोग कर सकते हैं, जिस तरह से आप उन सभी चीजों का फिर से उपयोग करेंगे, जिन्हें आप दोहराना चाहते हैं: एक फ़ंक्शन के साथ।

Es7- भूमि में, विनाशकारी, टेम्पलेट स्ट्रिंग्स और एरो-फ़ंक्शंस का उपयोग करके, आप सीधे सुंदर दिखने वाले घटक फ़ंक्शंस लिख सकते हैं जिन्हें आसानी से $.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 (और फिर स्क्रिप्ट आदि) चला सकते हैं, तो किसी टेम्पलेट को दिए गए अपने गुणों को स्पष्ट करना न भूलें।


1
अच्छा टेम्पलेट इंजन।
आर्थर कास्त्रो

40
JS सेक्शन के अंदर आपका टेम्प्लेट बम है
BigRon

2
क्या आप "टेम्प्लेट इनसाइड HTML" अप्रोच के लिए डेमो / फिडल जोड़ सकते हैं?
LCJ

1
वाह! JS के अंदर टेम्पलेट ... ऐसा कभी नहीं सोचा था! गजब का!
रोमन लोपेज़

2
वाह, यह वास्तव में बहुत अच्छा है। मैं प्रत्येक टेम्पलेट में एक डेटा-url विशेषता जोड़ रहा हूं। और प्रत्येक के लिए ajax डेटा प्राप्त करना। यह बहुत अच्छा है और मुझे इतना समय बचा लिया है! धन्यवाद।
डेवी

42

इसके बजाय HTML टेम्पलेट का उपयोग करें!

चूंकि स्वीकृत उत्तर ओवरलोडिंग स्क्रिप्ट विधि का प्रतिनिधित्व करेगा, इसलिए मैं एक और सुझाव देना चाहूंगा जो कि मेरी राय में, XSS जोखिमों के कारण बहुत अधिक क्लीनर और अधिक सुरक्षित है जो ओवरलोडिंग स्क्रिप्ट के साथ आते हैं।

मैंने आपको यह दिखाने के लिए एक डेमो बनाया कि इसे एक क्रिया में कैसे उपयोग किया जाए और एक टेम्पलेट को दूसरे में कैसे इंजेक्ट किया जाए, संपादित करें और फिर दस्तावेज़ डोम में जोड़ें।

उदाहरण 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>

उदाहरण जे.एस.

// 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>और सामग्री है जो उन तत्वों में अनुमति दी है की किसी भी प्रकार के हो सकते हैं। ध्यान दें कि "कहीं भी" का अर्थ है कि <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 डिफ़ॉल्ट रूप से है।
  • + निष्क्रिय - ब्राउज़र जेएस के रूप में स्क्रिप्ट सामग्री को पार्स नहीं करता है क्योंकि इसका प्रकार इसके अलावा किसी अन्य चीज़ के लिए सेट है "text/javascript"
  • -सुरक्षा मुद्दे - के उपयोग को प्रोत्साहित करता है .innerHTML। उपयोगकर्ता-प्रदत्त डेटा की रन-टाइम स्ट्रिंग पार्सिंग आसानी से XSS कमजोरियों को जन्म दे सकती है।

पूरा लेख: https://www.html5rocks.com/en/tutorials/webcompenders/template/#toc-old

उपयोगी संदर्भ: https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode http://caniuse.com/#feat=queryselector

WEB घटक बनाने के लिए ट्रॉवर्स मीडिया द्वारा HTML टेम्प्लेट का उपयोग करके कस्टम वेब घटक ट्यूटोरियल बनाना: https://youtu.be/PCWaFLy3VUo


4
templateतत्व इंटरनेट एक्सप्लोरर (2018 के रूप में, IE11) द्वारा समर्थित नहीं है। W3c.github.io/html/single-page.html के उदाहरण 580 के साथ परीक्षण किया गया ।
रोलैंड

मुझे पसंद है <template>, हालांकि मैं उदारतापूर्वक कक्षाओं का उपयोग करने की सलाह दूंगा, इसलिए यह स्पष्ट है कि क्या क्या हो रहा है। यह अभी भी आपके डेटा को ठीक से टेम्पलेट में मैप करने के लिए कुछ js कौशल लेता है, विशेष रूप से डेटा के बड़े सेट में मैपिंग के लिए एक घटक-शैली दृष्टिकोण का उपयोग कर रहा है। व्यक्तिगत रूप से मुझे अभी भी केवल फ़ंक्शन में HTML का निर्माण करना पसंद है, या आदर्श रूप से डोम को सीधे जेएस के साथ ही निर्माण करना और HTML को पूरी तरह से समाप्त करना (जैसे कि यह कैसे प्रतिक्रिया करता है)।
Qaribou

टेम्पलेट दृष्टिकोण ने मेरे लिए अच्छा काम किया। मेरे पास एक सिफारिश यह है कि पहले टेम्पलेट को क्लोन करें (बजाय अंत में) और क्लोन किए गए ऑब्जेक्ट के साथ काम करें। अन्यथा, आपके द्वारा किए जा रहे परिवर्तन टेम्पलेट के लिए ही हो रहे हैं। यदि आपके पास सशर्त तर्क है जहां आप कुछ समय के लिए कुछ गुण / सामग्री सेट करते हैं, तो वे गुण आपके अगले टेम्पलेट के उपयोग में मौजूद होंगे। प्रत्येक उपयोग से पहले क्लोनिंग करके, आप यह सुनिश्चित करते हैं कि आपके पास काम करने के लिए हमेशा एक सुसंगत आधार हो।
जे.टी.

13

शरीर में कहीं जोड़ें

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

फिर सीएसएस बनाएं

.hide { display: none; }

और अपने js में जोड़ें

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

1
OP में JSON है और डेटा स्रोत के रूप में उस सरणी का उपयोग करके कुछ html रेंडर करना चाहता है। यह उत्तर समस्या का समाधान कैसे कर रहा है? आपका उत्तर html नोड और क्लोन लेता है / इसे डुप्लिकेट करता है और डेटा बाइंडिंग से संबंधित कुछ भी नहीं करता है।
एड्रियन इफोडे

तो मैं कौन है जो नीच है।
एड्रियन इफोडे 14

मुझे वास्तव में लगता है कि आप एक बेहतर उत्तर पाने में मदद नहीं कर रहे हैं, क्योंकि आप हमें यह याद दिलाने के साथ शुरू कर सकते हैं कि यह बिंदु व्यापक था कि हमारे उत्तरों के लिए क्या संबोधित किया गया था।
सेबेस्टियन नीरा

1
यह काम करता है, लेकिन यह करने के .children().clone()बजाय अधिक कुशल है .html()<tr/>इस कोड का उपयोग करके एक पृष्ठ पर रैंडम के लिए गति लगभग 3: 1 है i=10000; time=performance.now(); while (--i) {$a.clone().append(0 ? $b.html() : $b.children().clone())} performance.now()-time। अनुपात वास्तव में थोड़ा अधिक अतिरंजित है क्योंकि मैं $ a.clone () का उपयोग कर रहा हूं, लेकिन प्रत्येक पुनरावृत्ति को खाली करने की कोशिश करना क्लोनिंग की तुलना में प्रदर्शन से अधिक हिट है, इसलिए मुझे यकीन नहीं है कि इसे और अधिक सटीक कैसे बनाया जाए क्योंकि समय के कार्यों की अपनी लागत है।
चिनोटो वोक्रो

1
यह ऑप्रॉच खराब है। मुख्य रूप से क्योंकि आपको टेम्पलेट सामग्री डाउनलोड मिलती है और भले ही आपने इसका उपयोग न किया हो। इसे एक वैध जवाब के रूप में माना जाना बहुत बड़ा मुद्दा है। ऊपर किसी और के रूप में भी, यदि आपको कम से कम .html () के बजाय क्लोन का उपयोग करना है
DevWL

3

अन्य विकल्प: शुद्ध

मैं इसका उपयोग करता हूं और इसने मेरी बहुत मदद की है। उनकी वेबसाइट पर दिखाया गया एक उदाहरण:

एचटीएमएल

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

JSON

{
  "who": "Hello Wrrrld"
}

परिणाम

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

2

इस समस्या को हल करने के लिए, मैं दो समाधान पहचानता हूं:

  • पहले वाला 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())
            });
    
        });
    });

    ध्यान रखें कि डेटा उपलब्ध होने के बाद अजाक्स पूरा होने के बाद घटना को जोड़ा जाना चाहिए!

  • दूसरा मूल 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 () नहीं करता है!)।


-- कोई बात नहीं! -
iConnor

ऑप में एक JSON है और डेटा स्रोत के रूप में उस सरणी का उपयोग करके कुछ html रेंडर करना चाहता है। यह उत्तर समस्या का समाधान कैसे कर रहा है? आपका उत्तर html नोड और क्लोन लेता है / इसे डुप्लिकेट करता है और डेटा बाइंडिंग से संबंधित कुछ भी नहीं करता है।
एड्रियन इफोडे

1
मैं op से उद्धृत करता हूं: मैं कुछ मूल्यों वाले कंटेनर तत्व के नीचे HTML कोड की एक प्रति संलग्न करना चाहता हूं। मेरा मानना ​​है कि यह उनकी समस्या का समाधान करता है।
सेबस्टियन नीरा

और "कुछ मूल्यों" भाग का इलाज कैसे किया जाता है?
एड्रियन इफोडे

खैर, इसका मतलब यह नहीं है कि यह समस्या को संबोधित नहीं करता है। मैं सराहना करता हूं कि आपने मुझे बताया था कि मुझे एक अंक याद आ रहा था :) वैसे भी, मुझे कैसे पता चलेगा कि उन मूल्यों को कैसे डाला जाए अगर मुझे यह भी पता नहीं है कि हम किन मूल्यों के बारे में बात कर रहे हैं? बस इस भाग पर एक नज़र डालें कि मैं इस HTML को स्मार्ट तरीके से फिर से उपयोग करने के लिए कहाँ रख सकता हूँ? । क्या सच में पूछा जा रहा है? JSON या HTML समावेशन के बारे में?
सेबस्टियन नीरा

1

देशी HTML5 टेम्पलेट तत्व का उपयोग करने के बारे में DevWL से बहुत अच्छा जवाब । ओपी से इस अच्छे प्रश्न में योगदान करने के लिए मैं जोड़ना चाहूंगा कि इस तत्व का उपयोग jQuery का उपयोग कैसे करें , उदाहरण के लिए:template

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

की सामग्री templatehtml नहीं है, लेकिन सिर्फ डेटा के रूप में व्यवहार की जाती है, इसलिए आपको उस सामग्री को एक jQuery ऑब्जेक्ट में लपेटने की आवश्यकता है, तब jQuery के तरीकों का उपयोग करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.