jQuery document.createElement equivalente?

1251

Estoy refactorizando algún código JavaScript antiguo y hay mucha manipulación DOM.

var d = document;
var odv = d.createElement("div");
odv.style.display = "none";
this.OuterDiv = odv;

var t = d.createElement("table");
t.cellSpacing = 0;
t.className = "text";
odv.appendChild(t);

Me gustaría saber si hay una mejor manera de hacer esto usando jQuery. He estado experimentando con:

var odv = $.create("div");
$.append(odv);
// And many more

Pero no estoy seguro de si esto es mejor.

Rob Stevenson-Leggett
fuente
jsben.ch/#/ARUtz - un punto de referencia para jQuery vs createElement
EscapeNetscape
Posible duplicado de Crear un elemento div en jQuery
T.Todua
TypeError no capturado: $ .create no es una función
Tyguy7

Respuestas:

1290

Aquí está su ejemplo en la línea "uno".

this.$OuterDiv = $('<div></div>')
    .hide()
    .append($('<table></table>')
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;

Actualización : pensé en actualizar esta publicación, ya que todavía recibe bastante tráfico. En los comentarios a continuación hay una discusión sobre $("<div>")vs $("<div></div>")vs $(document.createElement('div'))como una forma de crear nuevos elementos, y cuál es el "mejor".

Creé un pequeño punto de referencia , y aquí están más o menos los resultados de repetir las opciones anteriores 100,000 veces:

jQuery 1.4, 1.5, 1.6

               Chrome 11  Firefox 4   IE9
<div>            440ms      640ms    460ms
<div></div>      420ms      650ms    480ms
createElement    100ms      180ms    300ms

jQuery 1.3

                Chrome 11
<div>             770ms
<div></div>      3800ms
createElement     100ms

jQuery 1.2

                Chrome 11
<div>            3500ms
<div></div>      3500ms
createElement     100ms

Creo que no es una gran sorpresa, pero document.createElementes el método más rápido. Por supuesto, antes de salir y comenzar a refactorizar toda su base de código, recuerde que las diferencias de las que estamos hablando aquí (en todas las versiones menos arcaicas de jQuery) equivalen a aproximadamente 3 milisegundos adicionales por mil elementos .


Actualización 2

Se actualizó para jQuery 1.7.2 y puso el punto de referencia en el JSBen.chque probablemente sea un poco más científico que mis puntos de referencia primitivos, ¡además ahora se puede hacer crowdsourcing!

http://jsben.ch/#/ARUtz

nickf
fuente
70
Encontrará que document.createElement es mucho más rápido que hacer que jQuery convierta su cadena html en un elemento. (solo en caso de que tenga ganas de hacer las cosas más eficientes)
Sugendran
25
Eso es cierto para jQuery <1.3 Su velocidad equivalente ahora creo.
Rob Stevenson-Leggett
15
@Kevin, eso es cierto, sin embargo, hace que jQuery haga más trabajo (lo ejecuta a través de una expresión regular para agregar la etiqueta de cierre), por lo que prefiero el método anterior. Además, diferencia su código del $('div')cual es visualmente muy similar, pero funcionalmente se separa.
nickf
14
Entonces, ¿básicamente una combinación de @Sungendran y @nickf sería $(document.createElement('div'))y debería ser la más rápida?
Kolky
14
Creo que la forma "correcta" es $ ('<div />'), con, IMO, tiene aún más "significado", ya que es bastante obvio que está creando un Nodo. Lo malo es que de esta manera se rompe el resaltado de sintaxis en todos los editores = (
Erik Escobedo
139

Simplemente suministrando el HTML de los elementos que desea agregar a un constructor jQuery $()devolverá un objeto jQuery del HTML recién creado, adecuado para ser agregado al DOM usando el append()método de jQuery .

Por ejemplo:

var t = $("<table cellspacing='0' class='text'></table>");
$.append(t);

A continuación, puede rellenar esta tabla mediante programación, si lo desea.

Esto le da la capacidad de especificar cualquier HTML arbitrario que desee, incluidos los nombres de clase u otros atributos, que puede encontrar más conciso que usar createElementy luego establecer atributos como cellSpacingy a classNametravés de JS.

Adam Bellaire
fuente
77
Tal vez esto era obvio, e indicado por su ejemplo, pero crear un elemento DOM jQuery usando la sintaxis $ ("<html string>"), no puede agregarse al DOM usando el método <element> .appendChild nativo o similar. Debe usar el método de adición jQuery.
Adam
44
$(htmlStr)se implementa como document.createElement("div").innerHTML = htmlStr. En otras palabras, invoca el analizador HTML del navegador. El HTML con formato incorrecto se rompe de manera diferente en IE frente a otros navegadores.
Matthew
2
El objeto @Adam jQuery tiene la getfunción que devuelve el elemento DOM nativo. (Sé que este tema es antiguo, pero lo agrego como referencia. ;-))
Constantino Tsarouhas
1
Si tiene problemas con la cadena html, intente analizarla con jQuery.parseHTML
fguillen
1
@ Adam O, si es más fácil para el flujo de código / ojos, puedes hacerlo[dom element].appendChild($('<html>')[0]);
ACK_stoverflow
49

Estoy haciendo asi:

$('<div/>',{
    text: 'Div text',
    class: 'className'
}).appendTo('#parentDiv');
kami
fuente
44

desde entonces jQuery1.8, usar $.parseHTML()para crear elementos es una mejor opción.

Hay dos beneficios:

1.si usa la forma anterior, que puede ser algo así $(string), jQuery examinará la cadena para asegurarse de que desea seleccionar una etiqueta html o crear un nuevo elemento. Al usar $.parseHTML(), le dice a jQuery que desea crear un nuevo elemento explícitamente, por lo que el rendimiento puede ser un poco mejor.

2.mucho más importante es que puede sufrir un ataque cruzado ( más información ) si usa la forma anterior. si tienes algo como:

    var userInput = window.prompt("please enter selector");
    $(userInput).hide();

un chico malo puede ingresar <script src="xss-attach.js"></script>para molestarte. Afortunadamente, $.parseHTML()evita esta vergüenza para ti:

var a = $('<div>')
// a is [<div>​</div>​]
var b = $.parseHTML('<div>')
// b is [<div>​</div>​]
$('<script src="xss-attach.js"></script>')
// jQuery returns [<script src=​"xss-attach.js">​</script>​]
$.parseHTML('<script src="xss-attach.js"></script>')
// jQuery returns []

Sin embargo, tenga en cuenta que aes un objeto jQuery mientras que bes un elemento html:

a.html('123')
// [<div>​123​</div>​]
b.html('123')
// TypeError: Object [object HTMLDivElement] has no method 'html'
$(b).html('123')
// [<div>​123​</div>​]
Brian
fuente
"Mejor opción" para "crear [cualquier] elemento" podría ser fuerte. La respuesta de @ siergiej hace un buen trabajo al decir que parseHTMLes bueno para html proveniente de fuentes externas, pero que " todo el impulso se ha ido después de envolver los resultados en un nuevo objeto jQuery ". Es decir, si desea codificar la creación de un nuevo elemento html envuelto en jQuery, el $("<div>stuff</div>")estilo aún parece ganar.
ruffin
38

ACTUALIZAR

A partir de las últimas versiones de jQuery, el siguiente método no asigna propiedades pasadas en el segundo objeto

Respuesta anterior

Siento que usar document.createElement('div')junto con jQueryes más rápido:

$(document.createElement('div'), {
    text: 'Div text',
    'class': 'className'
}).appendTo('#parentDiv');
Om Shankar
fuente
29

Aunque esta es una pregunta muy antigua, pensé que sería bueno actualizarla con información reciente;

Desde jQuery 1.8 hay una función jQuery.parseHTML () que ahora es una forma preferida de crear elementos. Además, hay algunos problemas con el análisis HTML a través de $('(html code goes here)'), por ejemplo, el sitio web oficial de jQuery menciona lo siguiente en una de sus notas de lanzamiento :

Análisis HTML relajado: una vez más puede tener espacios iniciales o nuevas líneas antes de las etiquetas en $ (htmlString). Todavía le recomendamos encarecidamente que use $ .parseHTML () al analizar HTML obtenido de fuentes externas, y que en el futuro pueda realizar más cambios al análisis HTML.

Para relacionarse con la pregunta real, el ejemplo proporcionado podría traducirse a:

this.$OuterDiv = $($.parseHTML('<div></div>'))
    .hide()
    .append($($.parseHTML('<table></table>'))
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;

que desafortunadamente es menos conveniente que usar solo $(), pero le da más control, por ejemplo, puede optar por excluir etiquetas de script (dejará scripts en línea como onclick):

> $.parseHTML('<div onclick="a"></div><script></script>')
[<div onclick=​"a">​</div>​]

> $.parseHTML('<div onclick="a"></div><script></script>', document, true)
[<div onclick=​"a">​</div>​, <script>​</script>​]

Además, aquí hay un punto de referencia de la respuesta superior ajustada a la nueva realidad:

Enlace JSbin

jQuery 1.9.1

  $ .parseHTML: 88ms
  $ ($. parseHTML): 240 ms
  <div> </div>: 138 ms
  <div>: 143ms
  createElement: 64ms

Parece que parseHTMLestá mucho más cerca createElementque $(), pero todo el impulso se ha ido después de envolver los resultados en un nuevo objeto jQuery

siergiej
fuente
11
var mydiv = $('<div />') // also works
Shimon Doodkin
fuente
6
var div = $('<div/>');
div.append('Hello World!');

Es la forma más corta / fácil de crear un elemento DIV en jQuery.

AcidicChip
fuente
5

Acabo de hacer un pequeño complemento jQuery para eso: https://github.com/ern0/jquery.create

Sigue tu sintaxis:

var myDiv = $.create("div");

La ID del nodo DOM se puede especificar como segundo parámetro:

var secondItem = $.create("div","item2");

¿Es serio? No. Pero esta sintaxis es mejor que $ ("<div> </div>") , y es un muy buen valor por ese dinero.

Soy un nuevo usuario de jQuery, cambio de DOMAssistant, que tiene una función similar: http://www.domassistant.com/documentation/DOMAssistantContent-module.php

Mi complemento es más simple, creo que es mejor agregar atributos y contenido encadenando métodos:

$("#container").append( $.create("div").addClass("box").html("Hello, world!") );

Además, es un buen ejemplo para un simple jQuery-plugin (el número 100).

ern0
fuente
4

¡Todo es bastante sencillo! Aquí hay un par de ejemplos rápidos ...


var $example = $( XMLDocRoot );

var $element = $( $example[0].createElement('tag') );
// Note the [0], which is the root

$element.attr({
id: '1',
hello: 'world'
});

var $example.find('parent > child').append( $element );
Cachondo
fuente
1

No se menciona en respuestas anteriores, por lo que estoy agregando ejemplos de trabajo sobre cómo crear elementos de elementos con la última jQuery, también con atributos adicionales como contenido, clase o devolución de llamada onclick:

const mountpoint = 'https://jsonplaceholder.typicode.com/users'

const $button = $('button')
const $tbody = $('tbody')

const loadAndRender = () => {
  $.getJSON(mountpoint).then(data => {

    $.each(data, (index, { id, username, name, email }) => {
      let row = $('<tr>')
        .append($('<td>', { text: id }))
        .append($('<td>', {
          text: username,
          class: 'click-me',
          on: {
            click: _ => {
              console.log(name)
            }
          }
        }))
        .append($('<td>', { text: email }))

      $tbody.append(row)
    })

  })
}

$button.on('click', loadAndRender)
.click-me {
  background-color: lightgrey
}
<table style="width: 100%">
  <thead>
    <tr>
      <th>ID</th>
      <th>Username</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
  
  </tbody>
</table>

<button>Load and render</button>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

Vladislav Ladicky
fuente
-2

jQuery listo para usar no tiene el equivalente de createElement. De hecho, la mayoría del trabajo de jQuery se realiza internamente mediante innerHTML sobre la manipulación de DOM puro. Como Adam mencionó anteriormente, así es como puede lograr resultados similares.

También hay complementos disponibles que hacen uso del DOM sobre innerHTML como appendDOM , DOMEC y FlyDOM solo por nombrar algunos. En cuanto al rendimiento, el jquery nativo sigue siendo el más eficiente (principalmente porque usa innerHTML)

James Hughes
fuente
55
Deberías ponerte al día. jQuery no usa innerHtml pero analiza la cadena HTML y construye internamente un árbol DOM usando document.createElement (). Este es el núcleo de jQuery.
Vincent Robert