公司项目有像上图中效果的功能需求这也是很常见功能很简单功能,通过一个小例子和大家聊聊js的事件冒泡和默认事件。

先说说一般的实现方式即使用阻止事件冒泡的方式去做,给input绑定一个click事件(并阻止事件冒泡到window)当点击上input的时候就显示ul再给window或者document 绑定一个click事件当点击页面其他地方的时候隐藏ul。

这里还要给ul 添加一个代理点击事件(事件代理比遍历li绑定点击事件性能要高)当点击到下面的li的时候把li里面的内容添加到input里面 并且此时ul 是不能隐藏的 要想ul不隐藏就得阻止事件冒泡防止事件传播到 window或者document上从而隐藏了ul原理跟给input阻止事件冒泡是一样的。

说说上面实现方式的不足就是给window或document添加点击事件当用户每点击一次页面的时候都会去执行一下给window绑定是函数(除了点击到input和ul 阻止了事件冒泡)具体实现代码如下。

<meta charset="UTF-8">
<title>test</title> <style>
*{padding:0;margin:0; }
ul{ list-style: none; }
#test2{
width:170px; }
#box{ padding:30px; }
#list{ width:170px; border:1px solid #ccc; display:none; }
#list li{ padding:5px;cursor:pointer; }
</style>
    <div id="box" >
<input type="text" id="test2" >
<ul id="list" >
<li>111</li>
<li>222</li>
<li>333</li>
<li>44</li>
</ul>
</div>
<script>
var $inp = $('#test2'),
$ul = $('#list'),doc = $(document);
$inp.on('click',show);
doc.on('click',hide);
$ul.on('click','li',changeText);//事件代理性能更好
function changeText(e){
e.stopPropagation();
$inp.val($(this).text());
}
function show(e){
e.stopPropagation(); //阻止事件冒泡
$ul.show();
}
function hide(){
$ul.hide();
} </script>

总结:

优点兼容性好ie6-ie8都ok。

缺点在window上绑定事件用户每次点击页面都会被触发绑定事件。

但我个人认为最优的实现方案不需要给window绑定click事件(用阻止默认事件的方式去实现), 我们只需给input绑定一个focus事件一个blur事件当input focus 的时候就显示ul,当input blur 的时候 就隐藏 ul 在给ul 绑定一个mousedown事件(阻止游览器默认事件)。注意:这里有必要说明一下事件的执行顺序和为什么不能给ul添加点击事件。当点击ul的时候鼠标键上升的时候 mousedown 执行完了input才会失去焦点blur。 mousedown --> blur 如果直接给ul 添加click事件input 会在失去焦点了blur 才会触发ul的click事件 事件执行顺序 blur --> click 当input blur了ul就隐藏了故得不到自己想要的效果。

按照我的方案基于第一种方案的代码稍加改动就可以具体实现的代码如下:

test

<style>
*{padding:0;margin:0; }
ul{ list-style: none; }
#test2{
width:170px; }
#box{ padding:30px; }
#list{ width:170px; border:1px solid #ccc; display:none; }
#list li{ padding:5px;cursor:pointer; }
</style>
  • 111
  • 222
  • 333
  • 44

var $inp = $('#test2'),
$ul = $('#list');
$inp.on('focus',show);
$inp.on('blur',hide);
$ul.on('mousedown','li',changeText);//事件代理性能更好 把mousedown改成click 可以验证我上面说的事件执行顺序感兴趣的自己动手试下。
function changeText(e){
e.preventDefault(); //把阻止事件冒泡改成阻止默认事件
$inp.val($(this).text());
}
function show(e){
$ul.show();
}
function hide(){
$ul.hide();
}

</script>

ie8下的效果图

ie9下的效果

在ie9及以上都ok没什么问题 但是ie8下跟我们想要的效果就不一样了每次点击ul会自动去隐藏了也就是说在ie8下 ul的mousedown是被执行了但是他没有去阻止掉input blur事件让input失去了焦点触发了绑定在blur事件的函数从而隐藏了ul。

总结:

优点不需要在window上绑定事件少一次事件绑定。

缺点兼容性ie9及以上不兼容ie8(有小问题)。

