jquery现在的事件API:on,off,trigger支持带命名空间的事件,当事件有了命名空间,就可以有效地管理同一事件的不同监听器,在定义组件的时候,能够避免同一元素应用到不同组件时,同一事件类型之间的影响,还能控制一些意外的事件冒泡。在实际工作中,相信大家都用的很多,但是不一定了解它的所有细节,至少我有这样的经验,经常在碰到疑惑的时候,还得重新写例子去验证它的相关作用,所以本文想把事件命名空间相关的细节都梳理出来,将来再犯迷糊的时候可以回来翻着看看以便加深对它的理解和运用。

在详细了解命名空间之前,得先认识下什么是自定义事件,因为命名空间可以同时应用于自定义事件和浏览器默认事件当中。

1. 自定义事件

我们在定义组件的时候,浏览器的默认事件往往不能满足我们的要求,比如我们写了一个树形组件,它有一个实例方法init用来完成这个组件的初始化工作,在这个方法调用结束之后,我们通常会自定义一个init事件,以便外部可以在树组件初始化完成之后做一些回调处理:

<script src="../js/lib/jquery.js"></script>
<div id="tree"> </div>
<script>
var Tree = function(element, options) {
var $tree = this.$tree = $(element);
//监听init事件,触发
$tree.on('init', $.proxy(options.onInit, this));
this.init();
}; Tree.prototype.init = function() {
console.log('tree init!');
this.$tree.trigger('init');
}; var tree = new Tree('#tree', {
onInit: function() {
console.log(this.$tree.outerHeight());
}
});
</script>

以上代码中.on('init',…)中的init就是一个类似click这样的自定义事件,该代码运行结果如下


自定义事件的使用就跟浏览器默认事件的使用没有任何区别,就连事件冒泡和阻止事件默认行为都完全支持,唯一的区别在于:浏览器自带的事件类型可以通过浏览器的UI线程去触发,而自定义事件必须通过代码来手动触发:

2. 事件命名空间

事件命名空间类似css的类,我们在事件类型的后面通过点加名称的方式来给事件添加命名空间:

<script>
var Tree = function(element, options) {
var $tree = this.$tree = $(element);
//监听init事件,触发
$tree.on('init.my.tree', $.proxy(options.onInit, this));
this.init();
}; Tree.prototype.init = function() {
console.log('tree init!');
this.$tree.trigger('init.my.tree');
}; var tree = new Tree('#tree', {
onInit: function() {
console.log(this.$tree.outerHeight());
}
});
</script>

以上代码中.on('init.my.tree',…)通过.my和.tree给init这个事件添加了2个命名空间,注意命名空间是类似css的类,而不是类似java中的package,所以这两个命名空间的名称分别是.my和.tree,而不是my和my.tree,注意命名空间的名称前面一定要带点,这个名称在off的时候可以用到。在监听和触发事件的时候带上命名空间,当触发带命名空间的事件时,只会调用匹配该命名空间的监听器。所以命名空间可以有效地管理同一事件的不同监听器,尤其在定义组件的时候可以有效地保证组件内部的事件只在组件内部有效,不会影响到其它组件。

现在假设我们不用命名空间,同时定义两个组件Tree和Dragable,并且同时对#tree这个元素做实例化,以便实现一棵可以拖动的树:

<script>
var Tree = function(element, options) {
var $tree = this.$tree = $(element);
//监听init事件,触发
$tree.on('init', $.proxy(options.onInit, this));
this.init();
}; Tree.prototype.init = function() {
console.log('tree init!');
this.$tree.trigger('init');
}; var tree = new Tree('#tree', {
onInit: function() {
console.log(this.$tree.outerHeight());
}
}); var Dragable = function(element, options) {
var $element = this.$element = $(element);
//监听init事件,触发
$element.on('init', $.proxy(options.onInit, this));
this.init();
}; Dragable.prototype.init = function() {
console.log('tree init!');
this.$element.trigger('init');
}; var drag = new Dragable('#tree', {
onInit: function() {
console.log('start drag!');
}
});
</script>

