Eu tenho uma matriz que eu estou fazendo um loop. Sempre que uma condição for verdadeira, desejo anexar uma cópia do HTML
código abaixo a um elemento de contêiner com alguns valores.
Onde posso colocar esse HTML para reutilizar de maneira inteligente?
<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
});
});
javascript
jquery
json
Patrick Reck
fonte
fonte
Respostas:
Você pode optar por usar um mecanismo de modelo no seu projeto, como:
Se você não deseja incluir outra biblioteca, John Resig oferece uma solução jQuery , semelhante à abaixo.
Navegadores e leitores de tela ignoram os tipos de script não reconhecidos:
Usando o jQuery, adicionar linhas com base no modelo seria semelhante a:
fonte
Pergunta antiga, mas como a pergunta é "usando jQuery", pensei em fornecer uma opção que permita fazer isso sem introduzir nenhuma dependência de fornecedor.
Embora existam muitos mecanismos de modelagem por aí, muitos de seus recursos caíram em desagrado recentemente, com iteração (
<% for
), condicionais (<% if
) e transformações (<%= myString | uppercase %>
) vistas como micro-idioma na melhor das hipóteses e antipadrões na pior. As práticas modernas de modelagem incentivam simplesmente o mapeamento de um objeto para sua representação DOM (ou outra), por exemplo, o que vemos com propriedades mapeadas para componentes no ReactJS (especialmente componentes sem estado).Modelos dentro do HTML
Uma propriedade em que você pode confiar para manter o HTML do seu modelo próximo ao restante do HTML é usar um não executável
<script>
type
, por exemplo<script type="text/template">
. Para o seu caso:No carregamento do documento, leia o seu modelo e o tokenize usando um simples
String#split
Observe que, com nosso token, você o obtém no
[text, property, text, property]
formato alternado . Isso nos permite mapeá-lo bem usando umaArray#map
função de mapeamento:Onde
props
poderia parecer{ url: 'http://foo.com', img: '/images/bar.png', title: 'Lorem Ipsum' }
.Reunindo tudo, assumindo que você analisou e carregou o seu
itemTpl
como acima, e você tem umaitems
matriz no escopo:Essa abordagem também é apenas apenas jQuery - você deve ser capaz de adotar a mesma abordagem usando javascript vanilla com
document.querySelector
e.innerHTML
.jsfiddle
Modelos dentro de JS
Uma pergunta a ser feita é: você realmente deseja / precisa definir modelos como arquivos HTML? Você sempre pode componente + reutilizar um modelo da mesma maneira que reutilizaria a maioria das coisas que deseja repetir: com uma função.
No es7-land, usando funções de desestruturação, seqüências de caracteres de modelo e setas, você pode escrever funções de componentes absolutamente bonitas que podem ser facilmente carregadas usando o
$.fn.html
método acima.Então você poderia renderizá-lo facilmente, mesmo mapeado a partir de uma matriz, assim:
Ah, e observação final: não se esqueça de higienizar suas propriedades passadas para um modelo, se forem lidas em um banco de dados ou se alguém puder passar HTML (e depois executar scripts etc.) da sua página.
fonte
Use o modelo HTML!
Como a resposta aceita representaria um método de sobrecarga de script, gostaria de sugerir outro que seja, na minha opinião, muito mais limpo e mais seguro devido aos riscos XSS que acompanham os scripts de sobrecarga.
Fiz uma demonstração para mostrar como usá-lo em uma ação e como injetar um modelo em outro, editar e adicionar ao documento DOM.
exemplo html
exemplo js
HTML <template>
+ Seu conteúdo é efetivamente inerte até ser ativado. Essencialmente, sua marcação está oculta no DOM e não é renderizada.
+ Qualquer conteúdo dentro de um modelo não terá efeitos colaterais. Os scripts não são executados, as imagens não são carregadas, o áudio não é reproduzido ... até que o modelo seja usado.
O conteúdo é considerado como não estando no documento. Usar
document.getElementById()
ouquerySelector()
na página principal não retornará nós filhos de um modelo.+ Os modelos podem ser colocados em qualquer lugar no interior de
<head>
,<body>
ou<frameset>
e pode conter qualquer tipo de conteúdo que é permitido naqueles elementos. Observe que "qualquer lugar" significa que<template>
pode ser usado com segurança em locais que o analisador de HTML não permite.Cair pra trás
O suporte ao navegador não deve ser um problema, mas se você deseja cobrir todas as possibilidades, pode fazer uma verificação fácil:
Algumas informações sobre o método de script Sobrecarregando
<script>
tag possuidisplay:none
por padrão."text/javascript"
..innerHTML
. A análise de string em tempo de execução dos dados fornecidos pelo usuário pode facilmente levar a vulnerabilidades do XSS.Artigo completo: https://www.html5rocks.com/en/tutorials/webcomponents/template/#toc-old
Referência útil: https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode http://caniuse.com/#feat=queryselector
CRIANDO COMPONENTES DA WEB Tutorial de criação de componentes da Web personalizados usando modelos HTML da Trawersy Media: https://youtu.be/PCWaFLy3VUo
fonte
template
elemento não é suportado pelo Internet Explorer (a partir de 2018, IE11). Testado com o exemplo 580 de w3c.github.io/html/single-page.html .<template>
, embora eu recomende o uso de classes liberalmente, por isso fica claro quais objetos estão sendo definidos. Ainda são necessárias algumas habilidades js para mapear seus dados corretamente no modelo, especialmente usando uma abordagem no estilo de componentes para mapear grandes conjuntos de dados. Pessoalmente, eu ainda gosto de apenas criar o HTML em funções, ou idealmente, construir o DOM diretamente com o próprio JS e renunciar completamente ao HTML (por exemplo, como o React faz isso).Adicione em algum lugar do corpo
então crie css
e adicione aos seus js
fonte
.children().clone()
, em vez de.html()
. A velocidade é de cerca de 3: 1 para um aleatório<tr/>
que tive em uma página usando esse códigoi=10000; time=performance.now(); while (--i) {$a.clone().append(0 ? $b.html() : $b.children().clone())} performance.now()-time
. A proporção é realmente um pouco mais exagerada porque estou usando $ a.clone (), mas tentar esvaziá-la a cada iteração é mais um sucesso de desempenho do que a clonagem, por isso não tenho certeza de como torná-lo mais preciso, porque funções de tempo têm seu próprio custo.Outra alternativa: Pure
Eu o uso e isso me ajudou muito. Um exemplo mostrado em seu site:
HTML
JSON
Resultado
fonte
Para resolver esse problema, reconheço duas soluções:
O primeiro vem com o AJAX, com o qual você terá que carregar o modelo de outro arquivo e adicionar sempre que quiser
.clone()
.Leve em consideração que o evento deve ser adicionado assim que o ajax for concluído para garantir que os dados estejam disponíveis!
O segundo seria adicioná-lo diretamente em qualquer lugar do html original, selecioná-lo e ocultá-lo no jQuery:
Depois, você pode adicionar uma nova instância do modelo com
Igual ao anterior, mas se você não quiser que o modelo permaneça lá, mas apenas no javascript, acho que você pode usar (não o testou!) Em
.detach()
vez de ocultar..detach()
remove elementos do DOM enquanto mantém os dados e eventos ativos (.remove () não!).fonte
Resposta muito boa do DevWL sobre o uso do elemento de modelo HTML5 nativo . Para contribuir com essa boa pergunta do OP, gostaria de acrescentar como usar esse
template
elemento usando o jQuery, por exemplo:O conteúdo do
template
arquivo não é html, mas apenas tratado como dados; portanto, você precisa agrupar o conteúdo em um objeto jQuery para acessar os métodos do jQuery.fonte