jQuery 中的设计模式和思想

参考资料:

jQuery 都过时了,那我还学它干嘛? - 方应杭

jQuery 设计思想 - 阮一峰的网络日志

jQuery Fundamentals - Bocoup

特殊函数 jQuery

window.jQuery(); // 提供的全局函数
  • jQuery(选择器)用来获取对应的元素
  • 但它却不返回这些元素
  • 相反,它返回一个 jQuery 构造出来的对象
  • 这个对象可以操作对应的元素

jQuery 是构造函数吗?

是: 因为 jQuery 函数确实构造出了一个对象.

不是: 因为不需要new jQuery()就能构造一个对象.

结论: jQuery 是一个不需要加 new 的构造函数

嫌 jQuery 太长?

还记得 bash alias 吗,添加一个别名即可: window.$ = window.jQuery

命名风格

  • 下面的代码令人误解:
const div = $(‘div#test')

我们会误以为 div 是一个 DOM,实际上 div 是 jQuery 构造的 api 对象,怎么避免这种误解呢?

  • 改成这样:
const $div = $(‘div#test')
// $div.appendChild不存在,因为它不是DOM对象
// $div.find存在,因为它是jQuery对象

链式操作

原理是因为每一步的 jQuery 操作,返回的都是一个 jQuery 对象,所以不同操作可以连在一起。

$("div")
  .find("h3")

  .eq(2)

  .html("Hi")

  .end() //退回到选中所有的h3元素的那一步

  .eq(0) //选中第一个h3元素

  .html("There"); //将它的内容改为World

选择元素

使用 CSS 选择器

$(document); //选择整个文档对象

$("#myId"); //选择ID为myId的网页元素

$("div.myClass"); // 选择class为myClass的div元素

$("input[name=first]"); // 选择name属性等于first的input元素

使用 jQuery 特有的表达式

$("a:first"); //选择网页中第一个a元素

$("tr:odd"); //选择表格的奇数行

$("#myForm :input"); // 选择表单中的input元素

$("div:visible"); //选择可见的div元素

$("div:gt(2)"); // 选择所有的div元素,除了前三个

$("div:animated"); // 选择当前处于动画状态的div元素

筛选结果集

$("div").has("p"); // 选择包含p元素的div元素

$("div").not(".myClass"); //选择class不等于myClass的div元素

$("div").filter(".myClass"); //选择class等于myClass的div元素

$("div").first(); //选择第1个div元素

.eq(5); //选择第6个div元素

根据结果集,移动到附近的相关元素

在 DOM 树上的移动方法

$("div").next("p"); //选择div元素后面的第一个p元素

$("div").parent(); //选择div元素的父元素

$("div").closest("form"); //选择离div最近的那个form父元素

$("div").children(); //选择div的所有子元素

$("div").siblings(); //选择div的同级元素

getter & setter

使用同一个重载来完成取值(getter)和赋值(setter)

$("h1").html(); //html()没有参数,表示取出h1的值

$("h1").html("Hello"); //html()有参数Hello,表示对h1进行赋值

移动元素

// 把div元素移动p元素后面
$("div").insertAfter($("p"));
// 把p元素加到div元素前面
$("p").after($("div"));

实际上,两种方法返回的元素不一样。第一种方法返回 div 元素,第二种方法返回 p 元素。

// 其他操作方法
// 在现存元素的外部,从后面插入元素
.insertAfter()
.after()
// 在现存元素的外部,从前面插入元素
.insertBefore()
.before()
// 在现存元素的内部,从后面插入元素
.appendTo()
.append()
// 在现存元素的内部,从前面插入元素
.prependTo()
.prepend()

复制、删除和创建元素

// 复制元素
.clone()
// 删除元素
.remove() // 不保留被删除元素的事件
.detach() // 留被删除元素的事件,有利于重新插入文档时使用
// 清空元素内容但是不删除元素
.empty()
// 创建新元素,直接把新元素直接传入jQuery的构造函数
$("<p>Hello</p>");
$("<li class=“new”>new list item</li>");
$("ul").append("<li>list item</li>");

jQuery 中的设计模式

发布订阅模式

var eventHub = $({});
eventHub.on("xxx", function () {
  console.log("收到");
});
eventHub.trigger("xxx");

用原型继承实现插件系统

$.fn.modal = function(){ ... }
$("#div1").modal()

事件委托

$("div").on("click", "span", function(){…})

链式调用

前文提到过

$("div").text("hi").addClass("red").animate({ left: 100 });

函数重载

$(fn);
$("div");
$(div);
$($(div));
$("span", "#scope1");

命名空间

// 你的插件在一个 button 上绑定了很多事件
$button.on("click.plugin", function(){…})
$button.on("mouseenter.plugin", function(){…})
// 然后你想在某个时刻移除以上所有事件
$button.off(".plugin")

此时利用 jQuery 会很简单

jQuery API: jQuery API Documentation

comments powered by Disqus