文档章节

jQuery learn - 2 - 事件

cangyu
 cangyu
发布于 2014/10/20 09:58
字数 2561
阅读 34
收藏 0

$(document).ready()是jQuery基于页面加载执行任务的一种主要方式。但并不是唯一,原生的window.onload也可实现相同效果。虽然二者具有类似效果,但它们在触发操作的时间上存在微妙差异,这种差异只有在加载的资源多到一定程度时才会体现出来。当文档完全下载到浏览器中时,会触发window.onload。这意味着页面上的全部元素对JavaScript而言都是可操作的,这种情况对编写功能性的代码非常有利,因为无需考虑加载次序。另一方面,通过$(document).ready()注册的事件处理程序,则会在DOM完全就绪并可使用时调用。虽然这也意味着所有元素对脚本而言都是可以访问的,但是,却不意味着所有关联的文件都已下载完毕
为保证JavaScript代码执行以前页面已经应用了样式,最好是在 <head>元素中把 <link rel="stylesheet"> 标签和 <style> 标签放在 <script> 标签前
一般来说,$(document).ready()优于使用onload,但必须要明确,因为支持文件可能还没有加载完成,所以类似图像的高度宽度属性此时不一定有效。如果需要访问这些属性,可能就得选择实现一个onload(或使用jQuery为load事件设置处理程序)。这两种机制和平共存
我们既可以在HTML标记中指定该函数:<body onload="doStuff();">也可在JavaScript中指定:window.onload = doStuff;这两种方式都会在页面加载完成后执行这个函数。但后者的优点在于,它能使行为更清晰地从标记中分离出来。注意,这里在将函数指定为处理程序时,省略了(),只用了函数名。如果带(),函数会被立即调用;没有,函数名就只是函数的标识符或函数引用,可用于在将来再调用.在只有一个函数的情况下,这样做没问题。但假设又定义了第2个函数:
    function doOtherStuff() {
        //执行另外一种任务......
    }
    也可将它指定为基于页面的加载来运行:window.onload = doOtherStuff;然而,这次指定的函数会取代刚才指定的第1个函数。因为.onload属性一次只能保存对一个函数的引用,所以不能在现有行为基础上再增加新行为。通过$(document).ready()机制能很好地解决这个问题。每次调用$(document).ready()都会向内部的行为队列中添加一个新函数,当页面加载完成后,所有函数都会被执行。而且,这些函数会按照注册它们的顺序依次执行(通过window.onload虽然也可注册多个函数,但却不能保证按顺序执行)。
在某些情况下,可能有必要在同一个页面中使用多个JavaScript库。由于很多库都使用$标识符,因此就需一种方式来避免名称冲突。为解决这个问题,jQuery提供了一个jQuery.noConflict(),调用该方法可以把对$标识符的控制权让渡还给其他库:
    <script src="prototype.js"></script>
    <script src="jquery.js"></script>
    <script>
        jQuery.noConflict();
    </script>
    <script src="myscript.js"></script>

    首先,包含jQuery之外的库(这里是Prototype)。然后,包含jQuery库,取得对$的使用权。接着,调用.noConflict()方法让出$,以便将控制权交还给Prototype。这样就可在自定义脚本中使用2个库——但是,在需要使用jQuery方法时,必须记住要用jQuery而不是$来调用。在这种情况下,还有一个在.ready()中使用$的技巧。传递给它的回调函数可以接收一个参数——jQuery对象本身。利用这个参数,可以重新命名jQuery为$,而不必担心造成冲突:
    jQuery(document).ready(function($) {
        //在这里,可以正常使用!
    });
    或者,也可以使用刚刚介绍的简写语法:
    jQuery(function($) {
        //使用$的代码
    });

$(document).ready(function() {
    $('#switcher-large').on('click', function() {
        $('body').addClass('large');
    })
;
});

    这里的全部操作就是绑定一个事件。多次调用.on()也没有任何问题,即可按需为同一事件追加更多行为。但这不是最优雅或最有效的方式
