第六章-jQuery

jQuery的理念是: 写更少的代码, 完成更多的工作

jQuery有两个版本1.x和2.x, 版本2.x不再支持IE678

jQuery最明显的标志就是$, jQuery把所有的功能都封装在了jQuery变量中, 而$就等同于jQuery变量

可以使用jQuery.noConflict()交出$变量(在最新的3.2.1中已经删除了这个方法) 

1 选择器

  jQuery对象 = $(选择器);  

  该jQuery对象类似于数组, 数组中的每个元素是引用了的一个DOM对象

  可以通过 jQuery对象.get(索引) 获得DOM对象, 又可以将DOM对象传给$()返回一个jQuery对象

  

  返回的jQuery对象不会是undefined或者null, 最差也是一个空数组

  查找得到的结果是按照顺序排列

  元素也不会被重复查找

1.1 基本选择器

  1) ID查找

var div = $('#abc');

  2) tag查找

var ps = $('p'); // 返回所有<p>节点
ps.length; // 数一数页面有多少个<p>节点

  3) class查找

var a = $('.red'); // 所有节点包含`class="red"`都将返回

  4) 属性查找

  其中属性可以不加引号, 但是有空格等特殊字符时, 需要加上

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
var names = $('[name$=with]'); // 找出所有name属性值以with结尾的DOM

  5) 组合查找

var emailInput = $('input[name=email]'); // 不会找出<div name="email">
var tr = $('tr.red'); // 找出<tr class="red ...">...</tr>

  6) 多项查找

$('p,div'); // 把<p>和<div>都选出来
$('p.red,p.green'); // 把<p class="red">和<p class="green">都选出来

1.2 层级选择器

  基本的层级选择器是用空格表示层级关系, (逗号表示多项查找)

$('form.test p input'); // 在class为test的form表单中选择被<p>包含的<input>

  子选择器

  限定关系必须是父子关系

$('div.main>p#test'); //选择class为main的div的子节点中id为test的p标签

  过滤器

  限定选择到的内容

  

  还有一些关于表单的过滤器

: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正好相反,选择那些不能输入的。

:visible : 选择可见的标签

:hidden : 选择隐藏的标签

1.3 查找过滤

  使用find(选择器)来在子节点中查找

  使用parent()获得父节点, next()获得下一个节点, prev()获得上一个节点, 其中next和prev还可以使用选择器

  使用filter()过滤节点, 其中可以传入选择器, 也可以传入一个函数, 内含this指定为调用对象中的每个元素

  使用map()可以用于处理得到的jQuery对象, 里面传入一个函数进行处理

  使用first(), last(),slice(), 获得第一个, 最后一个, 和切片获取, 其中切片获取规则与python切片类似

  具体使用如下:

  对于HTML

<ul class="lang">
    <li class="js dy">JavaScript</li>
    <li class="dy">Python</li>
    <li id="swift">Swift</li>
    <li class="dy">Scheme</li>
    <li name="haskell">Haskell</li>
</ul>

  有以下操作

var ul = $('ul.lang'); // 获得<ul>
var dy = ul.find('.dy'); // 获得JavaScript, Python, Scheme
var swf = ul.find('#swift'); // 获得Swift
var hsk = ul.find('[name=haskell]'); // 获得Haskell

var swift= $('#swift'); // 获得Swift
var parent = swift.parent(); // 获得Swift的上层节点<ul>
var a = swift.parent('div.red'); // 从Swift的父节点开始向上查找,直到找到某个符合条件的节点并返回

swift.next(); // Scheme
swift.next('[name=haskell]'); // Haskell,因为Haskell是后续第一个符合选择器条件的节点
swift.prev(); // Python
swift.prev('.js'); // JavaScript,因为JavaScript是往前第一个符合选择器条件的节点

var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var a = langs.filter('.dy'); // 拿到JavaScript, Python, Scheme

var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
langs.filter(function () {
    return this.innerHTML.indexOf('S') === 0; // 返回S开头的节点
}); // 拿到Swift, Scheme

var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var arr = langs.map(function () {
    return this.innerHTML;
}).get(); // 用get()拿到包含string的Array:['JavaScript', 'Python', 'Swift', 'Scheme', 'Haskell']

var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var js = langs.first(); // JavaScript,相当于$('ul.lang li:first-child')
var haskell = langs.last(); // Haskell, 相当于$('ul.lang li:last-child')
var sub = langs.slice(2, 4); // Swift, Scheme, 参数和数组的slice()方法一致

2 操作DOM

  1) 获取和设置节点文本或者HTML文本采用text()html()

  如果不传入参数, 那么就是获取值; 如果需要设置, 那么就将设置的值传入参数

  

  2) 修改css样式直接使用css(样式名, 样式值), 多个css可以使用链式写法

  3) 操作class属性可以使用hasClass(), addClass(), removeClass()

  4) 显示和隐藏元素可以直接使用show()和hide(), 隐藏后原标签的位置会被别的占领

  5) 获取DOM信息

// 浏览器可视窗口大小:
$(window).width(); // 800
$(window).height(); // 600

// HTML文档大小:
$(document).width(); // 800
$(document).height(); // 3500

  6) 设置和删除元素的属性  

// <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

  关于radio选择

// <input id="test-radio" type="radio" name="test" checked value="1">

var radio = $('#test-radio');
radio.attr('checked'); // 'checked'
radio.prop('checked'); // true
radio.is(':checked'); // true

  类似的is还可以判断:selected, 一般也是使用is而不是prop更不是attr

  7) 关于表单

  可以使用val()来获取和设置值  

input.val(); // 'test'
input.val('abc@example.com'); // 文本框的内容已变为abc@example.com

  8) 添加节点

  使用append或者是prepend()

  可以传入jQuery对象, DOM对象, 或者是一个函数 