javascript 阻止事件冒泡和阻止默认事件对比的更多相关文章

  1. JS如果阻止事件冒泡和浏览器默认事件

    原地址:http://missra.com/article/web-57.html 嵌套的标签元素,如果父元素和子元素都绑定了一些事件,那么在点击最内层子元素时可能会触发父级元素的事件,下面介绍一下J ...

  2. javascript(九)事件冒泡 onmouseenter onmouseenter 默认事件 和 键盘事件

    1 事件冒泡 子元素触发的事件,会往上(父元素)传递: 例子: <div id="box"> <p></p> </div> < ...

  3. JS事件——禁止事件冒泡和禁止默认事件

    Event 对象 Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件通常与函数结合使用,函数不会在事件发生前被执行! 一.什么是事件冒泡 在一 ...

  4. jQuery 中的事件冒泡和阻止默认行为

    1.事件冒泡 <%@ page language="java" import="java.util.*" pageEncoding="utf-8 ...

  5. 这可能是最简明扼要的 js事件冒泡机制+阻止默认事件 讲解了

    哎 js事件冒泡机制和阻止冒泡 阻止默认行为好像永远也整不清楚,记了忘 忘了记...醉了 这篇文章写完以后下次再忘记 就呼自己一巴掌,忘一次一巴掌 首先要明白两个概念——事件和事件流 事件指的是用户或 ...

  6. JS事件冒泡及阻止

    事件冒泡及阻止 当一个元素接收到事件的时候,会把他接收到的事件传给自己的父级,一直到window,当然其传播的是事件,绑定的执行函数并不会传播,如果父级没有绑定事件函数,就算传递了事件,也不会有什么表 ...

  7. jQuery中事件对象e的事件冒泡用法示例(事件冒泡与阻止冒泡)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 一个取消事件的简单js例子(事件冒泡与取消默认行为)

    先上代码: <div id='outer' onclick='alert("我是outer")'> <div id="middle" oncl ...

  9. JS 事件冒泡整理 浏览器的事件流

    JavaScript与HTML的交互通过事件来实现.而浏览器的事件流是一个非常重要的概念.不去讨论那些古老的浏览器有事件捕获与事件冒泡的争议, 只需要知道在DOM2中规定的事件流包括了三个部分,事件捕 ...

  10. javascript 停止事件冒泡以及阻止默认事件冒泡

    停止事件冒泡 function stopBubble(e) { // 如果提供了事件对象,则这是一个非IE浏览器 if ( e && e.stopPropagation ) { // ...

随机推荐

  1. 洛谷 P3367 【模板】并查集

    P3367 [模板]并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数 ...

  2. 【6】Laravel5.1的migration数据库迁移

    查看Laravel5.1的目录 当你配置好数据库后,在命令行执行下边的操作 php artisan migrate 打开数据库会发现,我们的数据库多了四个表,神奇吧! 打开任意一个migration查 ...

  3. 解决django关于图片无法显示的问题

    http://python.usyiyi.cn/django/index.html http://m.blog.csdn.net/blog/qingyuanluofeng/44877399 http: ...

  4. <c:if>标签

    <c:if>的用途就和我们一般在程序中用的if一样. 语法 语法1:没有本体内容(body) <c:if test="testCondition" var=&qu ...

  5. 安装python3.4

    1.http://www.python.org下载适合自己机型的镜像文件 2.一路“next”到底,安装python到C盘上 3.计算机-属性-高级系统设置-环境变量,将刚刚安装的python路径添加 ...

  6. Django-Rest-Framework 教程: 快速入门

    本篇中, 我们会创建一个简单的API, 用来查看和编辑django默认的user和group数据. 1. 设置 我们创建django项目tutorial, 和app quickstart: # 创建新 ...

  7. vim 删除临时文件

    今天在用Xshell连接到CentOS后 使用vim 编辑文档 因为中途有事  临时关闭 并没有保存 再一次打开时 vim 提示要恢复 , 但是每次打开文件后到要恢复,于是找到了以下办法 和vim工作 ...

  8. 一种针对虚拟机的应用软件License认证方法

    由于虚拟机的硬件信息可以随意修改,使得虚拟机可能具有相同的硬件信息,在传统的应用软件License认证方式中会导致License认证漏洞.本专利提供了一种有效的解决方法. 文/王宏财 目 前,云计算的 ...

  9. 收集点小文,讲CGI,FASTCGI,PHP-CGI,PHP-FPM之间通透点的文章

    http://blog.csdn.net/meegomeego/article/details/36180343 http://www.opsers.org/linux-home/server/php ...

  10. 完整的多项匹配tomcat access日志的正则

    <pre name="code" class="html"><pre name="code" class="ht ...