内容 | 网址 |
---|---|
JavaScript个人学习笔记总结 - 快速入门 | https://blog.csdn.net/weixin_50594210/article/details/115112096 |
JavaScript个人学习笔记总结 - 函数 | https://blog.csdn.net/weixin_50594210/article/details/115113081 |
JavaScript个人学习笔记总结 - 标准对象 | https://blog.csdn.net/weixin_50594210/article/details/115112683 |
JavaScript个人学习笔记总结 - 面向对象编程 | https://blog.csdn.net/weixin_50594210/article/details/115113024 |
JavaScript个人学习笔记总结 - 浏览器 | https://blog.csdn.net/weixin_50594210/article/details/115113131 |
JavaScript个人学习笔记总结 - jQuery | https://blog.csdn.net/weixin_50594210/article/details/115113299 |
JavaScript个人学习笔记总结 - 错误处理 | https://blog.csdn.net/weixin_50594210/article/details/115113442 |
JavaScript个人学习笔记总结 - underscore | https://blog.csdn.net/weixin_50594210/article/details/115113498 |
文章目录
jQuery
- jQuery 是一个 JavaScript 库。
- 所谓的库,就是一个 JS 文件,里面封装了很多预定义的函数,比如获取元素,执行隐藏、移动等,目的就 是在 使用时直接调用,不需要再重复定义,这样就可以极大地简化了 JavaScript 编程。
- jQuery 官网:https://www.jquery.com
jQuery这么流行,肯定是因为它解决了一些很重要的问题。实际上,jQuery能帮我们干这些事情:
- 消除浏览器差异:你不需要自己写冗长的代码来针对不同的浏览器来绑定事件,编写AJAX等代码;
- 简洁的操作DOM的方法:写
$('#test')
肯定比document.getElementById('test')
来得简洁; - 轻松实现动画、修改CSS等各种操作。
jQuery的理念“Write Less, Do More“,让你写更少的代码,完成更多的工作!
使用jQuery只需要在页面的<head>
引入jQuery文件即可。
$符号
$
是著名的jQuery
符号。实际上,jQuery
把所有功能全部封装在一个全局变量jQuery中,而$
也是一个合法的变量名,它是变量jQuery
的别名:
<script>
window.jQuery; // jQuery(selector, context)
window.$; // jQuery(selector, context)
$ === jQuery; // true
typeof($); // 'function'
</script>
$
本质上就是一个函数,但是函数也是对象,于是$
除了可以直接调用外,也可以有很多其他属性。
注意 ,你看到的$
函数名可能不是jQuery(selector, context)
,因为很多JavaScript压缩工具可以对函数名和参数改名,所以压缩过的jQuery源码$
函数可能变成a(b, c)
。
绝大多数时候,我们都直接用$
(因为写起来更简单嘛)。但是,如果$
这个变量不幸地被占用了,而且还不能改,那我们就只能让jQuery
把$
变量交出来,然后就只能使用jQuery
这个变量:
<script>
$; // jQuery(selector, context)
jQuery.noConflict();
$; // undefined
jQuery; // jQuery(selector, context)
</script>
这种黑魔法的原理是jQuery
在占用$
之前,先在内部保存了原来的$
,调用jQuery.noConflict()
时会把原来保存的变量还原。
快速入门:
- 编写 HTML 文档。
- 引入 jQuery 文件。
- 使用 jQuery 获取元素。
- 使用浏览器测试
<script>
// JS方式,通过id属性值来获取div元素
let jsDiv = document.getElementById("div");
//alert(jsDiv);
// alert(jsDiv.innerHTML);
// jQuery方式,通过id属性值来获取div元素
let jqDiv = $("#div");
//alert(jqDiv);
//alert(jqDiv.innerHTML);
</script>
<script>
// JS方式,通过id属性值来获取div元素
let jsDivs = document.getElementsByTagName("div");
// jQuery方式,通过id属性值来获取div元素
let jqDiv = $("#div");//
alert(jsDivs);
alert(jqDiv);
</script>
1、选择器
选择器是jQuery的核心。一个选择器写出来类似$(’#dom-id’)。
// 按ID查找:
var a = document.getElementById('dom-id');
// 按tag查找:
var divs = document.getElementsByTagName('div');
// 查找<p class="red">:
var ps = document.getElementsByTagName('p');
// 过滤出class="red":
// TODO:
// 查找<table class="green">里面的所有<tr>:
var table = ...
for (var i=0; i<table.children; i++) {
// TODO: 过滤出<tr>
}
这些代码实在太繁琐了,并且,在层级关系中,例如,查找<table class="green">
里面的所有,一层循环实际上是错的,因为<table>
的标准写法是:
<table>
<tbody>
<tr>...</tr>
<tr>...</tr>
</tbody>
</table>
很多时候,需要递归查找所有子节点。
jQuery的选择器就是帮助我们快速定位到一个或多个DOM节点。
按ID查找
如果某个DOM节点有id属性,利用jQuery查找如下:
// 查找<div id="abc">:
var div = $('#abc');
注意,#abc
以#
开头。返回的对象是jQuery对象。
什么是jQuery对象?jQuery对象类似数组,它的每个元素都是一个引用了DOM节点的对象。
以上面的查找为例,如果id
为abc
的<div>
存在,返回的jQuery对象如下:
[<div id="abc">...</div>]
如果id
为abc
的<div>
不存在,返回的jQuery对象如下:
[]
总之jQuery的选择器不会返回undefined
或者null
,这样的好处是你不必在下一行判断if (div === undefined)
。
jQuery对象和DOM对象之间可以互相转化:
var div = $('#abc'); // jQuery对象
var divDom = div.get(0); // 假设存在div,获取第1个DOM元素
var another = $(divDom); // 重新把DOM包装为jQuery对象
通常情况下你不需要获取DOM对象,直接使用jQuery对象更加方便。如果你拿到了一个DOM对象,那可以简单地调用$(aDomObject)
把它变成jQuery对象,这样就可以方便地使用jQuery的API了。
按tag查找
按tag查找只需要写上tag名称就可以了:
var ps = $('p'); // 返回所有<p>节点
ps.length; // 数一数页面有多少个<p>节点
按class查找
按class查找注意在class名称前加一个.:
var a = $('.red'); // 所有节点包含`class="red"`都将返回
// 例如:
// <div class="red">...</div>
// <p class="green red">...</p>
通常很多节点有多个class,我们可以查找同时包含red和green的节点:
var a = $('.red.green'); // 注意没有空格!
// 符合条件的节点:
// <div class="red green">...</div>
// <div class="blue green red">...</div>
按属性查找
一个DOM节点除了id
和class
外还可以有很多属性,很多时候按属性查找会非常方便,比如在一个表单中按属性来查找:
var email = $('[name=email]'); // 找出<??? name="email">
var passwordInput = $('[type=password]'); // 找出<??? type="password">
var a = $('[items="A B"]'); // 找出<??? items="A B">
当属性的值包含空格等特殊字符时,需要用双引号括起来。
按属性查找还可以使用前缀查找或者后缀查找:
var icons = $('[name^=icon]'); // 找出所有name属性值以icon开头的DOM
// 例如: name="icon-1", name="icon-2"
var names = $('[name$=with]'); // 找出所有name属性值以with结尾的DOM
// 例如: name="startswith", name="endswith"
这个方法尤其适合通过class属性查找,且不受class包含多个名称的影响:
var icons = $('[class^="icon-"]'); // 找出所有class包含至少一个以`icon-`开头的DOM
// 例如: class="icon-clock", class="abc icon-home"
组合查找
组合查找就是把上述简单选择器组合起来使用。如果我们查找$('[name=email]')
,很可能把表单外的<div name="email">
也找出来,但我们只希望查找<input>
,就可以这么写:
var emailInput = $('input[name=email]'); // 不会找出<div name="email">
同样的,根据tag和class来组合查找也很常见:
var tr = $('tr.red'); // 找出<tr class="red ...">...</tr>
多项选择器
多项选择器就是把多个选择器用,组合起来一块选:
$('p,div'); // 把<p>和<div>都选出来
$('p.red,p.green'); // 把<p class="red">和<p class="green">都选出来
要注意的是,选出来的元素是按照它们在HTML中出现的顺序排列的,而且不会有重复元素。例如,<p class="red green">
不会被上面的$('p.red,p.green')
选择两次。
1.1 层级选择器
<script>
// 1. 后代选择器 $("A B"); A下的所有B(包括B的子级,子子孙孙)
let spans1 = $("div span");
//alert(spans1.length);
// 2. 子选择器 $("A > B"); A下的所有B(不包括B的子级,只有儿子)
let spans2 = $("div > span");
//alert(spans2.length);
// 3. 兄弟选择器 $("A + B"); A紧挨着的的下一个B
let ps1 = $("div + p");
//alert(ps1.length);
// 4. 兄弟选择器 $("A ~ B"); A同级(下边)的所有B
let ps2 = $("div ~ p");
alert(ps2.length);
</script>
如果两个DOM元素具有层级关系,就可以用$(‘ancestor descendant’)来选择,层级之间用空格隔开。例如:
<!-- HTML结构 -->
<div class="testing">
<ul class="lang">
<li class="lang-javascript">JavaScript</li>
<li class="lang-python">Python</li>
<li class="lang-lua">Lua</li>
</ul>
</div>
要选出JavaScript,可以用层级选择器:
$('ul.lang li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
$('div.testing li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
因为<div>
和<ul>
都是<li>
的祖先节点,所以上面两种方式都可以选出相应的<li>
节点。
要选择所有的<li>
节点,用:
$('ul.lang li');
这种层级选择器相比单个的选择器好处在于,它缩小了选择范围,因为首先要定位父节点,才能选择相应的子节点,这样避免了页面其他不相关的元素。
例如:
$('form[name=upload] input');
就把选择范围限定在name
属性为upload
的表单里。如果页面有很多表单,其他表单的<input>
不会被选择。
多层选择也是允许的:
$('form.test p input'); // 在form表单选择被<p>包含的<input>
子选择器(Child Selector)
子选择器$('parent>child')
类似层级选择器,但是限定了层级关系必须是父子关系,就是<child>
节点必须是<parent>
节点的直属子节点。还是以上面的例子:
$('ul.lang>li.lang-javascript'); // 可以选出[<li class="lang-javascript">JavaScript</li>]
$('div.testing>li.lang-javascript'); // [], 无法选出,因为<div>和<li>不构成父子关系
过滤器(Filter)
过滤器一般不单独使用,它通常附加在选择器上,帮助我们更精确地定位元素。观察过滤器的效果:
<script>
$('ul.lang li'); // 选出JavaScript、Python和Lua 3个节点
$('ul.lang li:first-child'); // 仅选出JavaScript
$('ul.lang li:last-child'); // 仅选出Lua
$('ul.lang li:nth-child(2)'); // 选出第N个元素,N从1开始
$('ul.lang li:nth-child(even)'); // 选出序号为偶数的元素
$('ul.lang li:nth-child(odd)'); // 选出序号为奇数的元素
</script>
表单相关
针对表单元素,jQuery还有一组特殊的选择器:
:input
:可以选择<input>
,<textarea>
,<select>
和<button>
;:file
:可以选择<input type="file">
,和input[type=file]
一样;:checkbox
:可以选择复选框,和input[type=checkbox]
一样;:radio
:可以选择单选框,和input[type=radio]
一样;:focus
:可以选择当前输入焦点的元素,例如把光标放到一个<input>
上,用$('input:focus')
就可以选出;:checked
:选择当前勾上的单选框和复选框,用这个选择器可以立刻获得用户选择的项目,如$('input[type=radio]:checked')
;:enabled
:可以选择可以正常输入的<input>
、<select>
等,也就是没有灰掉的输入;:disabled
:和:enabled
正好相反,选择那些不能输入的。
此外,jQuery还有很多有用的选择器,例如,选出可见的或隐藏的元素:
$('div:visible'); // 所有可见的div
$('div:hidden'); // 所有隐藏的div
1.2 过滤器选择器
<script>
// 1.首元素选择器 $("A:first");
let div1 = $("div:first");
alert(div1.html()); //div1
// 2.尾元素选择器 $("A:last");
let div4 = $("div:last");
alert(div4.html()); //div4
// 3.非元素选择器 $("A:not(B)");
let divs1 = $("div:not(#div2)");
alert(divs1.length); //3
// 4.偶数选择器 $("A:even");
let divs2 = $("div:even");
alert(divs2.length); //2
alert(divs2[0].innerHTML); //div1
alert(divs2[1].innerHTML); //div3
// 5.奇数选择器 $("A:odd");
let divs3 = $("div:odd");
alert(divs3.length); //2
alert(divs3[0].innerHTML); //div2
alert(divs3[1].innerHTML); //div4
// 6.等于索引选择器 $("A:eq(index)");
let div3 = $("div:eq(1)"); // equals
//alert(div3.html());
// 7.大于索引选择器 $("A:gt(index)");
let divs4 = $("div:gt(1)"); //
//alert(divs4.length);
//alert(divs4[0].innerHTML);
//alert(divs4[1].innerHTML);
// 8.小于索引选择器 $("A:lt(index)");
let divs5 = $("div:lt(2)");
// alert(divs5.length);
// alert(divs5[0].innerHTML);
// alert(divs5[1].innerHTML);
//9 多个 混合使用
$("div:lt(5):gt(3)");
</script>
1.3 基本选择器
- 选择器:类似于 CSS 的选择器,可以帮助我们获取元素。
- 例如:id 选择器、类选择器、元素选择器、属性选择器等等。
- jQuery 中选择器的语法:$();
<script>
//1.元素选择器 $("元素的名称")
let divs = $("div");
//alert(divs.length);
//2.id选择器 $("#id的属性值")
let div1 = $("#div1");
//alert(div1);
//3.类选择器 $(".class的属性值")
let cls = $(".cls");
alert(cls.length);
</script>
1.4 属性选择器
<script>
//1.属性名选择器 $("元素[属性名]")
let in1 = $("input[type]");
//alert(in1.length);
//2.属性值选择器 $("元素[属性名=属性值]")
let in2 = $("input[type='password']");
alert(in2.length);
</script>
1.5 表单属性选择器
<script>
// 1.可用元素选择器 $("A:enabled");
let ins1 = $("input:enabled");
alert(ins1.length);
// 2.不可用元素选择器 $("A:disabled");
let ins2 = $("input:disabled");
//alert(ins2.length);
// 3.单选/复选框被选中的元素 $("A:checked");
let ins3 = $("input:checked");
//alert(ins3.length);
//alert(ins3[0].value);
//alert(ins3[1].value);
//alert(ins3[2].value);
// 4.下拉框被选中的元素 $("A:selected");
let select = $("select option:selected");
alert(select.html());
</script>
2、操作DOM
修改Text和HTML
jQuery对象的text()和html()方法分别获取节点的文本和原始HTML文本,例如,如下的HTML结构:
<!-- HTML结构 -->
<ul id="test-ul">
<li class="js">JavaScript</li>
<li name="book">Java & JavaScript</li>
</ul>
分别获取文本和HTML:
$('#test-ul li[name=book]').text(); // 'Java & JavaScript'
$('#test-ul li[name=book]').html(); // 'Java & JavaScript'
一个jQuery对象可以包含0个或任意个DOM对象,它的方法实际上会作用在对应的每个DOM节点上。在上面的例子中试试:
$('#test-ul li').text('JS'); // 是不是两个节点都变成了JS?
所以jQuery对象的另一个好处是我们可以执行一个操作,作用在对应的一组DOM节点上。即使选择器没有返回任何DOM节点,调用jQuery对象的方法仍然不会报错:
// 如果不存在id为not-exist的节点:
$('#not-exist').text('Hello'); // 代码不报错,没有节点被设置为'Hello'
这意味着jQuery帮你免去了许多if
语句。
修改CSS
jQuery对象有“批量操作”的特点,这用于修改CSS实在是太方便了。考虑下面的HTML结构:
<!-- HTML结构 -->
<ul id="test-css">
<li class="lang dy"><span>JavaScript</span></li>
<li class="lang"><span>Java</span></li>
<li class="lang dy"><span>Python</span></li>
<li class="lang"><span>Swift</span></li>
<li class="lang dy"><span>Scheme</span></li>
</ul>
要高亮显示动态语言,调用jQuery对象的css(‘name’, ‘value’)方法。
注意
,jQuery对象的所有方法都返回一个jQuery对象(可能是新的也可能是自身),这样我们可以进行链式调用,非常方便。
jQuery对象的css()方法可以这么用:
var div = $('#test-div');
div.css('color'); // '#000033', 获取CSS属性
div.css('color', '#336699'); // 设置CSS属性
div.css('color', ''); // 清除CSS属性
为了和JavaScript保持一致,CSS属性可以用'background-color'
和’backgroundColor
’两种格式。
css()
方法将作用于DOM节点的style
属性,具有最高优先级。如果要修改class
属性,可以用jQuery提供的下列方法:
var div = $('#test-div');
div.hasClass('highlight'); // false, class是否包含highlight
div.addClass('highlight'); // 添加highlight这个class
div.removeClass('highlight'); // 删除highlight这个class
显示和隐藏DOM
要隐藏一个DOM,我们可以设置CSS的display
属性为none
,利用css()
方法就可以实现。不过,要显示这个DOM就需要恢复原有的display属性,这就得先记下来原有的display
属性到底是block
还是inline
还是别的值。
考虑到显示和隐藏DOM元素使用非常普遍,jQuery直接提供show()
和hide()
方法,我们不用关心它是如何修改display
属性的,总之它能正常工作:
v
ar a = $('a[target=_blank]');
a.hide(); // 隐藏
a.show(); // 显示
注意
,隐藏DOM节点并未改变DOM树的结构,它只影响DOM节点的显示。这和删除DOM节点是不同的。
获取DOM信息
利用jQuery对象的若干方法,我们直接可以获取DOM的高宽等信息,而无需针对不同浏览器编写特定代码:
<script>
// 浏览器可视窗口大小:
$(window).width(); // 800
$(window).height(); // 600
// HTML文档大小:
$(document).width(); // 800
$(document).height(); // 3500
// 某个div的大小:
var div = $('#test-div');
div.width(); // 600
div.height(); // 300
div.width(400); // 设置CSS属性 width: 400px,是否生效要看CSS是否有效
div.height('200px'); // 设置CSS属性 height: 200px,是否生效要看CSS是否有效
</script>
attr()
和removeAttr()
方法用于操作DOM节点的属性:
<script>
// <div id="test-div" name="Test" start="1">...</div>
var div = $('#test-div');
div.attr('data'); // undefined, 属性不存在
div.attr('name'); // 'Test'
div.attr('name', 'Hello'); // div的name属性变为'Hello'
div.removeAttr('name'); // 删除name属性
div.attr('name'); // undefined
</script>
prop()
方法和attr()
类似,但是HTML5规定有一种属性在DOM节点中可以没有值,只有出现与不出现两种,例如:
<input id="test-radio" type="radio" name="test" checked value="1">
等价于:
<input id="test-radio" type="radio" name="test" checked="checked" value="1">
attr()
和prop()
对于属性checked
处理有所不同:
var radio = $('#test-radio');
radio.attr('checked'); // 'checked'
radio.prop('checked'); // true
prop()
返回值更合理一些。不过,用is()方法判断更好:
var radio = $('#test-radio');
radio.is(':checked'); // true
类似的属性还有selected
,处理时最好用is(':selected')
。
操作表单
对于表单元素,jQuery对象统一提供val()方法获取和设置对应的value属性:
<script>
/*
<input id="test-input" name="email" value="">
<select id="test-select" name="city">
<option value="BJ" selected>Beijing</option>
<option value="SH">Shanghai</option>
<option value="SZ">Shenzhen</option>
</select>
<textarea id="test-textarea">Hello</textarea>
*/
var
input = $('#test-input'),
select = $('#test-select'),
textarea = $('#test-textarea');
input.val(); // 'test'
input.val('abc@example.com'); // 文本框的内容已变为abc@example.com
select.val(); // 'BJ'
select.val('SH'); // 选择框已变为Shanghai
textarea.val(); // 'Hello'
textarea.val('Hi'); // 文本区域已更新为'Hi'
</script>
可见,一个val()
就统一了各种输入框的取值和赋值的问题。
2.1 修改DOM结构
添加DOM
要添加新的DOM节点,除了通过jQuery的html()
这种暴力方法外,还可以用append()
方法,例如:
<div id="test-div">
<ul>
<li><span>JavaScript</span></li>
<li><span>Python</span></li>
<li><span>Swift</span></li>
</ul>
</div>
如何向列表新增一个语言?首先要拿到<ul>
节点:
var ul = $('#test-div>ul');
然后,调用append()
传入HTML片段:
ul.append('<li><span>Haskell</span></li>');
除了接受字符串,append()
还可以传入原始的DOM对象,jQuery对象和函数对象:
// 创建DOM对象:
var ps = document.createElement('li');
ps.innerHTML = '<span>Pascal</span>';
// 添加DOM对象:
ul.append(ps);
// 添加jQuery对象:
ul.append($('#scheme'));
// 添加函数对象:
ul.append(function (index, html) {
return '<li><span>Language - ' + index + '</span></li>';
});
传入函数时,要求返回一个字符串、DOM对象或者jQuery对象。因为jQuery的append()
可能作用于一组DOM节点,只有传入函数才能针对每个DOM生成不同的子节点。
append()
把DOM添加到最后,prepend()
则把DOM添加到最前。
另外注意,如果要添加的DOM节点已经存在于HTML文档中,它会首先从文档移除,然后再添加,也就是说,用append()
,你可以移动一个DOM节点。
如果要把新节点插入到指定位置,例如,JavaScript和Python之间,那么,可以先定位到JavaScript,然后用after()
方法:
var
js = $('#test-div>ul>li:first-child');
js.after('<li><span>Lua</span></li>');
也就是说,同级节点可以用after()
或者before()
方法。
删除节点
要删除DOM节点,拿到jQuery对象后直接调用remove()
方法就可以了。如果jQuery对象包含若干DOM节点,实际上可以一次删除多个DOM节点:
var li = $('#test-div>ul>li');
li.remove(); // 所有<li>全被删除
2.2 操作文本
<script>
//1. html() 获取标签的文本内容
$("#btn1").click(function(){
//获取div标签的文本内容
let value = $("#div").html();
alert(value);
});
//2. html(value) 设置标签的文本内容,解析标签
$("#btn2").click(function(){
//设置div标签的文本内容
//$("#div").html("我真的是div");
// $("#div").html("<b>我真的是div</b>");
let username = $("#username").val();
alert(username);
});
</script>
2.3 操作对象
<script>
let p=$("p");
let p= $("<p>abc<p>");
/*
1. $("元素") 创建指定元素
// 水添加"到"杯子中
// 杯子添加水
// 父子 关系
2. append(element) 添加成最后一个子元素,由添加者对象调用
3. appendTo(element) 添加成最后一个子元素,由被添加者对象调用
4. prepend(element) 添加成第一个子元素,由添加者对象调用
5. prependTo(element) 添加成第一个子元素,由被添加者对象调用
// 兄弟关系
6. before(element) 添加到当前元素的前面,两者之间是兄弟关系,由添加者对象调用
7. after(element) 添加到当前元素的后面,两者之间是兄弟关系,由添加者对象调用
8. remove() 删除指定元素(自己移除自己,自杀)
9. empty() 清空指定元素的所有子元素(武则天)
*/
// 按钮一:添加一个span到div
$("#btn1").click(function(){
let span = $("<span>span</span>");
$("#div").append(span);
});
//按钮二:将加油添加到城市列表最下方
$("#btn2").click(function(){
//$("#city").append($("#jy"));
$("#jy").appendTo($("#city"));
});
//按钮三:将加油添加到城市列表最上方
$("#btn3").click(function(){
//$("#city").prepend($("#jy"));
$("#jy").prependTo($("#city"));
});
//按钮四:将雄起添加到上海下方
$("#btn4").click(function(){
$("#sh").after($("#xq"));
});
//按钮五:将雄起添加到上海上方
$("#btn5").click(function(){
$("#sh").before($("#xq"));
});
//按钮六:将雄起删除
$("#btn6").click(function(){
$("#xq").remove();
});
//按钮七:将描述列表全部删除
$("#btn7").click(function(){
$("#desc").empty();
});
</script>
2.4 操作样式
<script>
// 1.css(name) 获取css样式
$("#btn1").click(function(){
alert($("#div").css("border"));
});
// 2.css(name,value) 设置CSS样式
$("#btn2").click(function(){
$("#div").css("background","blue");
});
// 3.addClass(value) 给指定的对象添加样式类名
$("#btn3").click(function(){
$("#div").addClass("cls1");
});
// 4.removeClass(value) 给指定的对象删除样式类名
$("#btn4").click(function(){
$("#div").removeClass("cls1");
});
// 5.toggleClass(value) 如果没有样式类名,则添加。如果有,则删除
$("#btn5").click(function(){
$("#div").toggleClass("cls1");
});
</script>
2.5 操作属性
<script>
// 1.attr(name,[value]) 获得/设置属性的值
//按钮一:获取输入框的id属性
$("#btn1").click(function(){
alert($("#username").attr("id"));
});
//按钮二:给输入框设置value属性
$("#btn2").click(function(){
$("#username").attr("value","hello...");
});
// 2.prop(name,[value]) 获得/设置属性的值(checked,selected)
//按钮三:选中女
$("#btn3").click(function(){
$("#gender2").prop("checked",true);
});
//按钮四:选中本科
$("#btn4").click(function(){
$("#bk").prop("selected",true);
});
</script>
3、事件
事件指的就是当某些组件执行了某些操作后,会触发某些代码的执行。
- 常用的事件
- 了解的事件
绑定事件 - 方式一
通过标签中的事件属性进行绑定。
<button id="btn" onclick="执行的功能"></button>
- 方式二
通过 DOM 元素属性绑定。
document.getElementById("btn").onclick = 执行的功能
事件:
- 鼠标事件
click: 鼠标单击时触发;
dblclick:鼠标双击时触发;
mouseenter:鼠标进入时触发;
mouseleave:鼠标移出时触发;
mousemove:鼠标在DOM内部移动时触发;
hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。
- 键盘事件
键盘事件仅作用在当前焦点的DOM上,通常是<input>
和<textarea>
。
keydown:键盘按下时触发;
keyup:键盘松开时触发;
keypress:按一次键后触发。
- 其他事件
focus:当DOM获得焦点时触发;
blur:当DOM失去焦点时触发;
change:当<input>
、<select>
或<textarea>
的内容改变时触发;
submit:当<form>
提交时触发;
ready:当页面被载入并且DOM树完成初始化后触发。
其中,ready
仅作用于document
对象。由于ready
事件在DOM完成初始化后触发,且只触发一次,所以非常适合用来写其他的初始化代码。假设我们想给一个<form>
表单绑定submit
事件,下面的代码没有预期的效果:
<html>
<head>
<script>
// 代码有误:
$('#testForm).on('submit', function () {
alert('submit!');
});
</script>
</head>
<body>
<form id="testForm">
...
</form>
</body>
因为JavaScript在此执行的时候,<form>
尚未载入浏览器,所以$('#testForm)
返回[]
,并没有绑定事件到任何DOM上。
所以我们自己的初始化代码必须放到document
对象的ready
事件中,保证DOM已完成初始化:
<html>
<head>
<script>
$(document).on('ready', function () {
$('#testForm).on('submit', function () {
alert('submit!');
});
});
</script>
</head>
<body>
<form id="testForm">
...
</form>
</body>
这样写就没有问题了。因为相关代码会在DOM树初始化后再执行。
由于ready事件使用非常普遍,所以可以这样简化:
$(document).ready(function () {
// on('submit', function)也可以简化:
$('#testForm).submit(function () {
alert('submit!');
});
});
甚至还可以再简化为:
$
(function () {
// init...
});
上面的这种写法最为常见。如果你遇到$(function () {...})
的形式,牢记这是document
对象的ready
事件处理函数。
完全可以反复绑定事件处理函数,它们会依次执行:
<script>
$(function () {
console.log('init A...');
});
$(function () {
console.log('init B...');
});
$(function () {
console.log('init C...');
});
</script>
- 事件参数
有些事件,如mousemove
和keypress
,我们需要获取鼠标位置和按键的值,否则监听这些事件就没什么意义了。所有事件都会传入Event对象作为参数,可以从Event对象上获取到更多的信息:
<script>
$(function () {
$('#testMouseMoveDiv').mousemove(function (e) {
$('#testMouseMoveSpan').text('pageX = ' + e.pageX + ', pageY = ' + e.pageY);
});
});
</script>
- 取消绑定
一个已被绑定的事件可以解除绑定,通过off('click', function)
实现:
<script>
function hello() {
alert('hello!');
}
a.click(hello); // 绑定事件
// 10秒钟后解除绑定:
setTimeout(function () {
a.off('click', hello);
}, 10000);
</script>
需要特别注意的是,下面这种写法是无效的:
<script>
// 绑定事件:
a.click(function () {
alert('hello!');
});
// 解除绑定:
a.off('click', function () {
alert('hello!');
});
</script>
这是因为两个匿名函数虽然长得一模一样,但是它们是两个不同的函数对象,off('click', function () {...})
无法移除已绑定的第一个匿名函数。
为了实现移除效果,可以使用off('click')
一次性移除已绑定的click
事件的所有处理函数。
同理,无参数调用off()
一次性移除已绑定的所有类型的事件处理函数。
- 事件触发条件
一个需要注意的问题是,事件的触发总是由用户操作引发的。例如,我们监控文本框的内容改动:
<script>
var input = $('#test-input');
input.change(function () {
console.log('changed...');
});
</script>
当用户在文本框中输入时,就会触发change
事件。但是,如果用JavaScript代码去改动文本框的值,将不会触发change
事件:
<script>
var input = $('#test-input');
input.val('change it!'); // 无法触发change事件
</script>
有些时候,我们希望用代码触发change
事件,可以直接调用无参数的change()
方法来触发该事件:
<script>
var input = $('#test-input');
input.val('change it!');
input.change(); // 触发change事件
</script>
input.change()
相当于input.trigger('change')
,它是trigger()
方法的简写。
- 浏览器安全限制
在浏览器中,有些JavaScript代码只有在用户触发下才能执行,例如,window.open()
函数:
// 无法弹出新窗口,将被浏览器屏蔽:
$(function () {
window.open('/');
});
这些“敏感代码”只能由用户操作来触发:
<script>
var button1 = $('#testPopupButton1');
var button2 = $('#testPopupButton2');
function popupTestWindow() {
window.open('/');
}
button1.click(function () {
popupTestWindow();
});
button2.click(function () {
// 不立刻执行popupTestWindow(),3秒后执行:
setTimeout(popupTestWindow, 3000);
});
</script>
当用户点击button1
时,click
事件被触发,由于popupTestWindow()
在click
事件处理函数内执行,这是浏览器允许的,而button2
的click
事件并未立刻执行popupTestWindow()
,延迟执行的popupTestWindow()
将被浏览器拦截。
4、动画
jQuery内置的几种动画样式:
- show / hide
直接以无参数形式调用show()
和hide()
,会显示和隐藏DOM元素。但是,只要传递一个时间参数进去,就变成了动画:
var div = $('#test-show-hide');
div.hide(3000); // 在3秒钟内逐渐消失
时间以毫秒为单位,但也可以是’slow’,'fast’这些字符串:
var div = $('#test-show-hide');
div.show('slow'); // 在0.6秒钟内逐渐显示
toggle()
方法则根据当前状态决定是show()
还是hide()
。
- slideUp / slideDown
show()
和hide()是从左上角逐渐展开或收缩的,而slideUp()
和slideDown()
则是在垂直方向逐渐展开或收缩的。
slideUp()
把一个可见的DOM元素收起来,效果跟拉上窗帘似的,slideDown()
相反,而slideToggle()
则根据元素是否可见来决定下一步动作:
var div = $('#test-slide');
div.slideUp(3000); // 在3秒钟内逐渐向上消失
- fadeIn / fadeOut
fadeIn()
和fadeOut()
的动画效果是淡入淡出,也就是通过不断设置DOM元素的opacity
属性来实现,而fadeToggle()
则根据元素是否可见来决定下一步动作:
var div = $('#test-fade');
div.fadeOut('slow'); // 在0.6秒内淡出
- 自定义动画
如果上述动画效果还不能满足你的要求,那就祭出最后大招:animate()
,它可以实现任意动画效果,我们需要传入的参数就是DOM元素最终的CSS状态和时间,jQuery在时间段内不断调整CSS直到达到我们设定的值:
<script>
var div = $('#test-animate');
div.animate({
opacity: 0.25,
width: '256px',
height: '256px'
}, 3000); // 在3秒钟内CSS过渡到设定值
</script>
animate()
还可以再传入一个函数,当动画结束时,该函数将被调用:
<script>
var div = $('#test-animate');
div.animate({
opacity: 0.25,
width: '256px',
height: '256px'
}, 3000, function () {
console.log('动画已结束');
// 恢复至初始状态:
$(this).css('opacity', '1.0').css('width', '128px').css('height', '128px');
});
</script>
实际上这个回调函数参数对于基本动画也是适用的。
- 串行动画
jQuery的动画效果还可以串行执行,通过delay()
方法还可以实现暂停,这样,我们可以实现更复杂的动画效果,而代码却相当简单:
<script>
var div = $('#test-animates');
// 动画效果:slideDown - 暂停 - 放大 - 暂停 - 缩小
div.slideDown(2000)
.delay(1000)
.animate({
width: '256px',
height: '256px'
}, 2000)
.delay(1000)
.animate({
width: '128px',
height: '128px'
}, 2000);
}
</script>
因为动画需要执行一段时间,所以jQuery必须不断返回新的Promise对象才能后续执行操作。简单地把动画封装在函数中是不够的。
5、扩展
使用jQuery对象的方法时,由于jQuery对象可以操作一组DOM,而且支持链式操作,所以用起来非常方便。
但是jQuery内置的方法永远不可能满足所有的需求。比如,我们想要高亮显示某些DOM元素,用jQuery可以这么实现:
$('span.hl').css('backgroundColor', '#fffceb').css('color', '#d85030');
$('p a.hl').css('backgroundColor', '#fffceb').css('color', '#d85030');
总是写重复代码可不好,万一以后还要修改字体就更麻烦了,能不能统一起来,写个highlight()
方法?
$('span.hl').highlight();
$('p a.hl').highlight();
答案是肯定的。我们可以扩展jQuery来实现自定义方法。将来如果要修改高亮的逻辑,只需修改一处扩展代码。这种方式也称为编写jQuery插件。
- 编写jQuery插件
给jQuery对象绑定一个新方法是通过扩展$.fn
对象实现的。让我们来编写第一个扩展——highlight1()
:
<script>
$.fn.highlight1 = function () {
// this已绑定为当前jQuery对象:
this.css('backgroundColor', '#fffceb').css('color', '#d85030');
return this;
}
</script>
注意到函数内部的this在调用时被绑定为jQuery对象,所以函数内部代码可以正常调用所有jQuery对象的方法。
对于如下的HTML结构:
<!-- HTML结构 -->
<div id="test-highlight1">
<p>什么是<span>jQuery</span></p>
<p><span>jQuery</span>是目前最流行的<span>JavaScript</span>库。</p>
</div>
可能发现了,为什么最后要return this;
?因为jQuery对象支持链式操作,我们自己写的扩展方法也要能继续链式下去:
$('span.hl').highlight1().slideDown();
不然,用户调用的时候,就不得不把上面的代码拆成两行。
但是这个版本并不完美。有的用户希望高亮的颜色能自己来指定,怎么办?
我们可以给方法加个参数,让用户自己把参数用对象传进去。于是我们有了第二个版本的highlight2()
:
<script>
$.fn.highlight2 = function (options) {
// 要考虑到各种情况:
// options为undefined
// options只有部分key
var bgcolor = options && options.backgroundColor || '#fffceb';
var color = options && options.color || '#d85030';
this.css('backgroundColor', bgcolor).css('color', color);
return this;
}
</script>
对于如下HTML结构:
<!-- HTML结构 -->
<div id="test-highlight2">
<p>什么是<span>jQuery</span> <span>Plugin</span></p>
<p>编写<span>jQuery</span> <span>Plugin</span>可以用来扩展<span>jQuery</span>的功能。</p>
</div>
对于默认值的处理,我们用了一个简单的&&
和||
短路操作符,总能得到一个有效的值。
另一种方法是使用jQuery提供的辅助方法$.extend(target, obj1, obj2, ...),
它把多个object对象的属性合并到第一个target对象中,遇到同名属性,总是使用靠后的对象的值,也就是越往后优先级越高:
// 把默认值和用户传入的options合并到对象{}中并返回:
var opts = $.extend({}, {
backgroundColor: '#00a8e6',
color: '#ffffff'
}, options);
紧接着用户对highlight2()
提出了意见:每次调用都需要传入自定义的设置,能不能让我自己设定一个缺省值,以后的调用统一使用无参数的highlight2()
?
也就是说,我们设定的默认值应该能允许用户修改。
那默认值放哪比较合适?放全局变量肯定不合适,最佳地点是$.fn.highlight2
这个函数对象本身。
于是最终版的highlight()
终于诞生了:
<script>
$.fn.highlight = function (options) {
// 合并默认值和用户设定值:
var opts = $.extend({}, $.fn.highlight.defaults, options);
this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
return this;
}
// 设定默认值:
$.fn.highlight.defaults = {
color: '#d85030',
backgroundColor: '#fff8de'
}
</script>
这次用户终于满意了。用户使用时,只需一次性设定默认值:
$.fn.highlight.defaults.color = '#fff';
$.fn.highlight.defaults.backgroundColor = '#000';
然后就可以非常简单地调用highlight()了。
对如下的HTML结构:
<!-- HTML结构 -->
<div id="test-highlight">
<p>如何编写<span>jQuery</span> <span>Plugin</span></p>
<p>编写<span>jQuery</span> <span>Plugin</span>,要设置<span>默认值</span>,并允许用户修改<span>默认值</span>,或者运行时传入<span>其他值</span>。</p>
</div>
最终,我们得出编写一个jQuery插件的原则:
- 给
$.fn
绑定函数,实现插件的代码逻辑; - 插件函数最后要
return this;
以支持链式调用; - 插件函数要有默认值,绑定在
$.fn.<pluginName>.defaults
上; - 用户在调用时可传入设定值以便覆盖默认值。
针对特定元素的扩展
我们知道jQuery对象的有些方法只能作用在特定DOM元素上,比如submit()方法只能针对form。如果我们编写的扩展只能针对某些类型的DOM元素,应该怎么写?
还记得jQuery的选择器支持filter()
方法来过滤吗?我们可以借助这个方法来实现针对特定元素的扩展。
先写出用户调用的代码:
$('#main a').external();
然后按照上面的方法编写一个external扩展:
<script>
$.fn.external = function () {
// return返回的each()返回结果,支持链式调用:
return this.filter('a').each(function () {
// 注意: each()内部的回调函数的this绑定为DOM本身!
var a = $(this);
var url = a.attr('href');
if (url && (url.indexOf('http://')===0 || url.indexOf('https://')===0)) {
a.attr('href', '#0')
.removeAttr('target')
.append(' <i class="uk-icon-external-link"></i>')
.click(function () {
if(confirm('你确定要前往' + url + '?')) {
window.open(url);
}
});
}
});
}
</script>
对如下的HTML结构:
<!-- HTML结构 -->
<div id="test-external">
<p>如何学习<a href="http://jquery.com">jQuery</a>?</p>
<p>首先,你要学习<a href="/wiki/1022910821149312">JavaScript</a>,并了解基本的<a href="https://developer.mozilla.org/en-US/docs/Web/HTML">HTML</a>。</p>
</div>
小结
扩展jQuery对象的功能十分简单,但是我们要遵循jQuery的原则,编写的扩展方法能支持链式调用、具备默认值和过滤特定元素,使得扩展方法看上去和jQuery本身的方法没有什么区别。
内容 | 网址 |
---|---|
JavaScript个人学习笔记总结 - 快速入门 | https://blog.csdn.net/weixin_50594210/article/details/115112096 |
JavaScript个人学习笔记总结 - 函数 | https://blog.csdn.net/weixin_50594210/article/details/115113081 |
JavaScript个人学习笔记总结 - 标准对象 | https://blog.csdn.net/weixin_50594210/article/details/115112683 |
JavaScript个人学习笔记总结 - 面向对象编程 | https://blog.csdn.net/weixin_50594210/article/details/115113024 |
JavaScript个人学习笔记总结 - 浏览器 | https://blog.csdn.net/weixin_50594210/article/details/115113131 |
JavaScript个人学习笔记总结 - jQuery | https://blog.csdn.net/weixin_50594210/article/details/115113299 |
JavaScript个人学习笔记总结 - 错误处理 | https://blog.csdn.net/weixin_50594210/article/details/115113442 |
JavaScript个人学习笔记总结 - underscore | https://blog.csdn.net/weixin_50594210/article/details/115113498 |