结果会发现Tree的onInit回调被调用两次:

根本原因就是因为#tree这个元素被应用到了多个组件,在这两个组件内部对#tree这个元素定义了同一个名称的事件,所以后面实例化的组件在触发该事件的时候也会导致前面实例化的组件的同一事件再次被触发。通过命名空间就可以避免这个问题,让组件各自的事件回调互不影响:

<script>
var Tree = function(element, options) {
var $tree = this.$tree = $(element);
//监听init事件,触发
$tree.on('init.my.tree', $.proxy(options.onInit, this));
this.init();
}; Tree.prototype.init = function() {
console.log('tree init!');
this.$tree.trigger('init.my.tree');
}; var tree = new Tree('#tree', {
onInit: function() {
console.log(this.$tree.outerHeight());
}
}); var Dragable = function(element, options) {
var $element = this.$element = $(element);
//监听init事件,触发
$element.on('init.my.dragable', $.proxy(options.onInit, this));
this.init();
}; Dragable.prototype.init = function() {
console.log('drag init!');
this.$element.trigger('init.my.dragable');
}; var drag = new Dragable('#tree', {
onInit: function() {
console.log('start drag!');
}
});
</script>

这样tree实例的onInit就不会被调用2次了:

3. 命名空间的匹配规则

在第2部分的举例当中,触发带命名空间的事件时,触发方式是:

然后就会调用这里监听的回调:

如果把触发方式改一下,不改监听方式,改成以下三种方式的一种,结果会怎么样呢:

this.$element.trigger('init');
this.$element.trigger('init.dragable');
this.$element.trigger('init.my');

答案是该监听回调依然会被调用。这个跟命名空间的匹配规则有关,为了说明这个规则,可以用以下的这个代码来测试:

<!DOCTYPE html>
<html lang="en">
<head>
<title>xxxxx</title>
<style type="text/css">
#parent {
margin: 100px auto 0 auto;
width: 600px;
height: 200px;
border: 1px solid #ccc;
position: relative;
} .log {
position: absolute;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
} p {
margin: 0;
} #btns {
margin: 20px auto 0 auto;
width: 600px;
}
</style>
</head>
<body>
<script src="../js/lib/jquery.js"></script>
<div id="parent">
<div class="log"></div>
</div>
<div id="btns">
<button id="btn1" type="button" onclick="$p.trigger('click.n1.n2.n3.n4');">trigger('click.n1.n2.n3.n4')</button>
<button id="btn2" type="button" onclick="$p.trigger('click.n1.n2.n3');">trigger('click.n1.n2.n3')</button>
<button id="btn3" type="button" onclick="$p.trigger('click.n1.n2');">trigger('click.n1.n2')</button>
<button id="btn4" type="button" onclick="$p.trigger('click.n1');">trigger('click.n1')</button>
<button id="btn5" type="button" onclick="$p.trigger('click');">trigger('click')</button>
</div>
<script>
function log($e, msg) {
var $log = $e.find('.log');
$log.append('<p>' + msg + '</p>');
} var $p = $('#parent'); $p.on('click.n1.n2.n3.n4', function(){
log($p, 'click n1 n2 n3 n4');
});
$p.on('click.n1.n2.n3', function(){
log($p, 'click n1 n2 n3');
});
$p.on('click.n1.n2', function(){
log($p, 'click n1 n2');
});
$p.on('click.n1', function(){
log($p, 'click n1');
});
$p.on('click', function(){
log($p, 'click');
}); </script>
</body>
</html>

初始化效果如下:
 
依次点击界面上的按钮(不过点击按钮前得先刷新页面,这样的话各个按钮效果才不会混在一起),界面打印的效果如下:

以上的测试代码一共给$p元素的click事件定义了4个命名空间,然后针对不同的命名空间数量,添加了五个监听器,通过外部的按钮来手动触发各个带命名空间的事件,从最后的结果,我们能得出这样一个规律:

1)当触发不带命名空间的事件时,该事件所有的监听器都会触发;(从最后一个按钮的测试结果可看出)

