455 lines
9.2 KiB
Markdown
455 lines
9.2 KiB
Markdown
|
---
|
|||
|
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("<b>nick</b>"); //每个p元素内后面追加内容
|
|||
|
|
|||
|
$("p").appendTo("div"); //p元素追加到div内后
|
|||
|
|
|||
|
$("p").prepend("<b>Hello</b>"); //每个p元素内前面追加内容
|
|||
|
|
|||
|
$("p").prependTo("div"); //p元素追加到div内前
|
|||
|
```
|
|||
|
|
|||
|
外部插入
|
|||
|
|
|||
|
```js
|
|||
|
$("p").after("<b>nick</b>"); //每个p元素同级之后插入内容
|
|||
|
|
|||
|
$("p").before("<b>nick</b>"); //在每个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
|
|||
|
<img src="https://www.runoob.com/images/pulpit.jpg" />
|
|||
|
<p tinyval="12"></p>
|
|||
|
```
|
|||
|
|
|||
|
```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"));
|
|||
|
```
|