1

再会!我在这里寻求有关应用于构造函数的 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 将其简化为一行:

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

此处的此链接恢复了如何完成此操作:使用eval(很多人说不推荐)和使用window(推荐)然后如果我这样做(没有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 for i 设置为仅一个:

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>
4

3 回答 3

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].

如果您尝试设置stage1,stage2等...停止。不要那样做。你有一堆物品,你对待它们是一样的……这就是数组的用途。一方面,请注意使用数组元素比使用类似名称的变量容易得多?我什至没有看到这个问题,因为数组已经不是问题了。

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

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破碎切换到使用数组,现在我们可以拥有任意多的阶段。

于 2012-04-11T22:26:05.860 回答
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。无论如何,这里是一个实现Array.map()的链接,您可以使用它来支持旧版浏览器,以防您必须支持旧版浏览器并且您还没有使用 JS5 shim。

于 2012-04-11T22:33:12.227 回答
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));
}
于 2012-04-11T22:24:15.053 回答