允许多个元素响应单击事件的一种策略叫做事件捕获(事件捕获和事件冒泡是“浏览器大战”时期分别由Netscape和微软提出的2种相反的事件传播模型)。在事件捕获过程中,事件首先会交给最外层的元素,接着再交给更具体的元素。另一种相反的策略叫做事件冒泡。即当事件发生时,会首先发送给最具体的元素,在这个元素获得响应机会之后,事件会向上冒泡到更一般的元素。毫不奇怪,不同的浏览器开发者最初采用的是不同的事件传播模型。因而,最终出台的DOM标准规定应该同时使用这2种策略:首先,事件从一般到具体元素逐层捕获,然后再通过冒泡返回DOM树的顶层。而事件处理程序可注册到这个过程中的任何一个阶段。为确保跨浏览器的一致性,也为了让人容易理解,jQuery始终会在模型的冒泡阶段注册事件处理程序。因此,我们总是可以假定最具体的元素会首先获得响应事件的机会。
事件冒泡可能会导致始料不及的行为,特别是在错误的元素响应mouseover或mouseout事件的情况下。假设在我们的例子中,为<div>添加了一个mouseout事件处理程序。当用户的鼠标指针退出这个<div>时,会按照预期运行mouseout处理程序。因为这个过程发生在顶层元素上,所以其他元素不会取得这个事件。但是,当指针从<a>元素上离开时,<a>元素也会取得一个mouseout事件。然后,这个事件会向上冒泡到<span>和<div>,从而触发上述的事件处理程序。这种冒泡序列很可能不是我们所希望的。
mouseentermouseleave,无论是单独绑定,还是在.hover()方法中组合绑定,都可避免这些冒泡问题。在使用它们处理事件时,不用担心某些非目标元素得到mouseover或mouseout事件导致的问题。

//未完成的代码
$(document).ready(function() {
    $('#switcher').click(function() {
        $('#switcher button').toggleClass('hidden');
    });
});

    这种改变会使样式转换器的整个区域都可通过单击切换其可见性。但同时也造成一个问题,即单击按钮会在修改内容区的样式之后折叠样式转换器。导致这个问题的原因就是事件冒泡,即事件首先被按钮处理,然后又沿着DOM树向上传递,直至到达<div id="switcher">激活事件处理程序并隐藏按钮。要解决这个问题,必须访问事件对象。事件对象是一种DOM结构,它会在元素获得处理事件的机会时传递给被调用的事件处理程序。这个对象中包含着与事件有关的信息(例如事件发生时的鼠标指针位置),也提供了可以用来影响事件在DOM中传递进程的一些方法。为使用事件对象,需为函数加1个参数:
    $(document).ready(function() {
        $('#switcher').click(function(event) {
            $('#switcher button').toggleClass('hidden');
        });
    });

    注意,这里把事件对象命名为event,主要是为了让大家一看就知道是什么,不是必须这样命名event保存事件对象event.target保存发生事件的目标元素。事件对象的.stopPropagation() (要在IE8及更早版本中安全使用,需将事件对象的cancelBubble属性设为false(但若通过jQuery来注册所有事件处理程序,就可放心使用))可完全阻止事件冒泡。
在事件的环境中完成了某些验证之后,通常会用到.preventDefault()。例如,在表单提交期间,对用户是否填写了必填字段进行检查,如果用户没有填写相应字段,就需阻止默认操作
事件传播和默认操作是相互独立的2套机制,在2者任何一方发生时,都可终止另一方。如果想要同时停止事件传播和默认操作,可在事件处理程序中return false,这是对在事件对象上同时调用.stopPropagation()和.preventDefault()的一种简写方式
is().hasClass():要测试元素是否包含某个类,可使用.hasClass()。不过,.is()更灵活,它可以测试任何选择符表达式
$('#switcher').on('click', 'button', function() {
    var bodyClass = event.target.id.split('-')[1];
    $('body').removeClass().addClass(bodyClass);
    $('#switcher button').removeClass('selected');
    $(this).addClass('selected');
});
(内置的事件委托)
$(document).ready(function() {
    $('#switcher').click(function(event) {
        if (!$(event.target).is('button'))    $('#switcher button').toggleClass('hidden');
    });
    $('#switcher-narrow, #switcher-large').click(function() {
        $('#switcher').off('click');
    });
});
(移除事件处理程序)
$(document).ready(function() {
    $('#switcher').on('click.collapse', function(event) {
        if (!$(event.target).is('button'))     $('#switcher button').toggleClass('hidden');
    });
    $('#switcher-narrow, #switcher-large').click(function() {
        $('#switcher').off('click.collapse');
    });
});
(用命名空间使.off()更据针对性)对事件处理系统,后缀.collapse不可见
$(document).ready(function() {
    var toggleSwitcher = function(event) {
        if (!$(event.target).is('button'))     $('#switcher button').toggleClass('hidden');
    };
    $('#switcher').on('click.collapse', toggleSwitcher);
});
(事件的重新绑定)使用命名函数时,必须省略函数名后的()()会导致函数被调用,而非被引用
$(document).ready(function() {
    var toggleSwitcher = function(event) {
        if (!$(event.target).is('button'))    $('#switcher button').toggleClass('hidden');
    };
    $('#switcher').on('click', toggleSwitcher);
    $('#switcher button').click(function() {
        $('#switcher').off('click', toggleSwitcher);
        if (this.id== 'switcher-default')    $('#switcher').on('click', toggleSwitcher);
    });
});
(完整的事件解除与重新绑定)对于只需触发一次,随后立即解绑的也有一种简写方法——.one():$('#switcher').one('click', toggleSwitcher);
$(document).ready(function() {
    var triggers = {
        D: 'default',
        N: 'narrow',
        L: 'large'
    };
    $(document).keyup(function(event) {
        var key = String.fromCharCode(event.which);
        if (key in triggers)    $('#switcher-' + triggers[key]).click();
    });
});
键盘事件分2类:直接对键盘按键给出响应事件(keyupkeydown)和对文本输入给出响应事件(keypress)。如果想知道用户按了哪个键,侦听keyup/keydown;输入的是什么字符,侦听keypress












