功能是设置所有而不是每个

时间:2012-01-10 22:37:31

标签: javascript jquery

我有一个简单的函数,可以根据参数设置条形的宽度。

我用jQuery调用.each上的函数。

控制台正确记录语句,显示它似乎有效。但是,样式似乎被最后找到的值所覆盖。

这是功能:

function barGraph(innerWidth, barWidth) {
    innerWidth = parseInt(innerWidth) * .01 || .50;
    barWidth = parseInt(barWidth) || 267;

   // find percentage of total width
   var innerWidth = Math.floor(innerWidth * barWidth);

   var $innerBar = $('.slider-box div');

   $innerBar.css('width', innerWidth + 'px');

   console.log("Width should be: " + innerWidth + 'px');
}

然后我用jQuery调用每个函数:

$(document).ready(function() {
   var $innerBar = $('.slider-box div');

   $innerBar.each(function(index) {
       var newWidth = $(this).attr("data-bar-width");
       barGraph(newWidth, 267);
   });
});

控制台日志显示10次,具有所有适当的宽度。但是,all的样式与最后一个宽度相同。

有人可以帮忙解释我如何获得设置当前所选div的宽度的功能吗?

非常感谢,

亚当。

5 个答案:

答案 0 :(得分:2)

问题出在这里,看看你的barGraph函数:

   var $innerBar = $('.slider-box div'); //here you choose all divs inside .slider-box

   $innerBar.css('width', innerWidth + 'px'); //and set the width for all of them 

更改barGraph功能:

function barGraph(innerWidth, barWidth) {
    innerWidth = parseInt(innerWidth) * .01 || .50;
    barWidth = parseInt(barWidth) || 267;

   // find percentage of total width
   var innerWidth = Math.floor(innerWidth * barWidth);

   var $innerBar = $('.slider-box div');
   $innerBar.each(function(index){
 $(this).css('width', innerWidth + 'px');
});

   console.log("Width should be: " + innerWidth + 'px');
}

答案 1 :(得分:2)

让我们分解

$(document).ready(function() {
   var $innerBar = $('.slider-box div');

   // going to call the barGraph function on each matching element
   // so far, so good
   $innerBar.each(function(index) {
       var newWidth = $(this).attr("data-bar-width");
       barGraph(newWidth, 267);
   });
});

然后在barGraph

function barGraph(innerWidth, barWidth) {
    innerWidth = parseInt(innerWidth) * .01 || .50;
    barWidth = parseInt(barWidth) || 267;

   // find percentage of total width
   var innerWidth = Math.floor(innerWidth * barWidth);

   // getting all the matching elements (again)
   var $innerBar = $('.slider-box div');

   // setting the width of each matched element to 
   // the innerwidth calculated in this barGraph call.
   $innerBar.css('width', innerWidth + 'px');

   console.log("Width should be: " + innerWidth + 'px');
}

因此,barGraph函数的运行次数与$('.slider-box div')中的匹配元素一样多,但每次运行都会设置所有匹配元素的宽度。实际上,最后一次运行会将所有匹配元素的宽度设置为上次运行时innerWidth计算的任何值。那是你想要发生的事吗?

更有可能的是这样的事情

$(function() {
   var $innerBar = $('.slider-box div');

   // going to call the barGraph function on each matching element
   // so far, so good
   $innerBar.each(function(index) {
       var bar = $(this),
           newWidth = bar.attr("data-bar-width");
       barGraph(bar, newWidth, 267);
   });

   function barGraph(bar, innerWidth, barWidth) {
       innerWidth = parseInt(innerWidth, 10) * .01 || .50;
       barWidth = parseInt(barWidth, 10) || 267;

       innerWidth = Math.floor(innerWidth * barWidth);

       bar.css('width', innerWidth + 'px');

       console.log("Width should be: " + innerWidth + 'px');
   }

});

如果在each调用之外没有使用barGraph函数,那么我可能倾向于将函数体移动到传递给each的匿名函数内部或者修改barGraph函数作为函数传递给每个人

