当前位置: 首页 > 编程日记 > 正文

JS 中的事件设计

看懂此文,不再困惑于 JS 中的事件设计

抽空学习了下javascript和jquery的事件设计,收获颇大,总结此贴,和大家分享。

(一)事件绑定的几种方式

javascript给DOM绑定事件处理函数总的来说有2种方式:在html文档中绑定、在js代码中绑定。下面的方式1、方式2属于在html中绑定事件,方式3、方式4和方式5属于在js代码中绑定事件,其中方法5是最推荐的做法。

方式1:

HTML的DOM元素支持onclick、onblur等以on开头属性,我们可以直接在这些属性值中编写javascript代码。当点击div的时候,下面的代码会弹出div的ID:

这种做法很显然不好,因为代码都是放在字符串里的,不能格式化和排版,当代码很多的时候很难看懂。这里有一点值得说明:onclick属性中的this代表的是当前被点击的DOM对象,所以我们可以通过this.id获取DOM元素的id属性值。

方式2:

当代码比较多的时候,我们可以在onclick等属性中指定函数名。

跟上面的做法相比,这种做法略好一些。值得一提的是:事件处理函数中的this代表的是window对象,所以我们在onclick属性值中,通过this将dom对象作为参数传递。

 1 <script>
 2 
 3     function buttonHandler(thisDom)
 4     {
 5         alert(this.id);//undefined
 6         alert(thisDom.id);//outestA
 7         return false;
 8     }
 9 </script>
10 <div id="outestA" οnclick="return buttonHandler(this);"></div>

方式3:在JS代码中通过dom元素的onclick等属性

1 var dom = document.getElementById("outestA");
2 dom.onclick = function(){alert("1=" + this.id);};
3 dom.onclick = function(){alert("2=" + this.id);};

这种做法this代表当前的DOM对象。还有一点:这种做法只能绑定一个事件处理函数,后面的会覆盖前面的。

方式4:IE下使用attachEvent/detachEvent函数进行事件绑定和取消。

attachEvent/detachEvent兼容性不好,IE6~IE11都支持该函数,但是FF和Chrome浏览器都不支持该方法。而且attachEvent/detachEvent不是W3C标准的做法,所以不推荐使用。在IE浏览器下,attachEvent有以下特点。

a) 事件处理函数中this代表的是window对象,不是dom对象。

1 var dom = document.getElementById("outestA");  
2 dom.attachEvent('onclick',a);  
3       
4 function a()  
5 {   
6     alert(this.id);//undefined  
7 }

b) 同一个事件处理函数只能绑定一次。 

1 var dom = document.getElementById("outestA");  
2 dom.attachEvent('onclick',a);  
3 dom.attachEvent('onclick',a);    
4 function a()  
5 {  
6     alert(this.id);
7 }

虽然使用attachEvent绑定了2次,但是函数a只会调用一次。

 
c)不同的函数对象,可以重复绑定,不会覆盖。
1 var dom = document.getElementById("outestA");  
2 dom.attachEvent('onclick',function(){alert(1);});  
3 dom.attachEvent('onclick',function(){alert(1);});  
4 
5 // 当outestA的click事件发生时,会弹出2个对话框

匿名函数和匿名函数是互相不相同的,即使代码完全一样。所以如果我们想用detachEvent取消attachEvent绑定的事件处理函数,那么绑定事件的时候不能使用匿名函数,必须要将事件处事函数单独写成一个函数,否则无法取消。

方式5:使用W3C标准的addEventListener和removeEventListener。

这2个函数是W3C标准规定的,FF和Chrome浏览器都支持,IE6/IE7/IE8都不支持这2个函数。不过从IE9开始就支持了这2个标准的API。
1 // type:事件类型,不含"on",比如"click"、"mouseover"、"keydown";
2 // 而attachEvent的事件名称,含含"on",比如"onclick"、"onmouseover"、"onkeydown";
3 // listener:事件处理函数
4 // useCapture是事件冒泡,还是事件捕获,默认false,代表事件冒泡类型
5 addEventListener(type, listener, useCapture);

a) 事件处理函数中this代表的是dom对象,不是window,这个特性与attachEvent不同。

1 var dom = document.getElementById("outestA");  
2 dom.addEventListener('click', a, false);  
3       
4 function a()  
5 {   
6     alert(this.id);//outestA  
7 }