© 著作权归作者所有

cangyu
粉丝 0
博文 42
码字总数 16749
作品 0
虹口
程序员
私信 提问
20 个 有用的 jQuery 电子书

这里有10 本很好的jquery电子书,提供给开发者。你可以学习到大量的函数和技巧,来提升你的前端开发的能力。 列表如下: Beginning JavaScript and CSS Development with jQuery jQuery – ...

小卒过河
2011/08/07
3.2K
4
jQuery基础 - 常用基本属性

jQuery简介 jQuery 是一个 JavaScript 库,极大地简化了 JavaScript 编程 jQuery 对象是通过jQuery包装DOM对象后产生的对象,jQuery对象是jQuery独有的,如果一个对象就是jQuery对象,那么它...

ZHAO_JH
2018/07/31
0
0
30 很棒的 jQuery Mobile 教程

本文涉及的 jQuery Mobile 教程包括乳如下 5 大方面的内容: 1. jQuery Mobile Swipe 2. jQuery Mobile Gallery 3. jQuery Mobile Menu 4. jQuery Mobile Datepickers 5. jQuery Mobile Them......

红薯
2011/08/30
16.4K
3
从零开始学 Web 之 jQuery(一)jQuery的概念,页面加载事件

大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http://www.cnblogs.com/lvonve/ CSDN...

fengdaoting
2018/07/04
0
0
Zepto.js简介(第二章)

接着上章的继续记录。 zepto 特点: 1、体积8kb 2、针对移动端的框架 3、语法同jquery大部分一样,都是$为核心函数 4、目前功能完善的框架体积最小的左右 zepto同jquery不同的API attr同pro...

张靖bibibi
2018/06/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

系列一、SpringMVC概念及测试案例

三层架构和MVC概念 一.、三层架构概念 咱们开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序,使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构 ...

我叫小糖主
23分钟前
2
0
Jenkins 文档特别兴趣小组

本文首发于:Jenkins 中文社区 我们很高兴地宣布 Jenkins 文档特别兴趣小组的成立。 文档特别兴趣小组鼓励贡献者和外部社区创建和 review Jenkins 文档。 更多详情和计划,请参见:文档特别兴...

Jenkins中文社区
25分钟前
2
0
servlet和jquery

package com.atguigu.demo;public class Demo {/** * Servlet * * 为什么学Servlet * htmlservlet dao-jdbc(sql:select * from users where username=? and pwd=?...

architect刘源源
34分钟前
1
0
微服务项目中如何集成——XXL-SSO单点登录系统

为什么需要做单点登陆系统 大型互联网公司中,公司旗下可能会有多个子系统,每个登陆实现统一管理多个账户信息统一管理 SSO单点登陆认证授权系统 总体设计架构图 单点登陆系统实现思路 ...

须臾之余
36分钟前
3
0
使用mybatis

1.引入依赖 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.0.0</version></dependency>......

贾峰uk
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部