--- title: jQuery categories: - Front-End status: done --- # 基础 在 `window` 对象中挂载了 `$`和`jQuery` ```js window.jQuery(); window.$ = window.jQuery; ``` # 模块化 ## 原始写法 只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块。 > 缺点很明显:"污染"了全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系。 ```js function m1() { //... } function m2() { //... } ``` ## 对象写法 把模块写成一个对象 > 写法会暴露所有模块成员,内部状态可以被外部改写。 ```js var module1 = new Object({ _count: 0, m1: function () { //... }, m2: function () { //... }, }); // 使用 module1.m1(); ``` ## IIFE 立即执行函数写法[推荐] > 外部代码无法读取内部的成员变量 ```js var module1 = (function () { var _count = 0; var m1 = function () { //... }; var m2 = function () { //... }; return { m1: m1, m2: m2, }; })(); console.info(module1._count); //undefined ``` ## (宽)放大模式 如果一个模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用"放大模式" ```js var module1 = (function (mod) { mod.m3 = function () { //... }; return mod; })(module1); ``` mod 可能存在异步,不知道内部哪个部分会先加载,如果采用上面的写法,第一个执行的部分有可能加载一个不存在空对象,这时就要采用"宽放大模式"。 ```js var module1 = (function (mod) { //... return mod; })(window.module1 || {}); ``` ## 输入全局变量[推荐] 为了在模块内部调用全局变量,必须显式地将其他变量输入模块 ```js var module1 = (function ($, YAHOO) { //... })(jQuery, YAHOO); ``` # 链式操作 ```js $('div').find('#child').addClass('red') // end() 函数返回上一级 $('div').find('#child').addClass('red').end().addClass('yellow') ``` # 选择器 ## 筛选器 ```js // $('li').first() $("li:first"); //第一个元素 // $('li').last() $("li:last"); //最后一个元素 $("tr:even"); //索引为偶数的元素,从 0 开始 $("tr:odd"); //索引为奇数的元素,从 0 开始 // $("tr").eq(1) $("tr:eq(1)"); //给定索引值的元素 $("tr:gt(0)"); //大于给定索引值的元素 $("tr:lt(2)"); //小于给定索引值的元素 $(":focus"); //当前获取焦点的元素 $(":animated"); //正在执行动画效果的元素 ``` ## 内容选择器 ```js $("div:contains('nick')"); //包含nick文本的元素 $("td:empty"); //不包含子元素或者文本的空元素 $("div:has(p)"); //含有选择器所匹配的元素 $("td:parent"); //含有子元素或者文本的元素 ``` ## 表单选择器 ```js $(":input"); //匹配所有 input, textarea, select 和 button 元素 $(":text"); //所有的单行文本框 $(":password"); //所有密码框 $(":radio"); //所有单选按钮 $(":checkbox"); //所有复选框 $(":submit"); //所有提交按钮 $(":reset"); //所有重置按钮 $(":button"); //所有button按钮 $(":file"); //所有文件域 $("input:radio[name=sex]:checked"); //所有name 尾input选中的元素 $("select option:selected"); //select中所有选中的option元素 ``` ## 查找 ```js $("#xxx"); //返回 一个 jquery 对象 $("#xxx").find(".xxx"); //查找#xxx里的.xxx元素 $("#xxx").parent(); //获取父类 $("#xxx").parents("xxx"); //获取xxx祖先 $("#xxx").children(); //获取子类 $("#xxx").siblings(); //获取同一父类的其他元素 $("#xxx").next(); //获取下一个元素 $("#xxx").prev(); //获取上一个元素 ``` ## 属性操作 ```js $("img").attr("src"); //返回文档中所有图像的src属性值 $("img").attr("src", "test.jpg"); //设置所有图像的src属性 $("img").removeAttr("src"); //将文档中图像的src属性删除 $("input[type='checkbox']").prop("checked", true); //选中复选框 $("input[type='checkbox']").prop("checked", false); $("img").removeProp("src"); //删除img的src属性 ``` ## css 操作 ```js $("p").addClass("selected"); //为p元素加上 'selected' 类 $("p").removeClass("selected"); //从p元素中删除 'selected' 类 $("p").toggleClass("selected"); //如果存在就删除,否则就添加 $("p").css("color"); //访问查看p元素的color属性 $("p").css("color", "red"); //设置p元素的color属性为red $("p").css({ color: "red", background: "yellow" }); // 设置多个属性 ``` ## 文档处理 内部插入 ```js $("p").append("nick"); //每个p元素内后面追加内容 $("p").appendTo("div"); //p元素追加到div内后 $("p").prepend("Hello"); //每个p元素内前面追加内容 $("p").prependTo("div"); //p元素追加到div内前 ``` 外部插入 ```js $("p").after("nick"); //每个p元素同级之后插入内容 $("p").before("nick"); //在每个p元素同级之前插入内容 $("p").insertAfter("#test"); //所有p元素插入到id为test元素的后面 $("p").insertBefore("#test"); //所有p元素插入到id为test元素的前面 ``` ## 复制 ```js $("p").clone(); //克隆元素并选中克隆的副本 $("p").clone(true); //布尔值指事件处理函数是否会被复制 ``` # attr 和 prop 区别 prop 和 attr 均可获取属性值,但 prop 获取的是 `DOM 对象内置属性`。 > !! 例如 input,radio,slect 元素,请使用 prop 获取 ```html
``` ```js // 因为页面源代码中没有设置 width 属性 $("img").attr("width"); // undefined $("img").prop("width"); // 284 // 由于 tinyval 并非 HTML 标准属性 $("p").prop("tinyval"); // undefined $("p").attr("tinyval"); // 12 ``` # 事件 ## 事件委托 - 可极大减少事件绑定次数,提高性能 - 可让动态加入的子元素绑定相同的命令 ```js function handleClick(event) { // this 表示当前单击的元素 alert($(this).html()); } // 把子级li元素的单击事件委托在父级ul身上 $("ul").delegate("li", "click", handleClick); ``` ## 单事件单元素 ```js function handleClick() {} $xxx.on("click", handleClick); ``` ## 单事件多元素 ```js function handleClick() {} $xxx.on("click", "#aaa, .bbb", handleClick); ``` ## 多事件多元素 ```js function handleClick() {} function handleMounseEnter() {} $xxx.on( { click: handleClick, mounseenter: handleMounseEnter, }, "#aaa, .bbb" ); ``` ## 一夜情事件 ```js function handleClick() {} $xxx.one("click", handleClick); ``` # 对象操作 ```js $.trim(); //去除字符串两端的空格 $.each(); //遍历一个数组或对象,for循环 $.inArray(); //返回一个值在数组中的索引位置,不存在返回-1 $.grep(); //返回数组中符合某种标准的元素 $.extend(true, {}, a, b); // 深浅拷贝合并 a、b 到 {} 上 $.makeArray(); //将对象转化为数组 $.type(); //判断对象的类别(函数对象、日期对象、数组对象、正则对象等等 $.isArray(); //判断某个参数是否为数组 $.isEmptyObject(); //判断某个对象是否为空(不含有任何属性) $.isFunction(); //判断某个参数是否为函数 $.isPlainObject(); //判断某个参数是否为用"{}"或"new Object"建立的对象 $.support(); //判断浏览器是否支持某个特性 ``` # 禁止右键功能菜单 ```js $(window).on({ contextmenu: function () { return false; }, keydown: function (e) { if (e.ctrlKey || (e.metaKey && (e.keyCode === 67 || e.keyCode === 8))) return false; }, }); ``` # 自动修改破损图像 ```js $("img").on("error", function () { $(this).prop("src", "img/broken.png"); }); ``` # 模块化 jquery 最佳实践 ```js // xx 视图模块 #xx (function ($, $view) { console.log($ + "has been imported"); // 缓存 dom需要用到的 dom,提高性能 var $partA = $view.find(".partA"), $partB = $view.find(".partB"); // 链式表结构,事件委托 $view .on("focus", "#btnFocusPartA", handleBtnFocusPartA) .on("click", ".btnClickPartB", handleBtnClickPartB); // 方法,建议函数式 function handleBtnFocusPartA() { console.log($partA + "handler"); } function handleBtnClickPartB(e) { console.log($partB + "handler", ",click 的 e.target" + e.target); } })(jQuery || window.jQuery || window.$, $("#viewModule")); ``` 更骚的`路由表`的写法,搭配模块化开发更优雅,更方便管理 ```js // xx 视图模块 #xx (function ($, $view) { console.log($ + "has been imported"); // 缓存 dom需要用到的 dom,提高性能 var $partA = $view.find(".partA"), $partB = $view.find(".partB"); // $view 视图的事件委托表 var eventTable = [ { name: "focus", elem: "#btnFocusPartA", handler: handleBtnFocusPartA, }, { name: "click", elem: ".btnClickPartB", handler: handleBtnClickPartB, }, ]; // 注册事件 eventTable.forEach(function (item) { $view.on(item.name, item.elem, item.handler); }); // 方法,建议函数式 function handleBtnFocusPartA() { console.log($partA + "handler"); } function handleBtnClickPartB(e) { console.log($partB + "handler", ",click 的 e.target" + e.target); } })(jQuery || window.jQuery || window.$, $("#viewModule")); ```