2)当触发带一个命名空间的事件时,在监听时包含该命名空间的所有监听器都会被触发;(从第4个按钮的测试结果可看出)

3)当触发带多个命名空间的事件时,只有在监听时同时包含那多个命名空间的监听器才会被触发;(从第2,3个按钮的测试结果可看出)

4)只要触发带命名空间的事件,该事件不带命名空间的监听器就不会被触发;(从1,2,3,4个按钮可看出)

5)2跟3其实就是一个,2是3的一种情况

这个规律完全适用于浏览器默认事件和自定义事件,自定义事件的测试可以用下面的代码,结论是一致的:

<!DOCTYPE html>
<html lang="en">
<head>
<title>xxxxx</title>
<style type="text/css">
#parent {
margin: 100px auto 0 auto;
width: 600px;
height: 200px;
border: 1px solid #ccc;
position: relative;
} .log {
position: absolute;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
} p {
margin: 0;
} #btns {
margin: 20px auto 0 auto;
width: 600px;
}
</style>
</head>
<body>
<script src="../js/lib/jquery.js"></script>
<div id="parent">
<div class="log"></div>
</div>
<div id="btns">
<button id="btn1" type="button" onclick="$p.trigger('hello.n1.n2.n3.n4');">trigger('hello.n1.n2.n3.n4')</button>
<button id="btn2" type="button" onclick="$p.trigger('hello.n1.n2.n3');">trigger('hello.n1.n2.n3')</button>
<button id="btn3" type="button" onclick="$p.trigger('hello.n1.n2');">trigger('hello.n1.n2')</button>
<button id="btn4" type="button" onclick="$p.trigger('hello.n1');">trigger('hello.n1')</button>
<button id="btn5" type="button" onclick="$p.trigger('hello');">trigger('hello')</button>
</div>
<script>
function log($e, msg) {
var $log = $e.find('.log');
$log.append('<p>' + msg + '</p>');
} var $p = $('#parent'); $p.on('hello.n1.n2.n3.n4', function(){
log($p, 'hello n1 n2 n3 n4');
});
$p.on('hello.n1.n2.n3', function(){
log($p, 'hello n1 n2 n3');
});
$p.on('hello.n1.n2', function(){
log($p, 'hello n1 n2');
});
$p.on('hello.n1', function(){
log($p, 'hello n1');
});
$p.on('hello', function(){
log($p, 'hello');
}); </script>
</body>
</html>

4. 命名空间的冒泡

为了说明命名空间的冒泡机制,需要把前面的测试代码改一改,并且以自定义事件来说明,测试代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<title>xxxxx</title>
<style type="text/css">
#parent {
margin: 100px auto 0 auto; width: 600px; height: 300px; border: 1px solid #ccc; position: relative;
} #child {
margin: 0 0 0 300px; width: 300px; height: 300px; border: 1px solid #ccc; position: relative;
} .log {
position: absolute; left: 0; width: 100%; height: 100%; overflow: auto;
} p {
margin: 0;
} #btns {
margin: 20px auto 0 auto; width: 600px;
}
</style>
</head>
<body>
<script src="../js/lib/jquery.js"></script>
<div id="parent">
<div class="log"></div>
<div id="child">
<div class="log"></div>
</div>
</div>
<div id="btns">
<button id="btn1" type="button" onclick="$c.trigger('hello.n1.n2.n3.n4');">trigger('hello.n1.n2.n3.n4')</button>
<button id="btn2" type="button" onclick="$c.trigger('hello.n1.n2.n3');">trigger('hello.n1.n2.n3')</button>
<button id="btn3" type="button" onclick="$c.trigger('hello.n1.n2');">trigger('hello.n1.n2')</button>
<button id="btn4" type="button" onclick="$c.trigger('hello.n1');">trigger('hello.n1')</button>
<button id="btn5" type="button" onclick="$c.trigger('hello');">trigger('hello')</button>
</div>
<script>
function log($e, msg) {
var $log = $e.children('.log');
$log.append('<p>' + msg + '</p>');
} var $p = $('#parent'); $p.on('hello.n1.n2.n3.n4', function(){
log($p, 'hello n1 n2 n3 n4');
});
$p.on('hello.n1.n2.n3', function(){
log($p, 'hello n1 n2 n3');
});
$p.on('hello.n1.n2', function(){
log($p, 'hello n1 n2');
});
$p.on('hello.n1', function(){
log($p, 'hello n1');
});
$p.on('hello', function(){
log($p, 'hello');
}); var $c = $('#child'); $c.on('hello.n1.n2.n3.n4', function(){
log($c, 'hello n1 n2 n3 n4');
});
$c.on('hello.n1.n2.n3', function(){
log($c, 'hello n1 n2 n3');
});
$c.on('hello.n1.n2', function(){
log($c, 'hello n1 n2');
});
$c.on('hello.n1', function(){
log($c, 'hello n1');
});
$c.on('hello', function(){
log($c, 'hello');
}); </script>
</body>
</html>