// 创建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>';
});

  当然也可以使用after()和before在某个节点之后或者之前添加一个元素

  9) 删除节点

  节点.remove() 就可以直接删除  

3 事件

  1) 绑定事件

jQuery对象.on("事件名", 执行函数);
jQuery对象.事件名(执行函数);

  2) 解绑事件

jQuery对象.off("事件名", 指定解绑的函数)

  一般地, 绑定事件的时候都是生成的匿名函数, 所以在解绑的时候是无法指定该解绑的函数的, 因此一般解绑都是省略第二个参数, 直接解绑所有该类型的事件

  3) 事件触发条件

  一般地, 事件触发的原则是用户自己触发, 对于文本框, 如果设置change事件, 当用JS代码去改变它的值的时候, 是不会触发change时间的

  代码触发事件的方式

jQuery对象.trigger("事件名");
// 可以简写为
jQuery对象.事件名();

  4) 浏览器安全限制

  同样有的代码必须要用户才能执行, 例如window.open(), 直接是无法执行的, 一般的解决办法是把这个代码方法点击事件的相应函数里面

  由于点击事件是用户触发的, 所以此时触发的函数内的window.open()可以被执行  

  5) 事件的分类

  事件分为鼠标事件, 键盘事件, 其他事件

鼠标事件有:
click: 鼠标单击时触发;
dblclick:鼠标双击时触发;
mouseenter:鼠标进入时触发;
mouseleave:鼠标移出时触发;
mousemove:鼠标在DOM内部移动时触发;
hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave

键盘事件有:
keydown:键盘按下时触发;
keyup:键盘松开时触发;
keypress:按一次键后触发

其他事件有:
focus:当DOM获得焦点时触发;
blur:当DOM失去焦点时触发;
change:当<input>、<select>或<textarea>的内容改变时触发;
submit:当<form>提交时触发;
ready:当页面被载入并且DOM树完成初始化后触发, 且只触发一次, ready仅作用于document对象

  其中由于ready事件十分的常用, 一般的写法是

$(document).ready(function () {
    函数体;    
});

  可以简写为

$(function () {
    函数体;
});

  这个简写可以反复绑定事件处理函数(可以出现多个这个简写形式), 它们会一次执行

  关于mousemove和keypress等函数需要获取鼠标位置按键位置等值, 所以在绑定方法的参数中可以设置一个变量e获取Event对象

$(function () {
    $('#testMouseMoveDiv').mousemove(function (e) {
        $('#testMouseMoveSpan').text('pageX = ' + e.pageX + ', pageY = ' + e.pageY);
    });
});

4 AJAX

  使用JavaScript来书写AJAX的时候需要判断浏览器的类型, 还需要判断状态和错误, 写起来十分不方便    

  在jQuery中绑定了一个专门用于处理的ajax()函数

$.ajax(url, settings);

  其中settings是一个对象, 常用的属性有:  

async:是否异步执行AJAX请求,默认为true,千万不要指定为false;

method:发送的Method,缺省为'GET',可指定为'POST'、'PUT'等;

contentType:发送POST请求的格式,默认值为'application/x-www-form-urlencoded; charset=UTF-8',也可以指定为text/plain、application/json;

data:发送的数据,可以是字符串、数组或object。如果是GET请求,data将被转换成query附加到URL上,如果是POST请求,根据contentType把data序列化成合适的格式;

headers:发送的额外的HTTP头,必须是一个object;

dataType:接收的数据格式,可以指定为'html'、'xml'、'json'、'text'等,缺省情况下根据响应的Content-Type猜测。

  同时使用ajax()得到的对象其实也是一个Promise对象, 因此可以在后面加上done(), fail()和always()函数用于回调完成时, 错误时, 任何情况都要执行的函数

  针对常见的请求方法, jQuery封装了ajax的常用请求方式

  1) get  

var jqxhr = $.get('/path/to/resource', {
    name: 'Bob Lee',
    check: 1
});

  由于第二个参数是一个对象, 表示需要附带参数, 因此此时请求的地址就变为了

/path/to/resource?name=Bob%20Lee&check=1

  这样可以省去构造请求地址

  2) post

  与get类似, 不过第二个参数会被序列化为application/x-www-form-urlencoded

  实际的内容也会被当做post的body被发送

var jqxhr = $.post('/path/to/resource', {
    name: 'Bob Lee',
    check: 1
});

  3) getJSON

var jqxhr = $.getJSON('/path/to/resource', {
    name: 'Bob Lee',
    check: 1
}).done(function (data) {
    // data已经被解析为JSON对象了
});

5 扩展jQuery

  可以通过扩展jQuery来实现一些自定义的方法来满足不同的需求

  扩展的方式是给 $.fn 绑定

  一般地

    绑定的方法内可以使用this变量, 表示当前的jQuery对象, 这就保证了之后可以直接是用$().自定义函数()  

    绑定的方法一般会 return this; 这样才能保证链式写法的正常运行 

    插件函数要有默认值, 设置在$.fn.插件函数名.defaults

    还需要接受参数, 以便覆盖原有的默认值

  设置高亮的插件函数实例为

// 设定默认值:
$.fn.highlight.defaults = {
    color: '#d85030',
    backgroundColor: '#fff8de'
}

// 设置高亮函数
$.fn.highlight = function (options) {
    // 合并默认值和用户设定值:
    var opts = $.extend({}, $.fn.highlight.defaults, options);
    this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
    return this;
}

  给a标签加上判定是否需要跳转

$.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);
                }
            });
        }
    });
}

  

  

posted @ 2017-06-01 12:19  weihuchao  阅读(294)  评论(0编辑  收藏  举报