我拼凑了这个jQuery函数。它的目的是计算div.article
内所有img元素的边距,以便平衡图像的高度与文档的基线网格,为20像素。为了匹配我的基线网格,每个图像高度应该是20的倍数。如果不是这种情况,例如一个图像的高度为154像素,该函数为img添加了6个像素的边距,以便恢复与基线网格的平衡。
该功能正常运行,所以我的实际问题是:由于我不是程序员,我想知道我的代码是否非常糟糕,尽管它有效,如果是的话,如何改进代码?
jQuery代码:
$('div.article img').each(function() {
// define line height of CSS baseline grid:
var line_height = 20;
// capture the height of the img:
var img_height = $(this).attr('height');
// divide img height by line height and round up to get the next integer:
var img_multiply = Math.ceil(img_height / line_height);
// calculate the img margin needed to balance the height with the baseline grid:
var img_margin = (img_multiply * line_height) - img_height;
// if calculated margin < 5 px:
if (img_margin < 5) {
// then add another 20 px to avoid too small whitespace:
img_margin = img_margin + 20;
}
// if img has caption:
if ($($(this)).next().length) {
// then apply margin to caption instead of img:
$($(this)).next().attr('style', "margin-bottom: " + img_margin + "px;");
} else {
// apply margin to img:
$(this).attr('style', "margin-bottom: " + img_margin + "px;");
}
});
HTML代码示例,img标题:
<div class="article">
<!-- [...] -->
<p class="image">
<img src="http://example.com/images/123.jpg" width="230" height="154" alt="Image alt text goes here" />
<small>Image Caption Goes Here</small>
</p>
<!-- [...] -->
</div>
HTML代码示例,img无标题:
<div class="article">
<!-- [...] -->
<p class="image">
<img src="http://example.com/images/123.jpg" width="230" height="154" alt="Image alt text goes here" />
</p>
<!-- [...] -->
</div>
编辑:基于Russ Cam建议的精炼代码:
var line_height = 20;
var min_margin = 5;
$('div.article img').each(function() {
var $this = $(this); // prefixed variable name with $ to remind it's a jQuery object
var img_height = $this.height();
var img_margin = ((Math.ceil(img_height / line_height)) * line_height) - img_height;
img_margin = (img_margin < min_margin)? img_margin + line_height : img_margin;
if ($this.next().length) {
$this.next().css({'margin-bottom' : img_margin + 'px'});
} else {
$this.css({'margin-bottom' : img_margin + 'px'});
}
});
答案 0 :(得分:12)
我可以推荐一些改进
1.cache $(this)
在each()
内的局部变量
$('div.article img').each(function() {
var $this = $(this); // prefixed variable name with $
// to remind it's a jQuery object
// ....
if ($this.next().length) {
// ....
}
});
2.而不是设置attr('style')
,请使用css()
命令
3.不需要这样做
$($(this))
虽然它不会破坏jQuery,但是将jQuery对象传递给另一个jQuery对象是不必要的。
4.使用$(this).height()
或$(this).outerHeight()
获取浏览器中元素的高度
5.不具体jQuery,但可以使用三元条件运算符来赋值
// if calculated margin < 5 px:
if (img_margin < 5) {
// then add another 20 px to avoid too small whitespace:
img_margin = img_margin + 20;
}
变为
// if calculated margin < 5 px then add another 20 px
// to avoid too small whitespace
img_margin = (img_margin < 5)? img_margin + 20 : img_margin;
6.正如Alex在评论中指出的那样,我还会删除那些仅仅重复代码告诉你的多余评论。即使这是调试脚本,在我看来,它们会降低可读性,而注释应仅用于提供读取代码时不具备的细节。
答案 1 :(得分:3)
代码很好。你可以做一些小的改进:
$(this)
。尽早将它分配给某些东西并使用它,这样你就不会反复扩展元素。$(this).attr('style', "margin-bottom: " + img_margin + "px;");
可以重写为someEl.css('margin-bottom', img_margin + 'px');
答案 2 :(得分:2)
无论如何,它可以重写得更短,比如
$('div.article').each(function() {
var img_margin = 20 - $(this).children('img:first').height() % 20;
if(img_margin < 5) img_margin += 20;
if($(this).children('small').length > 0)
$(this).children('small').attr('style', "margin-bottom: " + img_margin + "px;");
else
$(this).children('img').attr('style', "margin-bottom: " + img_margin + "px;");
}
答案 3 :(得分:2)
你不应该评论每一行来说明什么是hapening,代码应该告诉你发生了什么。 (除非这是一个非常奇怪的陈述)
应该使用评论告诉你为什么正在完成某些事情。
e.g:
// if img has caption:
if ($($(this)).next().length) {
// then apply margin to caption instead of img:
$($(this)).next().attr('style', "margin-bottom: " + img_margin + "px;");
} else {
// apply margin to img:
$(this).attr('style', "margin-bottom: " + img_margin + "px;");
}
可以改为,在我眼中更具可读性:
// if img has caption, apply margin to caption instead
if ($($(this)).next().length) {
$(this).next().css('margin-bottom', img_margin + 'px;');
} else {
$(this).css('margin-bottom', img_margin + 'px;');
}
答案 4 :(得分:1)
我认为你可以放弃
$($(this))
支持
$(this)
答案 5 :(得分:1)
加速和简化高度计算的方法是:
var img_margin = 20 - ($this.height() % 20);
至少应该有所帮助。
答案 6 :(得分:0)
这是我要做的,在评论中解释
$(function(){
// put this variable out of the loop since it is never modified
var line_height = 20;
$('div.article img').each(function() {
// cache $(this) so you don't have to re-access the DOM each time
var $this = $(this);
// capture the height of the img - use built-in height()
var img_height = $this.height();
// divide img height by line height and round up to get the next integer:
var img_multiply = Math.ceil(img_height / line_height);
// calculate the img margin needed to balance the height with the baseline grid:
var img_margin = (img_multiply * line_height) - img_height;
// if calculated margin < 5 px:
if (img_margin < 5) {
// then add another 20 px to avoid too small whitespace:
//use ternary operator for concision
img_margin += 20;
}
// if img has caption:
if ($this.next().length) {
// then apply margin to caption instead of img: - use built-in css() function
$this.next().css("margin-bottom", img_margin);
} else {
// apply margin to img: - use built-in css() function
$this.css("margin-bottom", img_margin);
}
});
});