初始化效果如下:

在这个测试中,点击按钮的时候触发的并不是$p元素的事件,而是$c元素的事件,$p是$c的父元素,上图中整个长方形容器就是$p元素,右边的正方形容器就是$c元素。当我们依次点击上面五个按钮的时候(还是采取刷新一次点一个按钮的方式),界面打印的效果如下:

从这个测试结果来看,我们可以得出一个结论:jquery提供的事件机制,当子元素的带命名空间的事件冒泡到父级元素时,会以同样的命名空间触发父级元素的同一事件,为了方便起见,可以把这种冒泡机制称为带命名空间的冒泡。意味着当子元素的事件冒泡到父级元素时,只有那些满足该事件匹配规则的父级监听器才会被调用。

浏览器默认事件的冒泡也与自定义事件的机制相同,可以用下面的代码测试:

<!DOCTYPE html>
<html lang="en">
<head>
<title>xxxxx</title>
<style type="text/css">
#parent {
margin: 100px auto 0 auto; width: 600px; height: 300px; border: 1px solid #ccc; position: relative;
} #child {
margin: 0 0 0 300px; width: 300px; height: 300px; border: 1px solid #ccc; position: relative;
} .log {
position: absolute; left: 0; width: 100%; height: 100%; overflow: auto;
} p {
margin: 0;
} #btns {
margin: 20px auto 0 auto; width: 600px;
}
</style>
</head>
<body>
<script src="../js/lib/jquery.js"></script>
<div id="parent">
<div class="log"></div>
<div id="child">
<div class="log"></div>
</div>
</div>
<div id="btns">
<button id="btn1" type="button" onclick="$c.trigger('click.n1.n2.n3.n4');">trigger('click.n1.n2.n3.n4')</button>
<button id="btn2" type="button" onclick="$c.trigger('click.n1.n2.n3');">trigger('click.n1.n2.n3')</button>
<button id="btn3" type="button" onclick="$c.trigger('click.n1.n2');">trigger('click.n1.n2')</button>
<button id="btn4" type="button" onclick="$c.trigger('click.n1');">trigger('click.n1')</button>
<button id="btn5" type="button" onclick="$c.trigger('click');">trigger('click')</button>
</div>
<script>
function log($e, msg) {
var $log = $e.children('.log');
$log.append('<p>' + msg + '</p>');
} var $p = $('#parent'); $p.on('click.n1.n2.n3.n4', function(){
log($p, 'click n1 n2 n3 n4');
});
$p.on('click.n1.n2.n3', function(){
log($p, 'click n1 n2 n3');
});
$p.on('click.n1.n2', function(){
log($p, 'click n1 n2');
});
$p.on('click.n1', function(){
log($p, 'click n1');
});
$p.on('click', function(){
log($p, 'click');
}); var $c = $('#child'); $c.on('click.n1.n2.n3.n4', function(){
log($c, 'click n1 n2 n3 n4');
});
$c.on('click.n1.n2.n3', function(){
log($c, 'click n1 n2 n3');
});
$c.on('click.n1.n2', function(){
log($c, 'click n1 n2');
});
$c.on('click.n1', function(){
log($c, 'click n1');
});
$c.on('click', function(){
log($c, 'click');
}); </script>
</body>
</html>

