【问题标题】:Creating a canvas element and setting its width and height attributes using jQuery使用 jQuery 创建画布元素并设置其宽度和高度属性
【发布时间】:2014-02-26 07:44:25
【问题描述】:

我只是想在 jQuery 中执行以下操作:

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

这是有效的(有点)并生成以下标记:

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

你们大多数人可能都知道canvas 元素并不真正喜欢 CSS 尺寸,但需要一个宽度和高度属性,所以这个对象创建对我来说失败了。

我知道我可以做到:

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

相反,但我只是想知道是否有任何方法告诉 jQuery 在通过 $('element',{attributes}) 创建元素时,widthheight 应该被视为属性而不是 CSS?

【问题讨论】:

  • 明确一点,&lt;canvas&gt; 元素“喜欢”CSS 宽度和高度就好了;与 HTML &lt;img&gt; 一样,通过 CSS 设置显示尺寸会放大/缩小位图。 &lt;canvas&gt; 高度和宽度属性/属性就像在 Photoshop 中更改图像的大小,设置源图像中的实际像素数。
  • @Phrogz 这就是我写“不太喜欢”的原因...无论如何,我猜 99% 的画布元素都需要这些属性,因为它们与默认比例不匹配,并且以此类推。
  • @Phrogz ,是的,好的,但要清楚,你需要一些简单的数学才能在纯 css 中正确缩放它。否则canvas 将像普通的img 标签一样(如您所说),但它会不按比例缩放,并且大多数用户(正如他们所拥有的那样)在实际理解方面存在问题 - 正是这个准/相似性。

标签: javascript jquery canvas html


【解决方案1】:

jQuery 尝试将每个属性名称与 jQuery 函数名称匹配。调用匹配的函数。

widthheight 是 jQuery 函数,所以你的原始代码是这样的:

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

width(value)height(value) 函数设置 CSS 元素的宽度和高度。


相关jQuery源码行(https://github.com/jquery/jquery/blob/master/src/attributes.js#L308)

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

attrFn 对象定义(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
},

【讨论】:

  • 虽然这个答案确实有效地设置了样式高度和宽度,但问题是询问画布高度和宽度属性。 $('&lt;canvas&gt;').width(100).height(100) 实际上是设置画布的样式。更合适的答案来自@thecodeparadox。使用.prop({width: 100, height: 100}) 添加我们正在寻找的直接高度和宽度。
【解决方案2】:
var newCanvas = $('<canvas/>',{
                   'class':'radHuh',
                    id: 'myCanvas'                   
                }).prop({
                    width: 200,
                    height: 200
                });
$('#canvas').append(newCanvas);

Proof

【讨论】:

  • 这应该是公认的答案。 .prop 为画布元素设置适当的宽度和高度。
【解决方案3】:

你可以这样使用

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

换个情况试试

【讨论】:

  • 这很有趣。这是有意为之还是利用了一些不一致性?
  • 我猜它正在检查已知的 css 属性!
  • 这种行为可能会在以后的 jQuery 版本中改变,所以请记住链接到冻结版本
【解决方案4】:

似乎更改任何字母的大小写都会阻止 jQuery 将属性转换为样式,因此 ranganadh 可能偶然发现了 jQuery 中的一些意外缺陷,它会根据样式检查属性,但不区分大小写。

例如,这似乎也可以工作??

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

本机 JS 属性不会转换为样式,我可能会使用以下解决方案以确保它是“面向未来的”(setAttribute() 似乎也可以正常工作):

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

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

【讨论】:

    【解决方案5】:

    我发现这样效果最好:

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

    您也可以通过这种方式添加idclass 或其他属性。因为它不在style="" 属性中,所以它不能算作CSS,会弄乱你的形状。

    【讨论】:

      【解决方案6】:

      编辑:这比较慢,见下面的 cmets。

      这可能比此处发布的任何解决方法都要快:

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

      稍微不那么花哨,但它与更少的函数调用基本相同。

      【讨论】:

      • 其实这样似乎慢了很多:jsperf.com/element-creation-vs-string-injection
      • @m90 嗯,有意思,我想知道那是什么原因,好像不太合乎逻辑。
      • jQuery 不只是将字符串插入到 DOM 中,而是以多种不同的方式解析和处理它。如果您将纯 HTML 标记传递给 $(),它可以跳过对 $.buildFragment 的调用,这似乎非常昂贵,并通过 .attr() 本身进行属性处理。请参阅:james.padolsey.com/jquery/#v=1.7.2&fn=init 了解正在发生的事情。
      • @m90 是的,这是我发表评论后不久的想法,是有道理的。很高兴知道任何一种方式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-04
      相关资源
      最近更新 更多