博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jQuery learn - 2 - 事件
阅读量:6181 次
发布时间:2019-06-21

本文共 5598 字,大约阅读时间需要 18 分钟。

hot3.png

$(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 οnlοad="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

转载于:https://my.oschina.net/u/1866954/blog/335293

你可能感兴趣的文章
TIOBE 6 月编程语言排行榜:Java 放缓,C 复兴了!
查看>>
Android Handler机制之Message及Message回收机制
查看>>
JSON vs Js
查看>>
css居中
查看>>
谈谈分享邀请奖励机制(附iOS实现代码)
查看>>
多隆:淘宝第一行代码撰写者的程序世界
查看>>
【刷算法】翻转单链表的递归和非递归方法
查看>>
基于JS快速生成各种网格布局工具Grid介绍
查看>>
十步零基础JavaScript学习路径
查看>>
vue-cli 3.0新特性解读
查看>>
第一个tensorflow程序
查看>>
从问题出发看JAVA编程规范
查看>>
【译】Swift算法俱乐部-快速排序
查看>>
150年前,他对拿破仑做数据可视化
查看>>
Kafka走查
查看>>
Ribbon 框架简介及搭建
查看>>
Vue 模板编程实践 之 巧用过滤器
查看>>
Node.js 服务器
查看>>
小议JS原型链、继承
查看>>
对比几段代码,看看你是 Python 菜鸟还是老鸟
查看>>