需要特别注意的是:浏览器的默认事件能通过鼠标或键盘等操作,由浏览器UI线程自动触发的,而且只要是浏览器自己触发的事件,是不会带命名空间的。这样的话,只要浏览器在子元素自动触发了默认事件,那么子元素以及父元素所有的监听器都会执行,有时候这并不一定是你期望的,所以最好在开发组件的时候始终加命名空间来触发或者添加监听,这样就能屏蔽掉浏览器自动触发给组件带来的影响。

5. 文中小结

通过第3和第4部分,可以发现jquery的事件机制,纵向是一种带命名空间的冒泡机制,横向是一种按照命名空间匹配规则的管理方式,如下图所示:

综合起来,一个元素上的某个事件监听器如果要被触发的话,一共有以下几种情况:

1)直接在该元素上触发了该事件,通过命名空间匹配规则被触发;
2)由子元素的相关事件冒泡到该元素,再通过匹配规则触发;

3)如果是浏览器默认事件,还会由浏览器自动触发,不过浏览器自动触发最终还是要体现到冒泡规则和匹配规则上来。

6. off方法中的使用

jquery中在移除事件监听的时候,有多种方式,可以不带命名空间只通过事件类型来移除:

$p.off('click');

也可以通过带命名空间的事件类型来移除:

$p.off('click.n1');

还可以只按命名空间来移除:

$p.off('.n1');

为了更清楚地说明这三种移除方式的效果和规律,可以以下代码来测试

<!DOCTYPE html>
<html lang="en">
<head>
<title>xxxxx</title>
<style type="text/css">
#parent {
margin: 100px auto 0 auto; width: 600px; height: 300px; border: 1px solid #ccc; position: relative;
}
.log {
position: absolute; left: 0; width: 100%; height: 100%; overflow: auto;
}
p {
margin: 0;
}
#btns {
margin: 20px auto 0 auto; width: 600px;
}
</style>
</head>
<body>
<script src="../js/lib/jquery.js"></script>
<div id="parent">
<div class="log"></div>
</div>
<div id="btns">
<button id="btn1" type="button" onclick="$p.off('click.n1.n2.n3.n4');">off('click.n1.n2.n3.n4')</button>
<button id="btn2" type="button" onclick="$p.off('click.n1.n2.n3');">off('click.n1.n2.n3')</button>
<button id="btn3" type="button" onclick="$p.off('click.n1.n2');">off('click.n1.n2')</button>
<button id="btn4" type="button" onclick="$p.off('click.n1');">off('click.n1')</button>
<button id="btn5" type="button" onclick="$p.off('click');$p.trigger('hello');">off('click')</button>
<button id="btn6" type="button" onclick="$p.off('.n1.n2.n3.n4');">off('.n1.n2.n3.n4')</button>
<button id="btn7" type="button" onclick="$p.off('.n1.n2.n3');">off('.n1.n2.n3')</button>
<button id="btn8" type="button" onclick="$p.off('.n1.n2');">off('.n1.n2')</button>
<button id="btn9" type="button" onclick="$p.off('.n1');">off('.n1')</button>
</div>
<script>
function log($e, msg) {
var $log = $e.children('.log');
$log.append('<p>' + msg + '</p>');
} var $p = $('#parent'); $p.on('click.n1.n2.n3.n4', function(){
log($p, 'click n1 n2 n3 n4');
});
$p.on('click.n1.n2.n3', function(){
log($p, 'click n1 n2 n3');
});
$p.on('click.n1.n2', function(){
log($p, 'click n1 n2');
});
$p.on('click.n1', function(){
log($p, 'click n1');
});
$p.on('click', function(){
log($p, 'click');
$p.trigger('hello');
}); $p.on('hello.n1.n2.n3.n4', function(){
log($p, 'hello n1 n2 n3 n4');
});
$p.on('hello.n1.n2.n3', function(){
log($p, 'hello n1 n2 n3');
});
$p.on('hello.n1.n2', function(){
log($p, 'hello n1 n2');
});
$p.on('hello.n1', function(){
log($p, 'hello n1');
});
$p.on('hello', function(){
log($p, 'hello');
});
</script>
</body>
</html>