$(function() {

   $('.slider-box div').each(barGraph);

   function barGraph(index, element) {
       var bar = $(this),
           newWidth = bar.attr("data-bar-width");

       newWidth = parseInt(newWidth , 10) * .01 || .50;
       newWidth = Math.floor(innerWidth * 267);

       bar.css('width', newWidth + 'px');

       console.log("Width should be: " + newWidth + 'px');
   }

});

答案 2 :(得分:1)

这可能会发生在最后barGraph()次通话中,因为您将所有$('.slider-box div'); 设置为您在each()

中读取的最后一个值

如果你尝试这样的事情怎么办

function barGraph(el, innerWidth, barWidth) {
   ...

   el.css('width', innerWidth + 'px');
   console.log("Width should be: " + innerWidth + 'px');
}

$(document).ready(function() {
   var $innerBar = $('.slider-box div');

   $innerBar.each(function(index, el) {
       var newWidth = $(el).attr("data-bar-width");
       barGraph($(el), newWidth, 267);
   });
});

在这种方法中,我将每个元素的jQuery引用传递给barGraph()函数。它也比以前便宜,因为你总是创建一个对div集合的jQuery引用。

答案 3 :(得分:1)

barGraph功能中,选择.slider-box div的所有实例并设置宽度。您只想设置当前使用的那个。

function barGraph($bar, innerWidth, barWidth) {
    innerWidth = parseInt(innerWidth) * .01 || .50;
    barWidth = parseInt(barWidth) || 267;

   // find percentage of total width
   var innerWidth = Math.floor(innerWidth * barWidth);

   $bar.css('width', innerWidth + 'px');

   console.log("Width should be: " + innerWidth + 'px');
}

在循环过程中将条形图传递给barGraph。

$(document).ready(function() {
   var $innerBar = $('.slider-box div');

   $innerBar.each(function(index) {
       var $bar = $(this)
         , newWidth = $bar.attr("data-bar-width");
       barGraph($bar, newWidth, 267);
   });
});

您可能还想将宽度选择移到barGraph函数中以保持清洁。

答案 4 :(得分:1)

与大多数jQuery的功能一样,css()适用于集合以及单个元素。由于$('.slider-box div')会返回一个集合,因此CSS规则将在each循环的每次迭代中应用于div的所有。因此,对于10个div,barGraph将被称为10×10 = 100次。并且因为div保持相同的顺序,所以最后一个div的newWidth将应用于所有div。

要仅将newWidth应用于each循环中的当前元素,您可以将所有逻辑保留在该函数中:

var $innerBar = $('.slider-box div');

$('.slider-box div').each(function(index, element) {
    var $this      = $(this);
    var innerWidth = ($this.attr("data-bar-width") / 10) || 0.5;
    var barWidth   = 267;

    innerWidth = Math.floor(innerWidth * barWidth);

    $this.css('width', innerWidth); // Note: no need to append 'px'; jQuery
});

只要逻辑很简单(最多几行)并且您不需要在其他地方使用它,这种方法效果很好。但是当你的代码变得有点复杂时,你可能想把它制成一个单独的函数。既然你已经完成了这个,那么让我们看看其他一些解决方案。

两种常见的解决方案:

  • Eiter:将当前元素作为函数的参数传递;
  • 或:将其变成jQuery插件。

第一个很简单:

function barGraph(element, innerWidth, barWidth) {
    var $this = $(element);
    // et cetera
}

// Call like this:
$('.slider-box div').each(function(index) {
    var newWidth = $(this).attr("data-bar-width");
    barGraph(this, newWidth, 267);
});
像我说的那样:简单。但它不是很整洁,是吗?第二种解决方案更优雅:

$.fn.barGraph = function(barWidth) {
    var $this      = this; // `this` is already a jQuery object
    var innerWidth = ($this.attr("data-bar-width") / 10) || 0.5;
    barWidth       = barWidth || 267;

    innerWidth = Math.floor(innerWidth * barWidth);

    $this.css('width', innerWidth);
};

// Use like this:
$('.slider-box div').each(function(index) {
    $(this).barGraph(267);
});

这就是编写自己的jQuery插件是多么容易!当然,它可以使用一些工作,例如更具描述性的名称和对chainability的支持。