Creando un elemento de lienzo y configurando sus atributos de ancho y alto usando jQuery

Solo estaba tratando de hacer lo siguiente en jQuery:

var newCanvas = $('<canvas/>',{'width':100,'height':200,'class':'radHuh'});
$(body).append(newCanvas);

Esto está funcionando (más o menos) y genera el siguiente marcado:

<canvas style="width:100px; height:200px;" class="radHuh"></canvas>

Como la mayoría de ustedes sabrán canvas A los elementos realmente no les gustan las dimensiones CSS, pero esperan un atributo de ancho y alto, por lo que la creación de este objeto falló para mí.

Sé que podría hacer:

var newCanvas = $('<canvas/>',{'class':'radHuh'}).attr({'width':100,'height':200});

en su lugar, pero me preguntaba, no obstante, si hay alguna forma de decirle a jQuery que width y height deben tratarse como atributos al crear el elemento a través de $('element',{attributes}) y no como CSS?

preguntado el 03 de mayo de 12 a las 15:05

Para ser claros, <canvas> los elementos "gustan" el ancho y la altura de CSS muy bien; como con un HTML <img>, al configurar las dimensiones de la pantalla a través de CSS, se escala hacia arriba o hacia abajo un mapa de bits. El <canvas> Las propiedades/atributos de alto y ancho son como cambiar el tamaño de una imagen en Photoshop, estableciendo el número real de píxeles en la imagen de origen. -

@Phrogz es por eso que estaba escribiendo "realmente no me gusta"... En cualquier caso, supongo que el 99% de los elementos del lienzo necesitarán estos atributos ya que no coinciden con la proporción predeterminada, etc. -

@Phrogz, sí, está bien, pero para que quede claro, necesitará un poco de matemática simple para escalarlo correctamente en CSS simple. De lo contrario, el canvas actuará (como dijiste) como un normal img etiqueta pero lo hará NO escalar proporcionalmente y la mayoría de los usuarios (como lo han hecho) tienen problemas para comprender realmente, exactamente esta cuasi/similitud. -

6 Respuestas

jQuery intenta hacer coincidir cada nombre de atributo con un nombre de función jQuery. Se llaman funciones emparejadas.

width y height son funciones de jQuery, por lo que su código original es equivalente a esto:

  var newCanvas = 
    $('<canvas/>',{'class':'radHuh'})
    .width(100)
    .height(100);

ancho (valor) y altura (valor) conjunto de funciones CO ancho y alto de un elemento.


Línea de código fuente de jQuery relevante (https://github.com/jquery/jquery/blob/master/src/attributes.js#L308)

if ( pass && name in jQuery.attrFn ) {

attrFn definición de objeto (https://github.com/jquery/jquery/blob/master/src/attributes.js#L288):

attrFn: {
    val: true,
    css: true,
    html: true,
    text: true,
    data: true,
    width: true,
    height: true,
    offset: true
},

contestado el 08 de mayo de 12 a las 12:05

Si bien esta respuesta establece efectivamente la altura y el ancho con estilo, la pregunta es sobre los atributos de altura y ancho del lienzo. $('<canvas>').width(100).height(100) en realidad establece el estilo del lienzo. La respuesta más apropiada es de @thecodeparadox. Utilizando .prop({width: 100, height: 100}) agrega la altura y el ancho directos que estamos buscando. - jose w lewis

var newCanvas = $('<canvas/>',{
                   'class':'radHuh',
                    id: 'myCanvas'                   
                }).prop({
                    width: 200,
                    height: 200
                });
$('#canvas').append(newCanvas);

Pruebas

contestado el 08 de mayo de 12 a las 15:05

Esta debería ser la respuesta aceptada. .prop establece el ancho y la altura de forma adecuada para los elementos del lienzo. - jose w lewis

Puedes usar así

$('<canvas/>',{'class':'radHuh','Width':100,'Height':200});

Cambia el caso y prueba

contestado el 03 de mayo de 12 a las 15:05

Eso es interesante. ¿Esto está sucediendo por diseño o se está aprovechando de alguna inconsistencia? - m90

¡Supongo que está buscando atributos css conocidos! - Ranganadh Paramkusam

este comportamiento podría cambiar en una versión posterior de jQuery, así que tenga en cuenta vincular a la versión congelada: Jacek Kaniuk

Parece que cambiar el caso de cualquier letra evitará que jQuery convierta el atributo en un estilo, por lo que ranganadh probablemente se topó con alguna falla no deseada en jQuery donde compara el atributo con los estilos, pero no distingue entre mayúsculas y minúsculas.

Esto, por ejemplo, parece funcionar también ??

var newCanvas = $('<canvas/>', {heiGht: 200, widtH: 100});
$('body').append(newCanvas);​​​

Los atributos nativos de JS no se convierten en estilos, y probablemente optaría por la siguiente solución para asegurarme de que sea "a prueba de futuro" ( setAttribute() parece funcionar bien también):

var newCanvas = $('<canvas/>');
    newCanvas[0].height = 200;
    newCanvas[0].width = 100;

$('body').append(newCanvas);​​​

Respondido 25 Feb 14, 23:02

Descubrí que esto funcionó mejor:

$('<canvas height="50px" width="50px"/>')

También puede añadir id, class, u otros atributos de esta manera. porque no está en el style="" atributo, no cuenta como CSS y estropea sus formas.

Respondido el 31 de enero de 14 a las 21:01

Edit: Esto es más lento, vea los comentarios a continuación.

Es probable que esto sea más rápido que cualquier solución publicada aquí:

var attributes = {width: 100, height: 100, class: "whatever"};
$('<canvas width="'+attributes.width+'" height="'+attributes.height+'" class="'+attributes.class+'""></canvas>').appendTo(document.body);

Ligeramente menos elegante, pero es esencialmente lo mismo con menos llamadas a funciones.

Respondido 10 Feb 13, 16:02

En realidad, parece ser mucho más lento de esa manera: jsperf.com/element-creation-vs-string-injection - m90

@ m90 Hm, interesante, me pregunto cuál es la razón detrás de eso, no parece ser muy lógico. - mahn

jQuery no solo insertará la cadena en el DOM, sino que la analizará y manejará de muchas maneras diferentes. Si pasa una etiqueta HTML sin formato a la $() puede omitir una llamada a $.buildFragment que parece ser bastante caro y hace el manejo de atributos a través de .attr() sí mismo. Ver: james.padolsey.com/jquery/#v=1.7.2&fn=init por lo que esta pasando - m90

@m90 sí, esto es lo que pensé poco después de publicar el comentario, tiene sentido. Bueno saber de cualquier manera. - mahn

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.