初始化界面效果为:

在这个测试中,为$p元素的两种事件click和hello各添加了五个监听器,命名空间的的设置还与前面的类似,hello事件在click事件不带命名空间的回调里被触发,提供了9个按钮分别用来测试不同的off事件的方式最后的结果。测试的方法是依次点击按钮(为了不让各个测试的结果互相影响,点击前还是得先刷新页面),点完按钮后,再点击一下$p元素,就是那个灰色边框的容器。只有第五个按钮不需要做第二次$p元素的点击,因为它已经把$p的click事件监听全部移除了,各个按钮的测试结果如下:

结果:click.n1.n2.n3.n4的监听没有被调用,hello事件不受影响。

结果:click.n1.n2.n3.n4和click.n1.n2.n3的监听没有被调用,hello事件不受影响。

结果:click.n1.n2.n3.n4和click.n1.n2.n3和click.n1.n2的监听没有被调用,hello事件不受影响。

结果:click.n1.n2.n3.n4和click.n1.n2.n3和click.n1.n2和click.n1的监听没有被调用,hello事件不受影响。

结果:所有click事件的回调都没有调用,hello事件不受影响。

综合以上的测试结果,可以得出的结论是:

1)当通过一个或多个命名空间结合事件类型来移除的时候,只会把该事件的在添加监听的时候包含那些命名空间的监听器移除,不会影响该事件类型的其它监听器以及其它事件类型。比如移除click.n1.n2,会把click.n1.n2,click.n1.n2.n3还有click.n1.n2.n3.n4都移除,但是click.n1 , click 还有hello事件都不受影响。

2)当通过事件类型来移除的时候,会把该事件的所有监听器都移除。

再看从第6个按钮开始的测试:

结果:移除了click.n1.n2.n3.n4和hello.n1.n2.n3.n4,其它事件监听不受影响。

结果:移除了click.n1.n2.n3.n4,click.n1.n2.n3和hello.n1.n2.n3.n4,hello.n1.n2.n3,其它事件监听不受影响。

结果:移除了click.n1.n2.n3.n4,click.n1.n2.n3,click.n1.n2和hello.n1.n2.n3.n4,hello.n1.n2.n3,hello.n1.n2,其它事件监听不受影响。

结果:移除了hello和click事件所有的带命名空间的监听。

综合最后这部分的测试结果,可以得出的结论是:

通过命名空间移除监听的时候,会影响所有的事件类型,会把所有事件类型的在添加监听的时候包含那些命名空间的监听器全部移除掉。比如最后的off(.n1),就把click和hello事件的所有带.n1这个命名空间的监听移除掉了。

7. 本文小结

本文花了大量的测试去了解命名空间在事件触发和事件冒泡以及移除监听时候的特性,内容虽然非常之多,但是已经充分达到了本文的最终目的,就是要把命名空间在事件管理里面的细节都梳理清楚,文中各个部分的核心内容最后都有简短的结论,将来有需要的时候可以直接通过结论来解除自己的疑惑,希望能给大家带来一些帮助,谢谢阅读:)

