使用Javascript和构造函数的动态变量名称:使用EaselJS动态地将图像克隆到多个画布

时间:2012-04-11 22:15:56

标签: javascript html5 syntax html5-canvas easeljs

美好的一天! 我在这里请求有关应用于构造函数的Javascript中的动态变量名称的帮助。这比预期困难得多。我在很多论坛和网页上都读过这个问题,但我找不到我做错了什么= /

我正在使用名为EaselJS的HTML5 + Javascript库,但我的问题与它无关,而是与Javascript语法有关! 这是我的问题。我得到了这段代码:

stage1 = new Stage(document.getElementById("cnvs1"));
stage2 = new Stage(document.getElementById("cnvs2"));
stage3 = new Stage(document.getElementById("cnvs3"));

这里,变量 stage 已经分配了一个Stage对象,该对象使用canvas id cnvs 进行初始化。这一行(在我的其余代码的上下文中)有效! 我想将其简化为一行,其中包含以下内容:

for(i = 0; i < 5; i++){
  //Of course this is wrong!
  stage[i] = new Stage(document.getElementById("cnvs[i]"));
}

This link here恢复如何做到这一点:使用 eval (很多人说它不值得推荐)和窗口(推荐)然后如果我这样做(没有for来简化更多):

var varname = "stage";
var i = 1;
window[varname + i] = new Stage(document.getElementById("cnvs_terminal1"));

代码仍然有效。但我无法弄清楚如何使用引号中的画布ID来完成类似的解决方案。这些代码行失败了:

var i = 1;
var varname = "stage";
var varname2 = 'cnvs1';
var varname3 = "\"cnvs1\"";
var varname4 = "\"cnvs1" + i + "\"";

window[varname +i] = new Stage(document.getElementById(window[varname2]));
window[varname +i] = new Stage(document.getElementById(window[varname3]));
window[varname +i] = new Stage(document.getElementById(window[varname4]));

在这些尝试中,即使尝试传递我需要的确切值(没有 i ),它也没有帮助我!我反驳了引号,因为我认为它们对于getElementbyId =(=(=(

)是必要的

现在我很无能为力! =( 我确定有办法做到这一点,也许我不知道语法,也许我不知道如何通过引用或值正确调用变量,我不知道... 请帮帮我,我不知道怎么做这个简单的任务!

感谢很多=)

修改 的 尝试@cHao建议我也做不到!保持简单,我为我设置了仅为一个:

for (var i = 1; i <= 1; ++i) {
  //I use only one of the following lines at a time of course, but I'll write here my failing tries all together:
  stage[i] = new Stage(document.getElementById('cnvs'+i));
  stage[i-1] = new Stage(document.getElementById('cnvs'+i));

  //Hardcoding the first variable works!
  stage1 = new Stage(document.getElementById('cnvs'+i));
}

问题的一半已解决,但如何处理第一个变量? = /感谢!!!!

编辑2: 已经要求更多细节!这是一个复制/粘贴示例!只需更新EaselJS和图像路径即可使用!

<!DOCTYPE HTML>
<html>
  <head>
    <script src="easeljs-0.4.0-26/lib/easel.js"></script>       

    <script type="text/javascript"> 
      function init() {
        //MY PROBLEM LIES HERE!!
        for (var i = 1; i <= 1; ++i) {
          //This code WORKS
          stage1 = new Stage(document.getElementById('cnvs'+i));
          //This code DOES NOT WORKS
          //stage[i] = new Stage(document.getElementById('cnvs'+i));
          //stage[i-1] = new Stage(document.getElementById('cnvs'+i));
        }
        var images = "images/itzapic.jpg";
        bitmap = new Bitmap(images);
        stage1.addChild(bitmap);
        stage1.update();
        Ticker.addListener(window);
      }

      function tick() {
        stage1.update();
      }
    </script>        
  </head>

  <body onload="init()"> 
    <canvas id="cnvs1" width="140" height="82">
  </body>
</html>

__ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ _

编辑3:已解决! 我将发布最终代码,以便参考想要使用EaselJS在同一对象中根据需要在尽可能多的画布中渲染单个图像的人。为此,您需要bitmap.clone()方法和阶段的数组。感谢@cHao帮助我;) 以下代码将在所有画布中呈现相同的图像!必要时更新;)

