繁体   English   中英

Javascript:遍历/遍历多个轴/方向?

[英]Javascript: Iterate/loop through multiple axes/directions?

正如您将在下面看到的那样,我正在尝试编写一些必须重复两次的逻辑-一次用于水平方向,第二次用于垂直方向。 问题在于每个方向都有不同的函数名称,并且与其他可以通过整数进行迭代的方案不同。 有没有更优雅的重写方式?

// Some calculations along the horizontal axis
someElementX.addEventListener('some-event', function(e){
  var someResult = e.clientX - thisElement.style.left;
  var someOtherResult = e.clientY; // Also some quick orthogonal calculation
});

// Some calculations along the vertical axis
someElementY.addEventListener('some-event', function(e){
  var someResult = e.clientY - thisElement.style.top;
  var someOtherResult = e.clientX; // Also some quick orthogonal calculation
});

这是我设法做到的一种方法,但是在消除了代码重复的同时,我感到它令人难以置信,而且难以维护。

// Set up a "direction" loop
var loopParams =
  { 0: { xy: 'x', clientXY: { 1: 'clientX', 2: 'clientY' }, side: 'left' } 
  , 1: { xy: 'y', clientXY: { 1: 'clientY', 2: 'clientX' }, side: 'top'  }
  };

// Run the loop for each direction
for( var i = 0; i < 2; i++ )
{
  var xy       = loopParams[i].xy;
  var clientXY = loopParams[i].clientXY;
  var side     = loopParams[i].side;

  someElements[xy].addEventListener('some-event', function(e){
    var someResult      = e[clientXY[1]] - thisElement.style[side];
    var someOtherResult = e[clientXY[2]]; // Some quick orthogonal calculation
  });
}

有任何想法吗?

另外,我不确定该怎么称呼这个问题。 有没有更好的术语来描述我要在这里做什么?

通常,您的方法很好。 但是,您的代码存在臭名昭著的Loop问题 -所有已安装的事件处理程序都将使用上次迭代中的变量值。

您应该使用数组文字而不是对象文字,这还具有以下优点:只要可以使用forEach ,就不需要loopParams变量和显式的for loopParams免费获取闭包。

[
  {dir:'x', posProp:'clientX', otherProp:'clientY', side:'left'},
  {dir:'y', posProp:'clientY', otherProp:'clientX', side:'top'}
].forEach(function(loopParam) {
  someElements[loopParam.dir].addEventListener('some-event', function(e){
    var someResult      = e[loopParam.posProp] - thisElement.style[loopParam.side];
    var someOtherResult = e[loopParam.otherProp]; // Some quick orthogonal calculation
  });
});

当然,您可以使用更多简洁的变量和属性名称。

您确实需要权衡消除重复的好处和增加的复杂性。 对于只有两个相似的函数(如果它们确实确实短于您的问题),却有这么多(4)个不同的部分,所获得的优势似乎还不足以使这种重写成为必要。


其他可以在此处应用的技术是:a)闭包工厂-不需要参数对象:

function addXYHandler(el, posProp, otherProp, side) {
  el.addEventListener('some-event', function(e){
    var someResult      = e[posProp] - thisElement.style[side];
    var someOtherResult = e[otherProp]; // Some quick orthogonal calculation
    // much "duplicate" code
  });
}
addXYHandler(someElementX, 'clientX', 'clientY', 'left');
addXYHandler(someElementY, 'clientY', 'clientX', 'top');

或b)仅使用不同的处理程序,并将外部功能中的通用功能外包:

function someResult(…) { … }
function someOtherResult(…) { … }
// or maybe use only one function with multiple parameters
var handlers = {
  x: function(e) {
    someResult(e.clientX - thisElement.style.left);
    someOtherResult(e.clientY);
  },
  y: function(e){
    someResult(e.clientY - thisElement.style.top);
    someOtherResult(e.clientX);
  }
});
for (var dir in handlers)
  someElements[xy].addEventListener('some-event', handlers[dir]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM