发布时间:2025-12-10 11:27:19 浏览次数:6
$()函数其实是创建了一个jQuery对象. 这个函数接受CSS选择符作为参数,充当一个工厂, 返回包含页面中对应元素的jQuery对象. 所有能在样式表中使用的选择符都可以传给这个函数, 随后就可以对匹配的元素集合应用jQuery方法.
在jQuery中,美元符号$其实就是标示符jQuery的"别名".
更多的基于表单的选择符
:input:button:enabled:disabled:checked:selectedfilter方法
$('tr').filter(':even')$('a').filter(function(){return this.hostname && this.hostname!=location.hostname;}) //选择包含带有域名的href属性的,且域名不等于页面当前所在域的名称的a元素.next() //选择下一个最接近的同辈元素$('td:contains(Henry)').next().nextAll() //选择后面的全部同辈元素//对应方法 .prev().prevAll().siblings() //选择处于相同DOM层次的所有其他元素,无论这些元素处于当前元素之前还是之后.parent().children() //另一种方法
连缀方法的原理:
几乎所有的jQuery方法都会返回一个jQuery对象, 因而可连缀调用多个jQuery方法.
| .add() | 将元素添加到匹配元素的集合中。 |
| .andSelf() | 把堆栈中之前的元素集添加到当前集合中。 |
| .children() | 获得匹配元素集合中每个元素的所有子元素。 |
| .closest() | 从元素本身开始,逐级向上级元素匹配,并返回最先匹配的祖先元素。 |
| .contents() | 获得匹配元素集合中每个元素的子元素,包括文本和注释节点。 |
| .each() | 对 jQuery 对象进行迭代,为每个匹配元素执行函数。 |
| .end() | 结束当前链中最近的一次筛选操作,并将匹配元素集合返回到前一次的状态。 |
| .eq() | 将匹配元素集合缩减为位于指定索引的新元素。 |
| .filter() | 将匹配元素集合缩减为匹配选择器或匹配函数返回值的新元素。 |
| .find() | 获得当前匹配元素集合中每个元素的后代,由选择器进行筛选。 |
| .first() | 将匹配元素集合缩减为集合中的第一个元素。 |
| .has() | 将匹配元素集合缩减为包含特定元素的后代的集合。 |
| .is() | 根据选择器检查当前匹配元素集合,如果存在至少一个匹配元素,则返回 true。 |
| .last() | 将匹配元素集合缩减为集合中的最后一个元素。 |
| .map() | 把当前匹配集合中的每个元素传递给函数,产生包含返回值的新 jQuery 对象。 |
| .next() | 获得匹配元素集合中每个元素紧邻的同辈元素。 |
| .nextAll() | 获得匹配元素集合中每个元素之后的所有同辈元素,由选择器进行筛选(可选)。 |
| .nextUntil() | 获得每个元素之后所有的同辈元素,直到遇到匹配选择器的元素为止。 |
| .not() | 从匹配元素集合中删除元素。 |
| .offsetParent() | 获得用于定位的第一个父元素。 |
| .parent() | 获得当前匹配元素集合中每个元素的父元素,由选择器筛选(可选)。 |
| .parents() | 获得当前匹配元素集合中每个元素的祖先元素,由选择器筛选(可选)。 |
| .parentsUntil() | 获得当前匹配元素集合中每个元素的祖先元素,直到遇到匹配选择器的元素为止。 |
| .prev() | 获得匹配元素集合中每个元素紧邻的前一个同辈元素,由选择器筛选(可选)。 |
| .prevAll() | 获得匹配元素集合中每个元素之前的所有同辈元素,由选择器进行筛选(可选)。 |
| .prevUntil() | 获得每个元素之前所有的同辈元素,直到遇到匹配选择器的元素为止。 |
| .siblings() | 获得匹配元素集合中所有元素的同辈元素,由选择器筛选(可选)。 |
| .slice() | 将匹配元素集合缩减为指定范围的子集。 |
当使用 animate() 时,必须使用 Camel 标记法书写所有的属性名,比如,必须使用 paddingLeft 而不是 padding-left,使用 marginRight 而不是 margin-right,等等。
还可以用.animate()为同一组元素应用多重效果, 可以通过连缀这些效果来实现排队
每次触发值回调, 都会给它传入两个参数. 第一个参数是整数, 表示迭代次数. 第二个参数保存的是修改之前的属性的值, 这里并没有用到.
HTML属性和DOM属性:
在jQuery中, 可以通过.prop()方法取得和设置DOM属性:
//取得"checked"属性的当前值var currentChecked = $('.my-checkbox').prop('checked');//设置"checked"属性的值$('.my-checkbox').prop('checked', false);
HTML属性和DOM属性差别最大就数表单控件的值. 比如,文本输入框的value属性在DOM中的属性叫defaultValue, DOM中就没有value值. 而选项列表(select)元素, 其选项的值在DOM中通常是通过selectedIndex属性, 或者通过其选项元素的selected属性来取得.
由于存在这些差异, 在取得和设置表达控件值时,最好不要用.attr()方法. 而对于选项列表, 最好也不要用.prop()方法. 建议用jQuery提供的val()方法:
//取得文本输入框的当前值var inputValue = $('#my-input').val();//取得选项列表的当前值var selectValue = $('#my-select').val();//设置单选列表的值$('#my-single-select').val('value3');//设置多选列表的值$('#my-multi-select').val(['value1','value2']);| 1 2 3 | // Add "back to top" links. $('<a href="#top">back to top</a>').insertAfter('p.chapter p'); $('<a id="top"></a>').prependTo('body'); |
| 1 2 | // Create footnotes. $('span.footnote').<strong>insertBefore</strong>('#footer'); |
| 1 2 3 4 5 | // Create footnotes. $('span.footnote') .insertBefore('#footer') .<strong>wrapAll</strong>('<ol id="notes"></ol>') //把所有脚本都包含在一个<ol>中 .<strong>wrap</strong>('<li></li>') //把每一个脚注分布包装在自己的<li>中 |
用.each()方法作为显式迭代器, 为提取脚注的位置加标记和编码
| 1 2 3 | $('<p>Hello</p>').appendTo('#container'); //与下面的代码结果一样 $('#container').append('<p>Hello</p>'); |
所以上面的代码还可以写作:
| 1 2 3 4 5 6 7 8 | // Create footnotes. var $notes = $('<ol id="notes"></ol>').insertBefore('#footer'); $('span.footnote').each(function(index) { $(this) .before('<sup>' + (index + 1) + '</sup>') .appendTo($notes) .wrap('<li></li>'); }); |
| 1 | $('p.chapter p:eq(0').clone().insertBefore('p.chapter'); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | //要在html中创建新元素, 使用$()标签 //要在每个匹配的元素中插入新元素: .append() .appendTo() .prepend() .prependTo() //要在每个匹配的元素相邻的位置上插入新元素 .after() .insertAfter() .before() .insertBefore() //要在每个匹配的元素外部插入新元素 .wrap() .wrapAll() .wrapInner() //要用新元素或文本替换每个匹配的元素 .html() .text() .replaceAll() .replaceWith() //要移除每个匹配的元素中的元素 .empty() //要从文档中移除每个匹配的元素及其后代元素, 但不实际删除它们 .remove() .detach() |
Ajax实质: 就是一种无需刷新页面即可从服务器(或客户端)上加载数据的手段
$(document).ready(function() {$('#letter-a a').click(function(event) {event.preventDefault();$.ajaxSetup({ //$.ajaxSetup()函数可以修改调用Ajax方法时每个选项的默认值. //这个函数与$.ajax()接受相同的选项对象参数. 之后所有Ajax请求都使用传递给该函数的选项, 除非明确覆盖url: 'a.html',type: 'POST',dataType: 'html'});$.ajax({type: 'GET',success: function(data) {$('#dictionary').html(data);}});});$('#letter-b a').click(function(event) {event.preventDefault();$.getJSON('b.json', function(data) { //$.getJSON()方法会在取得相应文件后对文件进行处理. 在数据从服务器返回后, 它只是一个简单的JSON格式的文本字符串. //$.getJSON()方法会解析这个字符串, 并将处理得到的JavaScript对象提供给调用代码//接受两个参数, 第2个参数是当加载完成时调用的函数//$.getJSON()函数: 没有该方法适用的DOM元素;作为结果的对象只能提供给脚本,而不能插入到页面中.//getJSON()是作为全局jQuery对象(由jQuery库定义的jQuery或$对象)的方法定义的, 而不是个别jQuery对象实例的方法//可把getJSON()方法看做类方法, 称其为全局函数. 这些全局函数使用的是jQuery命名空间.var html = '';$.each(data, function(entryIndex, entry) { //$.each()函数不操作jQuery对象, 它以数组或对象作为第一个参数,以回调函数作为第二个参数. //此外还需要将每次循环中数组或对象的当前索引和当前项作为回调函数的两个参数html += '<p class="entry">';html += '<h3 class="term">' + entry.term + '</h3>';html += '<p class="part">' + entry.part + '</p>';html += '<p class="definition">';html += entry.definition;if (entry.quote) {html += '<p class="quote">';$.each(entry.quote, function(lineIndex, line) {html += '<p class="quote-line">' + line + '</p>';});if (entry.author) {html += '<p class="quote-author">' + entry.author + '</p>';}html += '</p>';}html += '</p>';html += '</p>';});$('#dictionary').html(html);});});$('#letter-c a').click(function(event) {event.preventDefault();$.getScript('c.js'); //$.getScript()也是一个全局函数. 接受一个url参数以查找脚本文件. //以这种方式取得的脚本会在全局环境下执行. 这意味着脚本有权访问在全局环境中定义的函数和变量, 当然也包括jQuery自身});$('#letter-d a').click(function(event) {event.preventDefault();$.get('d.xml', function(data) { //加载xml文档. //通常,$.get()函数只是取得由url指定的文件, 然后将纯文本格式的数据提供给回调函数. 但是在根据服务器提供的mine类型知道相应的是xml的情况下, 提供给回调函数的将是xml dom树$('#dictionary').empty();$(data).find('entry').each(function() {var $entry = $(this);var html = '<p class="entry">';html += '<h3 class="term">' + $entry.attr('term');html += '</h3>';html += '<p class="part">' + $entry.attr('part');html += '</p>';html += '<p class="definition">';html += $entry.find('definition').text(); //jQuery内部的选择符引擎, 对查找xml文档元素也有效var $quote = $entry.find('quote');if ($quote.length) {html += '<p class="quote">';$quote.find('line').each(function() {html += '<p class="quote-line">';html += $(this).text() + '</p>';});if ($quote.attr('author')) {html += '<p class="quote-author">';html += $quote.attr('author') + '</p>';}html += '</p>';}html += '</p>';html += '</p>';$('#dictionary').append($(html));});});});$('#letter-e a').click(function(event) {event.preventDefault(); //为了防止单击这些链接时打开新的url.//当默认动作是重新加载页面或重新打开新页面时, 推荐使用preventDefault()而不是return false结束该处理程序.//return false意味着同时调用event.preventDefault()和event.stopPropagation(), 因此想要阻止事件冒泡, 还得调用后者var requestData = {term: $(this).text()};$.get('e.php', requestData, function(data) { //向服务器传递数据. 第二个参数是一个用来构建查询关键字符串的键和值的对象.$('#dictionary').html(data);}).fail(function(jqXHR) {$('#dictionary').html('Sorry, but an error occurred: ' + jqXHR.status).append(jqXHR.responseText);});});$('#letter-f form').submit(function(event) {event.preventDefault();var formValues = $(this).serialize();$.get('f.php', formValues, function(data) {$('#dictionary').html(data);});});var url = 'http://examples.learningjquery.com/jsonp/g.php';$('#letter-g a').click(function(event) {event.preventDefault();$.getJSON(url + '?callback=?', function(data) { //使用JSONP加载远程数据, 实现跨域
为了防止jQuery的别名$已经被让渡出去, 可以在插件的作用域内定义这个快捷方式, 使用立即调用的函数表达式(IIFE, Immediately Invoked Function Expression)
| 1 2 3 | (function($){ //code here })(jQuery); |
所谓全局函数, 实际上就是jQuery对象的方法, 但从实践的角度上看,它们是位于jQuery命名空间内部的函数. 比如.ajax(),.each(), $.map().
给jQuery添加新的全局方法就是只要在第一节中的IIFE内部定义一个方法, 在函数外部就可以调用了. 因为它已经是jQuery的对象方法了. 比如:
/******************************************************************************Our plugin code comes first in this document. Normally, plugins wouldappear in separate files named jquery.plugin-name.js, but for our examplesit's convenient to place this plugin code in the same JavaScript file asthe code that calls it.******************************************************************************//******************************************************************************$.sum()Return the total of the numeric values in an array/object.******************************************************************************/(function($) {$.sum = function(array) {var total = 0;$.each(array, function(index, value) {value = $.trim(value);value = parseFloat(value) || 0;total += value;});return total;};$.average = function(array) {if ($.isArray(array)) {return $.sum(array) / array.length;}return '';};})(jQuery);/******************************************************************************End plugin code; begin custom script code.******************************************************************************/$(document).ready(function() {var $inventory = $('#inventory tbody');var quantities = $inventory.find('td:nth-child(2)').map(function(index, qty) {return $(qty).text();}).get();var sum = $.sum(quantities);$('#sum').find('td:nth-child(2)').text(sum);});
此外, 还可以利用$.extend()函数通过另一种语法定义全局函数:
(function($) {$.extend({sum: function(array) {var total = 0;$.each(array, function(index, value) {value = $.trim(value);value = parseFloat(value) || 0;total += value;});return total;},average: function(array) {if ($.isArray(array)) {return $.sum(array) / array.length;}return '';}});})(jQuery);
为了避免冲突, 可以把属于一个插件的全局对象都封装到一个对象中. 即使用命名空间隔离函数 .比如:
(function($) {$.mathUtils = {sum: function(array) {var total = 0;$.each(array, function(index, value) {value = $.trim(value);value = parseFloat(value) || 0;total += value;});return total;},average: function(array) {if ($.isArray(array)) {return $.mathUtils.sum(array) / array.length;}return '';}};})(jQuery);调用时需要:
var sum = $.mathUtils.sum(quantities);var average = $.mathUtils.average(prices);
这样, 就可以在插件方法上连缀内置方法了
所谓内部函数, 就是定义在另一个函数中的函数. 可以避免污染命名空间.
而JS中的内部函数可以逃脱定义它们的外部函数. 逃脱的方法有多种:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | var globalVar; function outerFn() { console.log('Outer function'); function innerFn() { console.log('Inner function'); } globalVar = innerFn; } console.log('outerFn():'); outerFn(); console.log('globalVar():'); globalVar(); |
| 1 2 3 4 5 6 7 8 9 10 11 | function outerFn() { console.log('Outer function'); function innerFn() { console.log('Inner function'); } return innerFn; } console.log('var fnRef = outerFn():'); var fnRef = outerFn(); //Outer function console.log('fnRef():'); fnRef();//Inner function |
当内部函数在定义它的作用域的外部被引出时, 就创建了该内部函数的一个闭包.
这种情况下, 我们称既不是内部函数局部变量, 也不是其参数的变量为自由变量, 称外部函数的调用环境为封闭闭包的环境. 从本质上将, 如果内部函数引用了位于外部函数中的变量, 相当于授权该变量能够被延迟使用. 因此, 当外部函数引用完成后, 这些变量的内存不会被释放, 因为闭包仍然需要使用它们.
依然要注意以下这个问题:
| 1 2 3 4 5 6 7 8 9 | $(document).ready(function($) { // Stuff to do as soon as the DOM is ready; for(var i=0; i<5; i++){ $('<p>Print ' + i + '</p>') .click(function(){ console.log(i); }).insertBefore('body'); } }); |
这里单击其中一项并不会看到相应的编号输出, 而是都会显示数值5. 即即使在绑定程序时i的值每次都不一样, 每个click处理程序最终引用的i都相同. 都等于单击事件实际发生时i的最终值(5).
要解决这个问题, 方法有:
这是因为函数的参数类似于在函数中定义的变量, 所以每次循环的value值实际上都是不同的变量. 结果, 每个click处理程序都指向一个不同的value变量, 因而每次单击输出的值会与元素的标签文本匹配.
| 1 2 3 4 5 6 7 8 9 10 | $(document).ready(function() { for(var i=0; i<5; i++){ (function(value){ $('<p>Print '+ value + '</p>') .click(function(){ console.log(value); }).insertBefore('body'); })(i); } }); |
因为event是函数的参数, 每次调用处理程序时它都是一个独立的实例, 而不是在所有调用中共享的一个值.
闭包可能会导致在不经意间创建引用u型拟合. 比如:
| 1 2 3 4 5 6 7 8 | function outerFn() { var outerVar = {}; function innerFn() { console.log(outerVar); } outerVar.fn = innerFn; return innerFn; }; |
这里innerFn()创建了一个引用outerVar的闭包, 而outerVar又引用了innerFn()
而更隐蔽的情形是:
| 1 2 3 4 5 6 7 8 | function outerFn() { var outerVar = {}; function innerFn() { <strong>console.log('hello');</strong> } outerVar.fn = innerFn; return innerFn; }; |
这里虽然innerFn()没有引用outerVar. 但是仍然没有断开循环. 即使innerFn()不再引用outerVar, outerVar也仍然位于innerFn()的封闭环境中. 由于闭包的原因, 位于outerFn()中的所有变量都隐含地被innerFn()所引用. 因此, 闭包会使意外地创建这些引用循环变得容易.
以上这种情况通常容易处理, 因为js能够检测到这些情况并在它们孤立时将其清除.
旧版本IE中存在的一种难以处理的引用循环问题. 当一个循环中同时包含DOM元素和常规JS元素时, IE无法释放任何一个对象----因为这两类对象是由不同的内存管理程序负责管理的. 即除非关闭浏览器, 否则这种循环在IE中永远得不到释放. 比如:
| 1 2 3 4 5 6 7 | $(document).ready(function() { var button = document.getElementById('button-1'); button.onclick = function() { console.log('hello'); return false; }; }); |
当指定单击事件处理程序时, 就创建了一个在其封闭的环境中包含button变量的闭包. 而且, 现在的button也包含一个指向闭包(onclick属性自身)的引用. 这样, 就导致了在IE中即使离开当前页面也不会释放这个循环.
为了释放内存, 就需要断开循环引用, 例如在关闭窗口关删除onclick属性. 另外, 可以向如下重写代码来避免:
| 1 2 3 4 5 6 7 8 | function hello() { console.log('hello'); return false; } $(document).ready(function() { var button = document.getElementById('button-1'); button.onclick = hello; }); |
这样,因为hello函数不再包含button, 引用就成了单向的(从button到hello), 不存在的循环, 就不会造成内存泄露了.
| 1 2 3 4 5 6 7 | $(document).ready(function() { var $button = $('#button-1'); $button.click(function(event) { event.preventDefault(); console.log('hello'); }); }); |
即使此时仍然会创建一个闭包, 并且也会导致同前面一样的循环, 但这里的代码却不会使IE发生内存泄露. 由于jQuery考虑到了内存泄露的潜在危害, 所以它会手动释放自己指定的所有事件处理程序.
另一种避免泄露的工具-----使用.data()方法可以像使用扩展属性一样, 将信息附加到DOM元素. 由于这里的数据并非直接保存在扩展属性中, 因此永远也不会构成引用循环.
http://www.cnblogs.com/haoyijing/p/5815647.html
转载于:https://www.cnblogs.com/Tanghongchang/p/7977028.html