选择的自由就是你得到的
自由选择是你想要的
-德沃,
“选择自由”
在前面的几章中,我们已经研究了许多类型的 jQuery 方法。然而,图书馆提供的一些方法迄今为止还无法进行分类。在本章中,我们将探讨可用于缩写常见 JavaScript 习惯用法的方法。
在主代码体开始之前,这些函数很有用。
| 包含有关当前运行的浏览器的信息。$.browser
|
没有一个
每个用户代理的布尔标志。
$.browser
属性允许我们检测浏览器本身报告的哪个 web 浏览器正在访问页面。它包含 Internet Explorer、Mozilla、Safari 和 Opera 这四种最流行的浏览器类别的标志。浏览器可以单独测试:
$()
.log('Safari: ' + $.browser.safari)
.log('Opera: ' + $.browser.opera)
.log('MSIE: ' + $.browser.msie)
.log('Mozilla: ' + $.browser.mozilla);
在 Firefox 浏览器上执行时,结果如下:
Safari: false
Opera: false
MSIE: false
Mozilla: true
此属性立即可用。因此,使用它来确定是否调用$(document).ready()
是安全的。
由于$.browser
使用navigator.useragent
确定平台,因此容易被用户欺骗。在可能的情况下,最好完全避免使用特定于浏览器的代码。在需要为不同代理编写的特殊情况下,最好的替代方法是测试您想要使用的 JavaScript 功能的存在。如果这不能很好地区分客户,$.browser
属性可用于进一步区分。
$.noConflict()
|
没有一个
全局 jQuery 对象。可将其设置为变量,以提供$
的替代快捷方式。
许多 JavaScript 库使用$
作为函数或变量名,就像 jQuery 一样。在 jQuery 的例子中,$
只是jQuery
的别名,因此所有功能都可以在不使用$
的情况下使用。如果我们需要在 jQuery 旁边使用另一个 JavaScript 库,我们可以通过调用$.noConflict()
将$
的控制权返回给另一个库:
// Import other library
// Import jQuery
$.noConflict();
// Code that uses other library’s $ can follow here.
与.ready()
方法对jQuery
对象进行别名的能力相结合,这种技术尤其有效,因为在.ready()
中,如果我们愿意,可以使用$
,而不必担心以后发生冲突:
// Import other library
// Import jQuery
$.noConflict();
jQuery(document).ready(function($) {
// Code that uses jQuery’s $ can follow here.
});
// Code that uses other library’s $ can follow here.
这些方法帮助我们处理每个 jQuery 对象下面的 DOM 元素。
| 返回 jQuery 对象匹配的 DOM 元素数。.length
|
没有一个
匹配的元素数。
假设页面上有一个简单的无序列表:
<ul>
<li>foo</li>
<li>bar</li>
</ul>
我们可以通过调用.length
来确定列表项的数量:
$().log('Length: ' + $('li’).length);
.size()
|
没有一个
匹配的元素数。
假设页面上有一个简单的无序列表:
<ul>
<li>foo</li>
<li>bar</li>
</ul>
我们可以通过调用.size()
来确定列表项的数量:
$().log('Size: ' + $('li’).size());
.get([index])
|
- 索引(可选):一个整数,指示要检索的元素
一个 DOM 元素,或一个 DOM 元素数组(如果省略索引)。
.get()
方法允许我们访问每个 jQuery 对象下面的 DOM 节点。假设页面上有一个简单的无序列表:
<ul>
<li>foo</li>
<li>bar</li>
</ul>
指定索引后,.get()
将检索单个元素:
$().log('Get(0): ' + $('li’).get(0));
由于索引是从零开始的,因此返回第一个列表项:
Get(0): [object HTMLLIElement]
每个 jQuery 对象也伪装成一个数组,因此我们可以使用数组解引用操作符来获取列表项:
$().log('Get(0): ' + $('li’)[0]);
不带参数,.get()返回常规数组中所有匹配的 DOM 节点:
$().log('Get(): ' + $('li’).get());
在我们的示例中,这意味着返回所有列表项:
Get(): [object HTMLLIElement],[object HTMLLIElement]
.index(node)
|
- node:要查找的 DOM 元素
元素在 jQuery 对象中的位置,如果找不到,则为-1
。
.get()
的补充操作,接受一个索引并返回一个 DOM 节点,.index()
接受一个 DOM 节点并返回一个索引。假设页面上有一个简单的无序列表:
<ul>
<li>foo</li>
<li>bar</li>
</ul>
如果检索两个列表项中的一个,则可以将其存储在变量中。然后.index()
可以在匹配的元素集中搜索该列表项:
var listItem = $('li’)[1];
$().log('Index: ' + $('li’).index(listItem));
我们返回列表项的从零开始的位置:
Index: 1
这些辅助函数操作数组、贴图和字符串。
| 迭代集合,对每个项启动回调函数。.each(callback)
$.each(collection, callback)
|
- 回调:为每个匹配元素执行的函数
jQuery 对象,用于链接目的。
- 集合:要迭代的对象或数组
- 回调:为集合中的每个项执行的函数
收藏。
.each()
方法和$.each()
函数是通用迭代器,旨在生成简洁且不易出错的循环结构。它们对集合进行操作,并对该集合中的每个项执行一次回调函数。
上面列出的第一个语法是 jQuery 对象的方法,当调用它时,它会迭代对象中的 DOM 元素。每次回调运行时,它都会作为参数传递当前循环迭代,从0
开始。更重要的是,回调是在当前 DOM 元素的上下文中触发的,因此关键字this
引用了该元素。
假设页面上有一个简单的无序列表:
<ul>
<li>foo</li>
<li>bar</li>
</ul>
我们可以选择列表项并遍历它们:
$('li’).each(function(index) {
$(this).log(index + ': ' + $(this).text());
});
因此,将为列表中的每个项目记录一条消息:
0: foo
1: bar
第二种语法类似,但它是一个全局函数,而不是一个方法。在本例中,集合作为第一个参数传递,可以是映射(JavaScript 对象)或数组。对于数组,每次回调都会传递一个数组索引和相应的数组值作为参数:
$.each([52, 97], function(key, value) {
$().log(key + ': ' + value);
});
这将产生两条消息:
0: 52
1: 97
如果将映射用作集合,则每次回调都会传递一个键值对作为参数:
$.each({'flammable’: 'inflammable’, 'duh’: 'no duh’}, function(index, value) {
$().log(index + ': ' + value);
});
这再次产生两条消息:
flammable: inflammable
duh: no duh
$.grep(array, filter[, invert])
|
- 数组:要搜索的数组
- 筛选器:应用于每个项的测试的函数,或包含用作测试的表达式的字符串
- 反转(可选):指示是否反转过滤条件的布尔值
新构造的过滤数组。
$.grep()
方法根据需要从数组中删除项,以便所有剩余项通过提供的测试。测试是一个函数,它通过数组项和数组中该项的索引作为参数传递;只有当测试返回 true 时,该项才会出现在结果数组中。
与 jQuery 方法一样,回调函数通常是匿名定义的:
var array = [0, 1, 52, 97];
$(this).log('Before: ' + array);
array = $.grep(array, function(a) {
return (a > 50);
});
$(this).log('After: ' + array);
超过50
的所有数组项都保留在结果数组中:
Before: 0,1,52,97
After: 52,97
由于筛选函数往往很短,jQuery 提供了进一步的快捷方式。过滤函数可以定义为单个表达式,该表达式针对数组中的每个项a
进行计算:
var array = [0, 1, 52, 97];
$(this).log('Before: ' + array);
array = $.grep(array, 'a > 50’);
$(this).log('After: ' + array);
这将产生与以前相同的结果。我们可以通过添加第三个参数来反转此测试:
var array = [0, 1, 52, 97];
$(this).log('Before: ' + array);
array = $.grep(array, 'a > 50’, true);
$(this).log('After: ' + array);
这将生成小于或等于50
的项目数组:
Before: 0,1,52,97
After: 0,1
$.map(array, filter)
|
- 数组:要转换的数组
- 筛选器:应用于每个项的函数,或包含要应用的表达式的字符串
新构造的转换数组。
$.map()
方法对数组中的每个项应用一个函数,将结果收集到一个新数组中。筛选器是一个函数,它将数组项和数组中该项的索引作为参数传递。
与 jQuery 方法一样,回调函数通常是匿名定义的:
var array = [0, 1, 52, 97];
$(this).log('Before: ' + array);
array = $.map(array, function(a) {
return (a - 45);
});
$(this).log('After: ' + array);
结果数组中所有数组项减少45
:
Before: 0,1,52,97
After: -45,-44,7,52
由于筛选函数往往很短,jQuery 提供了进一步的快捷方式。过滤函数可以定义为应用于数组中每个项a
的单个表达式:
var array = [0, 1, 52, 97];
$(this).log('Before: ' + array);
array = $.map(array, 'a - 45’);
$(this).log('After: ' + array);
这将产生与以前相同的结果。我们可以通过过滤函数返回null
从数组中删除项目:
var array = [0, 1, 52, 97];
$(this).log('Before: ' + array);
array = $.map(array, 'a > 50 ? a - 45 : null’);
$(this).log('After: ' + array);
这将产生一个大于50
的项目数组,每个项目减少45
:
Before: 0,1,52,97
After: 7,52
如果 filter 函数返回数组而不是标量,则返回的数组将连接在一起以形成结果:
var array = [0, 1, 52, 97];
$(this).log('Before: ' + array);
array = $.map(array, function(a, i) {
return [a - 45, i];
});
$(this).log('After: ' + array);
该贴图不是二维结果数组,而是一个展平的结果数组:
Before: 0,1,52,97
After: -45,0,-44,1,7,2,52,3
$.merge(array1, array2)
|
- array1:要合并的第一个数组
- array2:要合并的第二个数组
由两个提供的数组中的元素组成的数组。
$.merge()
操作形成一个数组,其中包含两个数组中的所有元素,并删除重复项。将保留第一个数组中的项目顺序,并附加第二个数组中的项目:
var array1 = [0, 1, 52];
var array2 = [52, 97];
$(this).log('Array 1: ' + array1);
$(this).log('Array 2: ' + array2);
array = $.merge(array1, array2);
$(this).log('After: ' + array);
结果数组包含所有四个不同的项:
Array 1: 0,1,52
Array 2: 52,97
After: 0,1,52,97
$.merge()
功能具有破坏性。它修改第一个参数以添加第二个参数中的项。如果您需要原始的第一个数组,请在调用$.merge()
之前复制它。幸运的是,$.merge()
本身可以用于此复制:
var newArray = $.merge([], oldArray);
此快捷方式创建一个新的空数组,并将oldArray
的内容合并到其中,从而有效地克隆数组。
$.unique(array)
|
- 数组:对象的数组
仅由唯一对象组成的数组。
$.unique()
函数搜索对象数组,形成一个不包含重复对象的新数组。如果两个对象引用内存中的不同位置,即使它们的内容相同,也会被认为是不同的。未修改原始数组。数组可以由任何类型的 JavaScript 对象组成:
var alice = {'alice’: 'alice’};
var bob = {'bob’: 'bob’};
var carol = {'carol’: 'carol’};
var ted = {'bob’: 'bob’};
var oldArray = [alice, bob, carol, bob, ted];
$(this).log('Before: ' + oldArray);
newArray = $.unique(oldArray);
$(this).log('After: ' + newArray);
结果数组仅包含四个不同的项:
Before: {alice: alice}, {bob: bob}, {carol: carol},
{bob: bob}, {bob: bob}
After: {alice: alice, mergeNum: 52}, {bob: bob, mergeNum: 52},
{carol: carol, mergeNum: 52}, {bob: bob, mergeNum: 52}
名为bob
的对象的第二个实例将从结果数组中删除。然而,名为ted
的对象仍然存在,即使它具有相同的内容,因为它是作为单独的对象创建的。
注意,$.unique()
修改数组中的对象,为每个对象添加一个名为mergeNum
的额外属性。此属性是函数实现的副作用,对调用代码没有用处。
$.extend([target, ]properties[, ...])
|
- 目标(可选):将接收新属性的对象
- 属性:包含要合并的其他属性的对象
修改后的目标对象。
$.extend()
函数以$.merge()
合并数组的相同方式合并两个对象。将第二个对象的特性添加到第一个对象,从而创建一个包含两个对象的所有特性的对象:
var object1 = {
apple: 0,
banana: 52,
cherry: 97
};
var object2 = {
banana: 1,
durian: 100
};
$().log(object1);
$().log(object2);
var object = $.extend(object1, object2);
$().log(object);
第二个对象中durian
的值与第一个对象相加,banana
的值被覆盖:
{apple: 0, banana: 52, cherry: 97, }
{banana: 1, durian: 100, }
{apple: 0, banana: 1, cherry: 97, durian: 100, }
$.extend()
功能具有破坏性;目标对象在此过程中被修改。这通常是理想的行为,因为$.extend()
可以用这种方式模拟对象继承。添加到对象的方法对于所有引用该对象的代码都可用。但是,如果我们希望保留这两个原始对象,可以通过传递一个空对象作为目标来实现:
var object = $.extend({}, object1, object2)
我们也可以向$.extend()
提供两个以上的对象。在这种情况下,所有对象的特性都将添加到目标对象中。
如果只向$.extend()
提供了一个参数,则表示忽略了目标参数。在本例中,假定 jQuery 对象本身是目标。通过这样做,我们可以向 jQuery 命名空间添加新函数。在讨论如何创建 jQuery 插件时,我们将探讨此功能。
$.extend()
执行的合并不是递归的;如果第一个对象的属性本身是对象或数组,它将被第二个对象中具有相同键的属性完全覆盖。这些值不会合并。
$.trim()
|
- 弦:要修剪的弦
修剪过的绳子。
$.trim()
函数删除所提供字符串开头和结尾的所有换行符、空格和制表符:
var string = "\tYes, no, I, this is. \n ";
$(this).log('Before: ' + string);
string = $.trim(string);
$(this).log('After: ' + string);
将修剪所有空白字符:
Before: Yes, no, I, this is.
After: Yes, no, I, this is.