jQuery learn - 2 - 事件

$(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事件致使的问题。
jquery

//未完成的代码
$(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











api

相关文章
相关标签/搜索