jquery的事件命名空间详解的更多相关文章

  1. jQuery常用事件方法详解

    目录 jQuery事件 ready(fn)|$(function(){}) jQuery.on() jQuery.click jQuery.data() jQuery.submit() jQuery事 ...

  2. jQuery 事件用法详解

    jQuery 事件用法详解 目录 简介 实现原理 事件操作 绑定事件 解除事件 触发事件 事件委托 事件操作进阶 阻止默认事件 阻止事件传播 阻止事件向后执行 命名空间 自定义事件 事件队列 jque ...

  3. 触碰jQuery:AJAX异步详解

    触碰jQuery:AJAX异步详解 传送门:异步编程系列目录…… 示例源码:触碰jQuery:AJAX异步详解.rar AJAX 全称 Asynchronous JavaScript and XML( ...

  4. jQuery调用AJAX异步详解[转]

    AJAX 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).它并非一种新的技术,而是以下几种原有技术的结合体. 1)   使用CSS和X ...

  5. jQuery的deferred对象详解(一)

    最近一段时间,都在研究jquery里面的$.Deffered对象,几天都搞不明白,其中源码的运行机制,网上查找了相关的资料,<jQuery的deferred对象详解>阮一峰老师的文章,里面 ...

  6. 触碰jQuery:AJAX异步详解(转)

    AJAX 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).它并非一种新的技术,而是以下几种原有技术的结合体. 1)   使用CSS和X ...

  7. jQuery form插件使用详解

    点击打开: jquery选择器全解 jquery中的style样式操作 jquery中的DOM操作 jquery中的事件操作全解 jquery中的动画操作全解 jquery中ajax的应用 自定义jq ...

  8. [转] jQuery的deferred对象详解

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

  9. jQuery的deferred对象详解(转)

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

随机推荐

  1. java学习笔记(2)

    上篇讲了一些概念之类的知识点,现在继续总结知识点: 1.用户自己在控制面板输入内容是如何实现的:java中有一个类可实现这个功能 类Scanner: import java.util.Scanner; ...

  2. Event Store 2.0发布,带来了安全支持和测试版Projections库

    Event Store 2.0版本于上周发布,它带来了安全支持允许锁定Event Store和在事件流上设置访问控制列表.其主要新特性包括: HTTP和TCP之上的身份认证,包括账户管理 测试版Pro ...

  3. Mono 3.2 测试NPinyin 中文转换拼音代码

    C#中文转换为拼音NPinyin代码  在Mono 3.2下运行正常,Spacebuilder 有使用到NPinyin组件,代码兼容性没有问题. using System; using System. ...

  4. 从天猫和支付宝身上学习opcity与rgba

    不知道什么时候,一个双层透明的对话框悄然流行了起来. 我们在各大网站上都能见到类似这样的对话框: 这样的聚焦更明显,用户体验更好,也显得更加的高大上. 先说点题外话,这种布局如何用CSS+DIV去实现 ...

  5. 使用border做三角形

    网站上经常会使用一些三角形,除了图片的方式,实际上利用border我们可以做出纯CSS的三角形.我们知道border是个边抖可以单独设置,当四个边相交的时候他们是什么时候改变的? .t0{ margi ...

  6. C语言 · 动态数组的使用

    从键盘读入n个整数,使用动态数组存储所读入的整数,并计算它们的和与平均值分别输出.要求尽可能使用函数实现程序代码.平均值为小数的只保留其整数部分. 样例输入: 5 3 4 0 0 2样例输出:9 1样 ...

  7. C# 用原生JS进行文件的上传

    1.此文章是用原生JS来进行文件的上传,有两个版本,一个不用ajax,一个用ajax. 1)非AJAX <!DOCTYPE html> <html> <head> ...

  8. KnockoutJS 3.X API 第七章 其他技术(7) 微任务

    注意:本文档适用于Knockout 3.4.0及更高版本. Knockout的微任务队列 Knockout的微任务队列支持调度任务尽可能快地运行,同时仍然是异步的,努力安排它们在发生I / O,回流或 ...

  9. php解决中文截取乱码问题

    针对截取字符串出现中文乱码问题,网上有很多介绍,也有很多函数,但笔者看着网上的函数,总感觉有点别扭, 所以自己动手写了一个防止截取字符串时出现中文乱码的函数. 实现的原理还是比较简单,主要是利用ASC ...

  10. linux 系统内核空间与用户空间通信的实现与分析<转>

    linux 系统内核空间与用户空间通信的实现与分析 2 评论: 陈鑫 (chen.shin@hotmail.com), 自由软件爱好者, 南京邮电学院电子工程系 2004 年 7 月 01 日 内容 ...