b) 同一个事件处理函数可以绑定2次,一次用于事件捕获,一次用于事件冒泡。

 1 var dom = document.getElementById("outestA");  
 2 dom.addEventListener('click', a, false);  
 3 dom.addEventListener('click', a, true);  
 4       
 5 function a()  
 6 {   
 7     alert(this.id);//outestA  
 8 }
 9 
10 // 当点击outestA的时候,函数a会调用2次

如果绑定的是同一个事件处理函数,并且都是事件冒泡类型或者事件捕获类型,那么只能绑定一次。

 1 var dom = document.getElementById("outestA");  
 2 dom.addEventListener('click', a, false);  
 3 dom.addEventListener('click', a, false);  
 4       
 5 function a()  
 6 {   
 7     alert(this.id);//outestA  
 8 }
 9 
10 // 当点击outestA的时候,函数a只会调用1次

c) 不同的事件处理函数可以重复绑定,这个特性与attachEvent一致。

(二)事件处理函数的执行顺序

方式1、方式2和方式3都不能实现事件的重复绑定,所以自然也就不存在执行顺序的问题。方式4和方式5可以重复绑定特性,所以需要了解下执行顺序的问题。如果你写出依赖于执行顺序的代码,可以断定你的设计存在问题。所以下面的顺序问题,仅作为兴趣探讨,没有什么实际意义。直接上结论:addEventListener和attachEvent表现一致,如果给同一个事件绑定多个处理函数,先绑定的先执行。下面的代码我在IE11、FF17和Chrome39都测试过。

 1 <script>
 2     window.onload = function(){
 3     <span style="white-space:pre">    </span>var outA = document.getElementById("outA");  
 4         outA.addEventListener('click',function(){alert(1);},false);
 5         outA.addEventListener('click',function(){alert(2);},true);
 6         outA.addEventListener('click',function(){alert(3);},true);
 7         outA.addEventListener('click',function(){alert(4);},true);
 8     };
 9 </script>
10 
11 <body>
12     <div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
13     </div>
14 </body>

当点击outA的时候,会依次打印出1、2、3、4。这里特别需要注意:我们给outA绑定了多个onclick事件处理函数,也是直接点击outA触发的事件,所以不涉及事件冒泡和事件捕获的问题,即addEventListener的第三个参数在这种场景下,没有什么用处。如果是通过事件冒泡或者是事件捕获触发outA的click事件,那么函数的执行顺序会有变化

(三) 事件冒泡和事件捕获

事件冒泡和事件捕获很好理解,只不过是对同一件事情的不同看法,只不过这2种看法都很有道理。
我们知道HTML中的元素是可以嵌套的,形成类似于树的层次关系。比如下面的代码:
1 <div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
2     <div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">
3         <div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div> 
4     </div>
5 </div>

如果点击了最内侧的outC,那么外侧的outB和outC算不算被点击了呢?很显然算,不然就没有必要区分事件冒泡和事件捕获了,这一点各个浏览器厂家也没有什么疑义。假如outA、outB、outC都注册了click类型事件处理函数,当点击outC的时候,触发顺序是A–>B–>C,还是C–>B–>A呢?如果浏览器采用的是事件冒泡,那么触发顺序是C–>B–>A,由内而外,像气泡一样,从水底浮向水面;如果采用的是事件捕获,那么触发顺序是A–>B–>C,从上到下,像石头一样,从水面落入水底。

事件冒泡见下图:

事件捕获见下图:

