1

我正在循环一个包含多个元素的对象,每个元素都包含多个媒体查询。

在循环中,我动态调用 enquire.js.register()以在比赛中执行某些操作。这最初是有效的,但在循环之外,并且在调整浏览器大小时,匹配不再有效,因为循环中使用的变量已从循环递增到它们的最高值。

用代码解释起来可能更容易!

这是images对象:

var images = [
   {
      "selector":"[data-id=\"0\"]",
      "breakpoints":[
         {
            "mediaquery":"(max-width: 31.25em) ",
            "src":"image-0-small.jpg"
         },
         {
            "mediaquery":"(min-width: 31.3125em) and (max-width: 46.25em) ",
            "src":"image-0-medium.jpg"
         },
         {
            "mediaquery":"(min-width: 46.3125em) ",
            "src":"image-0-large.jpg"
         }
      ]
   },
   {
      "selector":"[data-id=\"1\"]",
      "breakpoints":[
         {
            "mediaquery":"(max-width: 31.25em) ",
            "src":"image-1-small.jpg"
         },
         {
            "mediaquery":"(min-width: 31.3125em) and (max-width: 46.25em) ",
            "src":"image-1-medium.jpg"
         },
         {
            "mediaquery":"(min-width: 46.3125em) ",
            "src":"image-1-large.jpg"
         }
      ]
   },
   {
      "selector":"[data-id=\"2\"]",
      "breakpoints":[
         {
            "mediaquery":"(max-width: 31.25em) ",
            "src":"image-2-small.jpg"
         },
         {
            "mediaquery":"(min-width: 31.3125em) and (max-width: 46.25em) ",
            "src":"image-2-medium.jpg"
         },
         {
            "mediaquery":"(min-width: 46.3125em) ",
            "src":"image-2-large.jpg"
         }
      ]
   }
];

这是循环:

for (var x=0; x < images.length; x++) {
  for (var y=0; y < images[x]['breakpoints'].length; y++) {
    enquire.register(images[x]['breakpoints'][y]['mediaquery'], function () {
      // x and y unfortuntaley equal 3 & 3 after the loop, so how do I maintain them from inside the match?
      // Interestingly, Firefox doesn't seem attempt to fire matches more than once. Chrome and IE 11 do, which is where I found the error that images[x] is undefined

      console.log('match-index', x, y);
      console.log('match-images', images);
      console.log('match-mediaquery', images[x]['breakpoints'][y]['mediaquery']);
    });
  }
}

images[x]未定义,因为x = 3. 我如何保持xy等于未来matches 最初传递的内容?

4

2 回答 2

1

了不起的@WickyNilliams教了我关于闭包的知识,并提供了以下工作代码:

function registerWithEnquire(x, y) {
    enquire.register(swapImages[x]['breakpoints'][y]['mediaquery'], function () {
        // I want to set the src of the relevant cloned image to its corresponding src property in the swapImages object with:

        //document.querySelector(swapImages[x]['selector']).src = swapImages[x]['breakpoints'][y]['src'];

        // x and y unfortuntaley equal 5 & 3 after the loop, so how do I maintain them from inside the match?

        // Interestingly, Firefox doesn't seem attempt to fire matches more than once. Chrome and IE 11 do, which is where I found the error that swapImages[x] is undefined

        console.log('match-index', x, y);
        console.log('match-swapImages', swapImages);
        console.log('match-mediiquery', swapImages[x]['breakpoints'][y]['mediaquery']);

    });
}

for (var x=0; x < swapImages.length; x++) {
    console.group(x);
    console.log(swapImages[x]['selector']);

    for (var y=0; y < swapImages[x]['breakpoints'].length; y++) {
        console.log(swapImages[x]['breakpoints'][y]['mediaquery']);

        registerWithEnquire(x, y);
    }

    console.groupEnd();
}
console.log(x, y);

可以在这里找到一支工作笔:http: //codepen.io/WickyNilliams/pen/ckEeD

于 2014-02-03T01:06:32.713 回答
1

变量范围保持在函数级别。因此,您必须找到一种方法来在每次迭代时创建变量的副本并将该副本传递给注册函数。

一种方法是创建一个立即执行的函数表达式,该表达式返回最终将由register().

它看起来像这样:

(function(innerX, innerY) {
    return function() {
        // use innerX and innerY here
    };
}(x, y))

其工作方式是立即执行的函数表达式为其返回的函数创建一个闭包,该闭包具有对 x 和 y 副本的引用——innerX 和 innerY。

于 2014-02-02T23:47:56.180 回答