抽象 是任何语言中一个重要的概念。 您可以将 CSS 视为将设计与网站内容分离的一种方式。 这使得两者的代码都更容易阅读、理解和维护。 Javascript 是一种将网站功能抽象化的方法,而 jQuery 则是进一步的抽象,使常见任务变得非常容易。 为 jQuery 编写插件是另一种更深层的抽象,它使您的 jQuery 更易于编写和理解。
为了说明这个想法,让我们构建一个 jQuery 插件。 既然我们要做,不妨做些有用的东西! 我们将其命名为 MaxSide。 这里的想法是获取任何页面元素并调整其大小,使其最长边的长度成为您确定的值。 例如,如果您的图像为 300x180px,您可以在其上调用 MaxSide 并设置值为 100,结果图像将变为 100x60px(它保持其比例)。
让我们开始吧。
不使用插件来实现
让我们在页面上放置三个图像,一个 200x200px,一个 200x50px,一个 50x200px。
<body>
<img src="images/200x200.jpg" alt="" />
<img src="images/200x50.jpg" alt="" />
<img src="images/50x200.jpg" alt="" />
</body>
我们希望对这些图像运行一些 jQuery,以便它们的每个最长边都变为 100。200x200px 变为 100x100px,200x50px 变为 100x25px,50x200px 变为 25x100px。
让我们在页面上包含 jQuery(在 <head> 部分)并编写使此代码生效的代码
<script type="text/javascript" src="../jquery-1.2.6.min.js"></script>
<script type="text/javascript">
// don't run until all images are loaded
$(window).bind("load", function() {
// run on every image on the page
$("img").each(function(){
// set a variable for this, quicker
var $this = $(this);
// maximum length is hard-coded here
var $maximum = 100;
// jQuery 1.2.6 has "dimensions" built-in
var $thewidth = $(this).width();
var $theheight = $(this).height();
if ($thewidth >= $theheight) {
if ($thewidth >= $maximum) {
$(this).attr({
width: $maximum
});
}
}
if ($theheight >= $thewidth) {
if ($theheight >= $maximum) {
$(this).attr({
height: $maximum
});
}
}
});
});
</script>
通俗地说,这段代码的意思是:“查看页面上的每个图像。 如果宽度大于高度,则将其宽度设置为 100。 如果高度大于宽度,则将其高度设置为 100。”
效果很好,请查看 不使用插件的示例。
使用插件来实现
不使用插件的方式存在一些问题。 首先,它会使我们的页面非常混乱。 我们应该将所有这些代码从 HTML 文件中移除,因为那里是我们的内容所在,并且我们正在尝试在这里进行抽象。 其次,“MaxSide” 在这里是硬编码的。 如果我们想在页面上使用相同的代码段,但使用不同的 MaxSide 值,该怎么办? 我们将不得不重复非常相似的代码。 这绝对不是一个好主意。
jQuery 使我们能够轻松地以插件的形式编写自己的函数,以抽象化此类代码。 请查看我们标题中使用插件的新代码
<script type="text/javascript" src="jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="jquery.maxside.js"></script>
<script type="text/javascript">
$(window).bind("load", function() {
$("img").maxSide({ maxSide: "100" });
});
</script>
是不是简单多了? 不仅更简单,而且现在我们可以在不同的页面元素上调用 maxSide 函数,并且可以使用不同的值。
jQuery.fn.maxSide = function(settings) {
// if no paramaters supplied...
settings = jQuery.extend({
maxSide: 100
}, settings);
return this.each(function(){
var maximum = settings.maxSide;
var thing = jQuery(this);
var thewidth = thing.width();
var theheight = thing.height();
if (thewidth >= theheight) {
if (thewidth >= maximum) {
thing.attr({
width: maximum
});
}
}
if (theheight >= thewidth) {
if (theheight >= maximum) {
thing.attr({
height: maximum
});
}
}
});
};
请注意,这里的代码实际上并没有太大区别。 不过,有一些重要的需要注意的地方。
- 此插件旨在对与您调用它匹配的每个页面元素执行其操作。 因此使用了“each” 函数。 如果您希望编写仅影响单个页面元素的插件,它会更容易。 省略“each” 函数并编写普通的 jQuery,但在最后添加一行“return this;”。
- 函数开头的“settings” 部分处理函数未传递参数的情况(它默认为 100px)。 如果需要,您可以仅使用 .maxSide(); 调用此函数。
- 如果将此函数用于图像,则应仅在窗口加载事件之后调用它。 许多 jQuery 函数是在 DOM 准备就绪时调用的,这样速度要快得多,但如果图像尚未完全加载(很有可能),则宽度和高度计算将失败。
- 插件中的变量不需要“$”。
简洁明了。 关于编写插件的绝佳教程。
$(window).bind(“load”, function() {
// 这里发生了一些事情
}
我需要让发生的事情在图像加载完成后发生,正如您所说,
但在 Firefox 中,它只是在 DOM 加载后发生(在图像加载之前)。
我主要使用 Opera,在那里一切正常。
PS:我的代码中的区别是我使用 CSS 将图像作为背景,因此 Opera 会将它们考虑在内,但 Firefox 不会。
如果要在 DOM 准备就绪时执行某些操作
如果要在页面加载时执行某些操作
您是说,即使使用这里面的第二个选项,它也执行得太早了吗? 如果是这样,那是一个有趣的问题,我从未遇到过。
是的,太早了。
但仅限 Firefox,Opera 和 IE 正常。 我想这仅适用于作为背景的图像(在我网站上,几乎所有图像都是背景)。
我还没有更新 Firefox - 我不太喜欢它 :)
哈,它在 Firefox3 中已修复。
好的,这很好……我不必编写一些奇怪的解决方案。
抱歉上条评论的拼写错误 :)
这个插件不错。 请注意,实际上下载页面显示 404 错误。 我不得不从示例页面下载 js 文件。
一些使用建议: 由于我尝试使用了一个大型 logo,想象一下在一个 logo 不能在上传之前调整大小并且可能非常大的地方使用此插件……加载页面时,会先出现大型图像版本,然后通过插件调整到正确的值。 如果您先给出 display:none 并在 $(“#logo”).maxSide({ maxSide: “xx” }); 后添加 $(“#logo”).show();,您的 logo 会在调整大小之前保持隐藏状态 :)
@Tinny: 当然,这是解决该问题的一种方法。 不过,如果用户禁用了 Javascript,那么他们根本看不到图像。 这取决于您的决定,但通常不是一个好主意。 另一种方法是在 DOM 准备就绪时隐藏图像,但仅在页面加载时调用 maxSize。
这是真的。 使用您的解决方案会非常完美。 也许在 show 之前调用 maxside 函数会更好(谈论的是毫秒……)。
一个不错的功能是针对宽度和高度设置不同的最大值。
出色的插件。 有没有办法修改它,以便它只调整大小超过特定宽度的图像? 例如,将任何宽度超过 300px 的图像调整为 300px 宽。 宽度小于 300px 的图像不调整大小。
这看起来很棒,并且非常接近我想要的功能。
有没有办法修改此代码以查找 div 中的所有图像,如果它们超过 600px 宽或对于包含 div 来说太宽,则将它们调整为仅 500px 宽并保持比例?
我一直到处寻找这种功能。
任何帮助将不胜感激! :)
AAron 我想您需要将此插件与尺寸插件 http://docs.jquery.com/Plugins/dimensions 结合起来,并对 div 中的所有图像进行 each 操作,然后根据大小执行 and if 操作
类似于
$.(“#IDOFTHEDIV”).children(“img”).each(function(){
if ((this).innerWidth() > 600)
{
$(this).maxSide({ maxSide: “500” });
}
});
没有尝试过,但我认为它应该可以工作
非常感谢 Tinny 的快速回复! 哇!
我已经下载了尺寸插件并尝试了上面的代码,但出现了错误。
这是我使用的代码。
jQuery(document).ready(function(){
$.(“.Content”).children(“img”).each(function(){
if ((this).innerWidth() > 550)
{
$(this).maxSide({ maxSide: 500 });
}
});
});
错误提示“Expected Identifier”,出现在第 5 行,即这一行
if ((this).innerWidth() > 550)
有任何想法或帮助吗? 我会非常感谢!
再次感谢您的帮助!
我刚意识到我还需要使用您的插件 maxside……哎呀!
但是……我已经包含了您的插件以及尺寸插件,并将调用更改为……
$(window).bind(“load”, function() {
$.(“.Content .p-20”).children(“img”).each(function(){
if ((this).innerWidth() > 550) {
$(this).maxSide({ maxSide: “500” });
}
});
});
但我仍然收到相同的错误。