一般来说事件冒泡机制,用的更多一些,所以在IE8以及之前,IE只支持事件冒泡。IE9+/FF/Chrome这2种模型都支持,可以通过addEventListener((type, listener, useCapture)的useCapture来设定,useCapture=false代表着事件冒泡,useCapture=true代表着采用事件捕获。

<script>window.onload = function(){var outA = document.getElementById("outA");  var outB = document.getElementById("outB");  var outC = document.getElementById("outC");  // 使用事件冒泡outA.addEventListener('click',function(){alert(1);},false);outB.addEventListener('click',function(){alert(2);},false);outC.addEventListener('click',function(){alert(3);},false);};</script><body><div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;"><div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;"><div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div> </div></div>
</body>

使用的是事件冒泡,当点击outC的时候,打印顺序是3–>2–>1。如果将false改成true使用事件捕获,打印顺序是1–>2–>3。

(四) DOM事件流

DOM事件流我也不知道怎么解释,个人感觉就是事件冒泡和事件捕获的结合体,直接看图吧。

 

DOM事件流:将事件分为三个阶段:捕获阶段、目标阶段、冒泡阶段。先调用捕获阶段的处理函数,其次调用目标阶段的处理函数,最后调用冒泡阶段的处理函数。这个过程很类似于Struts2框中的action和Interceptor。当发出一个URL请求的时候,先调用前置拦截器,其次调用action,最后调用后置拦截器。

<script>window.onload = function(){var outA = document.getElementById("outA");  var outB = document.getElementById("outB");  var outC = document.getElementById("outC");  // 目标(自身触发事件,是冒泡还是捕获无所谓)outC.addEventListener('click',function(){alert("target");},true);// 事件冒泡outA.addEventListener('click',function(){alert("bubble1");},false);outB.addEventListener('click',function(){alert("bubble2");},false);// 事件捕获outA.addEventListener('click',function(){alert("capture1");},true);outB.addEventListener('click',function(){alert("capture2");},true);    };</script><body><div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;"><div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;"><div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div> </div></div>
</body>

当点击outC的时候,依次打印出capture1–>capture2–>target–>bubble2–>bubble1。到这里是不是可以理解addEventListener(type,handler,useCapture)这个API中第三个参数useCapture的含义呢?useCapture=false意味着:将事件处理函数加入到冒泡阶段,在冒泡阶段会被调用;useCapture=true意味着:将事件处理函数加入到捕获阶段,在捕获阶段会被调用。从DOM事件流模型可以看出,捕获阶段的事件处理函数,一定比冒泡阶段的事件处理函数先执行。

(五) 再谈事件函数执行先后顺序

在DOM事件流中提到过:

// 目标(自身触发事件,是冒泡还是捕获无所谓)
outC.addEventListener('click',function(){alert("target");},true);

我们在outC上触发onclick事件(这个是目标对象),如果我们在outC上同时绑定捕获阶段/冒泡阶段事件处理函数会怎么样呢?

 1 <script>
 2 
 3     window.onload = function(){
 4         var outA = document.getElementById("outA");  
 5         var outB = document.getElementById("outB");  
 6         var outC = document.getElementById("outC");  
 7         
 8         // 目标(自身触发事件,是冒泡还是捕获无所谓)
 9         outC.addEventListener('click',function(){alert("target2");},true);
10         outC.addEventListener('click',function(){alert("target1");},true);
11         
12         // 事件冒泡
13         outA.addEventListener('click',function(){alert("bubble1");},false);
14         outB.addEventListener('click',function(){alert("bubble2");},false);
15         
16         // 事件捕获
17         outA.addEventListener('click',function(){alert("capture1");},true);
18         outB.addEventListener('click',function(){alert("capture2");},true);
19 
20         
21         
22     };
23  
24 </script>
25 
26 <body>
27     <div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
28         <div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">
29             <div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div> 
30         </div>
31     </div>
32 </body>

点击outC的时候,打印顺序是:capture1–>capture2–>target2–>target1–>bubble2–>bubble1。由于outC是我们触发事件的目标对象,在outC上注册的事件处理函数,属于DOM事件流中的目标阶段。目标阶段函数的执行顺序:先注册的先执行,后注册的后执行。这就是上面我们说的,在目标对象上绑定的函数是采用捕获,还是采用冒泡,都没有什么关系,因为冒泡和捕获只是对父元素上的函数执行顺序有影响,对自己没有什么影响。如果不信,可以将下面的代码放进去验证。

1 // 目标(自身触发事件,是冒泡还是捕获无所谓)
2 outC.addEventListener('click',function(){alert("target1");},false);
3 outC.addEventListener('click',function(){alert("target2");},true);
4 outC.addEventListener('click',function(){alert("target3");},true);
5 outC.addEventListener('click',function(){alert("target4");},false);

至此我们可以给出事件函数执行顺序的结论了:捕获阶段的处理函数最先执行,其次是目标阶段的处理函数,最后是冒泡阶段的处理函数。目标阶段的处理函数,先注册的先执行,后注册的后执行

(六) 阻止事件冒泡和捕获

默认情况下,多个事件处理函数会按照DOM事件流模型中的顺序执行。如果子元素上发生某个事件,不需要执行父元素上注册的事件处理函数,那么我们可以停止捕获和冒泡,避免没有意义的函数调用。前面提到的5种事件绑定方式,都可以实现阻止事件的传播。由于第5种方式,是最推荐的做法。所以我们基于第5种方式,看看如何阻止事件的传播行为。IE8以及以前可以通过 window.event.cancelBubble=true阻止事件的继续传播;IE9+/FF/Chrome通过event.stopPropagation()阻止事件的继续传播。

 1 <script>
 2 
 3     window.onload = function(){
 4         var outA = document.getElementById("outA");  
 5         var outB = document.getElementById("outB");  
 6         var outC = document.getElementById("outC");  
 7         
 8         // 目标
 9         outC.addEventListener('click',function(event){
10             alert("target");
11             event.stopPropagation();
12         },false);
13 
14         // 事件冒泡
15         outA.addEventListener('click',function(){alert("bubble");},false);
16 
17         // 事件捕获
18         outA.addEventListener('click',function(){alert("capture");},true);        
19         
20     };
21  
22 </script>
23 
24 <body>
25     <div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
26         <div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">
27             <div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div> 
28         </div>
29     </div>
30 </body>

当点击outC的时候,之后打印出capture–>target,不会打印出bubble。因为当事件传播到outC上的处理函数时,通过stopPropagation阻止了事件的继续传播,所以不会继续传播到冒泡阶段。

最后再看一段更有意思的代码:

 1 <script>
 2 
 3     window.onload = function(){
 4         var outA = document.getElementById("outA");  
 5         var outB = document.getElementById("outB");  
 6         var outC = document.getElementById("outC");  
 7         
 8         // 目标
 9         outC.addEventListener('click',function(event){alert("target");},false);
10 
11         // 事件冒泡
12         outA.addEventListener('click',function(){alert("bubble");},false);
13 
14         // 事件捕获
15         outA.addEventListener('click',function(){alert("capture");event.stopPropagation();},true);        
16         
17     };
18  
19 </script>
20 
21 <body>
22     <div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
23         <div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">
24             <div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div> 
25         </div>
26     </div>
27 </body>

执行结果是只打印capture,不会打印target和bubble。神奇吧,我们点击了outC,但是却没有触发outC上的事件处理函数,而是触发了outA上的事件处理函数。原因不做解释,如果你还不明白,可以再读一遍本文章。

转载于:https://www.cnblogs.com/wjlog/p/5818088.html

相关文章:

‘百度杯’十月场web ---login

首先一看的题&#xff0c;既然是是web类的&#xff0c;就要查看源码&#xff0c;一看&#xff0c;最先有一行注释&#xff0c;估摸着是用户名和密码 果然登录上去了&#xff0c;显示一段乱码&#xff0c;源码也没有什么东西&#xff0c; 那就抓一次包吧 发现响应头里边有个sho…

oracle 与 client端执行结果不一致_不同模式下Spark应用的执行过程

根据应用执行的3个阶段&#xff0c;不同执行模式下各个阶段的执行逻辑不相同&#xff0c;本文分析不同模式下的执行逻辑。Yarn-Client模式的执行流程Yarn的组成Yarn是hadoop自带的资源管理框架&#xff0c;它的设计思想是&#xff1a;YARN的基本思想是将资源管理和作业调度/监视…

分享EOS加拿大的文章《REX——从源代码做技术解析》

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 已提议将丢失密钥恢复系统部署到EOS主网。 丢失密钥解决方案的最后一步已经在链上提出。最后一步是将丢失密钥解决方案智能合约部署到为此目的创建…

16.QT鼠标

头文件 1 #include <QMouseEvent> 2 #include <QStatusBar> 3 #include <QLabel> 1 protected: 2 //鼠标按下 3 void mousePressEvent(QMouseEvent *e); 4 //鼠标移动 5 void mouseMoveEvent(QMouseEvent *e); 6 //鼠标释放 7 void …

c++ windows获得当前工作目录文件_基于linux下Python文件操作

Python中的文件操作1、文件的打开与关闭想一想&#xff1a;如果想用word编写一份简历&#xff0c;应该有哪些流程呢&#xff1f;1、打开word软件&#xff0c;新建一个word文件2、写入个人简历信息3、保存文件4、关闭word软件同样&#xff0c;在操作文件的整体过程与使用word编写…

maven 插件

maven-enforcer-plugin https://maven.apache.org/enforcer/maven-enforcer-plugin/ https://maven.apache.org/enforcer/maven-enforcer-plugin/enforce-mojo.html http://maven.apache.org/enforcer/enforcer-rules/index.html转载于:https://www.cnblogs.com/SamuelSun/p/58…

数字货币EOS半年时间暴跌90%多,还可追捧吗?

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 对财富上的自由&#xff0c;很多人认为这比感情来得容易多了。但是面对这个竞争激烈的社会&#xff0c;是兢兢业业的工作&#xff0c;还是投资房地产…

resnet keras 结构_Wandb用起来,一行Python代码实现Keras模型可视化

大数据文摘出品来源&#xff1a;wandb编译&#xff1a;邢畅、宁静在训练神经网络的过程中&#xff0c;我们可能会希望可视化网络的性能和中间的结构&#xff0c;很多可视化代码的冗长复杂使得我们望而却步&#xff0c;有没有一行代码就能解决可视化的所有问题呢&#xff1f;通过…

tensorflow学习笔记————分类MNIST数据集

在使用tensorflow分类MNIST数据集中&#xff0c;最容易遇到的问题是下载MNIST样本的问题。 一般是通过使用tensorflow内置的函数进行下载和加载&#xff0c; from tensorflow.examples.tutorials.mnist import input_data mnist input_data.read_data_sets("MNIST_data&q…

Build SSCLI20 under VS2008 full Document (完全手册)

以前build过几次sscli2都成功了&#xff0c;这次换了个新的环境&#xff0c;没想到出了一大堆的问题。折腾了半天&#xff0c;最终搞定&#xff0c;把解决问题的过程和方法都记录下来。 首先说说build的过程中参考过的链接和资源。 首先就是sscli自带的文档&#xff1a;Buildin…

vue 发展历程时间轴动画_PPT时间轴如何做出创意感?海量素材免费分享,网友:收藏...

时间轴页面&#xff0c;是工作型PPT中常见的页面之一。个人述职或者公司介绍PPT中&#xff0c;使用时间轴&#xff0c;能够让观众更加清晰地了解公司的发展历程。但是&#xff0c;很多人在制作时间轴页面时&#xff0c;往往是这样的效果&#xff1a;只有几行字和一根线&#xf…

[CQOI2014]数三角形 组合数 + 容斥 + gcd

推导过程 &#xff1a; 组合数容斥原理gcd 正确做法是暴力的一种优化&#xff0c;ans所有情况 - 平行坐标轴的三点共线 - 斜线三点共线 如果快速求斜线三点共线&#xff1a; 首先要知道一个结论&#xff0c;对于点(a,b) (x,y)连成的线段而言(其中a>x,b>y)&#xff0c; 在…

石子合并[DP-N3]

题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆&#xff0c;并将新的一堆的石子数&#xff0c;记为该次合并的得分。 试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分. 输入输出格式 输入格式&…

智能合约智能么?

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 近几年&#xff0c;随着区块链、加密货币概念的发展&#xff0c;智能合约也开始被广泛的接受&#xff0c;然而就像最初的人工智能被过度神化一样&…

Codeforces 504 A (Round #285 div.1 A) Misha and Forest

Codeforces Round #285 (Div.1) A Misha and Forest 水题水题水…… 题意&#xff1a;给你一些点&#xff0c;给出他们连通了多少个点以及这些点的下标的异或值&#xff0c;让你找出一个图 题解&#xff1a;拓扑排序一发 代码: #include <iostream> #include <cstdio&…

hashlib模式和hmac模式

hashlib模式 什么叫hash&#xff1f; 一&#xff1a;hash是一种算法&#xff08;3.x里代替了md5模块和sha模块&#xff0c;主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 &#xff0c;MD5 算法&#xff09;&#xff0c;该算法接受传入的内容&#xff0c;经过运算得到一串hash…

asp导出word中文乱码_解决文档打开乱码问题丨小工具系列

问题:手头上有个从Workbench导出的数据表文档打开发现里面的中文是乱码&#xff01;如图所示&#xff1a;解决方法利用记事本&#xff08;notepad&#xff09;将该文档的格式修改为UTF-8&#xff0c;步骤如下点击电脑的开始菜单&#xff0c;点击"所有程序"&#xff0…

一篇文章让你了解智能合约以及和区块链的关系

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 智能合约是区块链最重要的特性&#xff0c;也是区块链能够被称为颠覆性技术的主要原因&#xff0c;更是各国央行考虑使用区块链技术来发行数字货币的…

我的常用npm命令

npm link gulp node-sass gulp-sass gulp-autoprefixer gulp-sourcemaps gulp-font-spider gulp-concat gulp-uglify gulp-jshint map-stream 转载于:https://www.cnblogs.com/siluo2000/p/8779988.html

pytorch 测试每一类_DeepFM全方面解析(附pytorch源码)

写在前面最近看了DeepFM这个模型。把我学习的思路和总结放上来给大家和未来的自己做个参考和借鉴。文章主要希望能串起学习DeepFM的各个环节&#xff0c;梳理整个学习思路。以“我”的角度浅谈一下DeepFM基础知识看过的一些有用文献最后附上可实现的pytorch代码&#xff0c;用具…

超简单的网页选项卡---jQuery

<!DOCTYPE html><html lang"en"><head> <meta charset"UTF-8"> <title>网页选项卡</title> <script src"jquery-1.4.2.js"></script> <script type"text/javascript"> $(funct…

一篇文章让你了解区块链技术的发展阶段

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 区块链是由一系列技术实现的全新去中心化经济组织模式&#xff0c;2009年诞生于比特币系统的构建&#xff0c;2017年成为全球经济热点&#xff0c;但…

301 Remove Invalid Parentheses 删除无效的括号

删除最小数目的无效括号&#xff0c;使输入的字符串有效&#xff0c;返回所有可能的结果。注意: 输入可能包含了除 ( 和 ) 以外的元素。示例 :"()())()" -> ["()()()", "(())()"]"(a)())()" -> ["(a)()()", "(a(…

python3 列表转字节_Python 3.9!10大新特性值得关注

选自towardsdatascience作者&#xff1a;Farhad Malik机器之心编译编辑&#xff1a;陈萍近日&#xff0c;Python 3.9 发布&#xff0c;并开发了一些新特性&#xff0c;包括字典合并与更新、新的解析器、新的字符串函数等。Python 3.9 已于 10 月 5 日发布&#xff0c;新版本的特…

HDU4080 Stammering Aliens(二分 + 后缀数组)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid4080 Description Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all efforts to decode their messages have failed so far because, as luck would have it, they ha…

共识机制:区块链技术的根基

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 Chapter&#xff0d;1&#xff1a;什么是共识机制&#xff1f; 技术定义是&#xff1a;共识机制是一个群体决策的流程&#xff0c;群体中的个体会执…

Web App、Hybrid App与Native App的设计差异

目前主流应用程序大体分为三类&#xff1a;Web App、Hybrid App、 Native App。 一、Web App、Hybrid App、Native App 纵向对比 首先&#xff0c;我们来看看什么是 Web App、Hybrid App、 Native App。 1. Web APP Web App 指采用Html5语言写出的App&#xff0c;不需要下载安装…

输入重定向,输出重定向,管道相关内容及实现方法

近期&#xff0c;通过实现shell了解了输入重定向&#xff0c;输出重定向&#xff0c;管道- 用自己的话总结定义&#xff1a; 输入重定向&#xff1a;把<右边的文件的内容输入到<左边的命令中。 输出重定向&#xff1a;把运行>左边命令得出的结果输入到>右边的文件中…

appium+python自动化测试教程_Python+Appium实现自动化测试

一、环境准备 1.脚本语言&#xff1a;Python3.x IDE&#xff1a;安装Pycharm 2.安装Java JDK 、Android SDK 3.adb环境&#xff0c;path添加E:\Software\Android_SDK\platform-tools 4.安装Appium for windows&#xff0c;官网地址 http://appium.io/点击下载按钮会到GitHub的下…

区块链热度飙升 BAT抢先布局话语权争夺战开打

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 今年以来&#xff0c;在互联网金融相对沉寂之后&#xff0c;区块链已当仁不让成为科技领域的主角。区块链作为一项突破性的新技术&#xff0c;如同当…