我有一个简单的函数,可以根据参数设置条形的宽度。
我用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的宽度的功能吗?
非常感谢,
亚当。
答案 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
});
只要逻辑很简单(最多几行)并且您不需要在其他地方使用它,这种方法效果很好。但是当你的代码变得有点复杂时,你可能想把它制成一个单独的函数。既然你已经完成了这个,那么让我们看看其他一些解决方案。
两种常见的解决方案:
第一个很简单:
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的支持。