<!DOCTYPE HTML>
<html>
  <head>
    <script src="easeljs-0.4.0-26/lib/easel.js"></script>       

    <script type="text/javascript"> 
      stage = [];
      function init() {
        for (var i = 1; i <= 6; ++i) {
          stage[i-1] = new Stage(document.getElementById('cnvs'+i));
        }
        var images = "images/itzapic.jpg";
        bitmap = new Bitmap(images);
        stage[0].addChild(bitmap);
        for (var i = 1; i <= 5; ++i) {
          stage[i].addChild(bitmap.clone());
        }
        stage[0].update();
        Ticker.addListener(window);
        }

        function tick() {
        for (var i = 0; i < stage.length; ++i) {
          stage[i].update();
        }
      }
</script>        
</head>

  <body onload="init()"> 
    <canvas id="cnvs1" width="140" height="82"></canvas>
    <canvas id="cnvs2" width="140" height="82"></canvas>
    <canvas id="cnvs3" width="140" height="82"></canvas>
    <canvas id="cnvs4" width="140" height="82"></canvas>
    <canvas id="cnvs5" width="140" height="82"></canvas>
    <canvas id="cnvs6" width="140" height="82"></canvas>
  </body>
</html>

3 个答案:

答案 0 :(得分:3)

我不确定是否得到了评估变量名称或预先计算变量名称的所有内容。好像你可以这样做

for (var i = 1; i <= 5; ++i) {
    stage[i] = new Stage(document.getElementById('cnvs' + i));
}
除非window["varname"]是全球性的,否则

varname将无济于事,并且......呃。如果可以的话,你会想要避免使用全局变量。无论哪种方式,你都不需要转义引号 - 你根本不需要名字本身的引号,除非你的ID中有引号(AFAIK无论如何都是无效的)或者你正在评估(这是邪恶本身)。

如果您希望将各个阶段放入一个数组(这似乎是一个更好的目标),您将希望您的第一阶段为stage[0]。在这种情况下,请设置stage[i-1]而不是stage[i]

如果你想设置stage1stage2等等,请停止。不要那样做。你有很多项目,你正在对待......这就是阵列的意思。首先,请注意使用数组元素比使用类似命名的变量更容易?我甚至没有看到这个问题,因为对于数组而言,它已经不是问题了。

至于你的代码......看这个。

stage = [];

function init() {
    for (var i = 1; i <= 1; ++i) {
        stage[i-1] = new Stage(document.getElementById('cnvs'+i));
    }
    var images = "images/itzapic.jpg";
    bitmap = new Bitmap(images);
    stage[0].addChild(bitmap);
    stage[0].update();
    Ticker.addListener(window);
}

function tick() {
    for (var i = 0; i < stage.length; ++i) {
        stage[i].update();
    }
}

一旦我们从stage1 stage2断裂切换到使用数组,现在我们可以拥有任意数量的阶段。

答案 1 :(得分:1)

我想你想要这个:

var stagePrefix = 'stage';
var canvasPrefix = 'cnvs';
//adjust loop below based on your naming e.g. do they start at 0 or 1?
for(var i=1;i<5;i++){
  window[stagePrefix + i] = new Stage(document.getElementById(canvasPrefix + i));
}

答案 2 :(得分:1)

我没有使用带有数字后缀的id来引用你的画布,而是通过标签名称获取它们:

var canvases = document.getElementsByTagName("canvas");

或者,如果您只想处理页面上的某些画布元素,请为它们提供一个类:

var canvases = document.getElementsByClassName("cnvs");

然后,要从画布中获取一系列舞台,请劫持Array.map() *方法:

var stages = [].map.call(canvases, function(canvas) {
    return new Stage(canvas);
});



* Array.map()是JS5的新功能,但如果您的浏览器支持<canvas>则支持JS5。无论如何,这里是您可以用来支持旧浏览器的implementation of Array.map()的链接,以防您必须支持旧浏览器并且您还没有使用JS5垫片。