实现下拉列表,点击其他位置自动隐藏效果的三种方式比较
来源:互联网 发布:黑客网站攻击软件 编辑:程序博客网 时间:2024/06/05 22:46
实现效果:
1.点击按钮展开下拉列表
2.点击下拉列表中的选项进行选择,随后收起下拉列表
3.点击除下拉列表外的位置(包括按钮),收起下拉列表
效果图如下所示:
完整代码请查看:
https://github.com/wolf-wolf/pullDownList.git
实现环境
1.angular
2.sublime
基本结构:
组件的基本HTML结构如下所示:
<!-- 外部包裹层 --><div class="main" ng-click="toggleList($event)"> <!-- 按钮展示 --> <h4 class="open-btn">选择列表3</h4> <!-- 下拉列表面板 --> <div class="list-wrapper" ng-show="flag.showList"> <ul class="list"> <!-- 选项 --> <li class="item" ng-repeat="item in list" ng-click="selectItem($event,item)"> <span class="item-name" ng-bind="item.name"></span> </li> </ul> </div></div>
实现
方法一:
基本思路
在document上监听click事件,进而关闭打开的下拉列表
主要代码
JavaScript代码
//列表是否打开的判断标志$scope.flag = { showList: false};//在document上监听click函数$document.bind('click', function(event) { _closeList();//关闭下拉列表 $scope.$apply();//为了保证angular的数据同步});/*** 关闭列表函数*/function _closeList() { $scope.flag.showList = false;}
总结
上述方法实现简单,理解容易,但存在问题,如果在同一页面中存在多个组件可供点击,并且存在部分组件针对click事件使用event.stopPropagation()
或event.stopImmediatePropagation()
方法阻止事件冒泡,则点击事件无法到达document,进而无法达到自动关闭下拉列表的效果。
方法二
基本思路
在列表打开时,在body
上添加遮罩层,并将其z-index
属性设置为最高,进而遮挡所有该页面的其他组件,同时监听发生在遮罩层上的点击事件,来达到自动关闭下拉列表的效果。
主要代码
JavaScript
/*** 切换列表关闭和打开状态* @param {Object} event 事件参数,用于阻止事件冒泡*/$scope.toggleList = function(event) { if ($scope.flag.showList) { //如果列表打开则关闭 _closeList(); } else { //如果列表是关闭状态则,创建遮罩层,并打开列表 var _mask = document.createElement('div'); _mask.className = 'drop-down-mask-' + _uniquePrefix; _mask.style.position = 'absolute';//使用绝对性为 _mask.style.top = '0'; _mask.style.left = '0'; _mask.style.width = '100%'; _mask.style.height = '100%'; _mask.style.zIndex = '99998'; _mask.style.background = 'rgba(255, 255, 255, 0)';//设置遮罩层背景颜色为透明 //为遮罩层添加click方法 _mask.addEventListener('click', function(event) { _closeList(); $scope.$apply(); }); $document[0].body.append(_mask); $scope.flag.showList = true; } };/*** 关闭列表函数,将列表是否打开的判断标志设置为false,并且清除遮罩层*/function _closeList() { $scope.flag.showList = false; //获取遮罩层元素 var _mask = angular.element(document.getElementsByClassName('drop-down-mask-' + _uniquePrefix)); if (_mask) { _mask.remove();//移除遮罩层 }}
HTML
<div class="main"> <button class="open-btn" ng-click="toggleList($event)">选择列表1</button> <div class="list-wrapper" ng-show="flag.showList"> <ul class="list"> <li class="item" ng-repeat="item in list" ng-click="selectItem($event,item)"> <span class="item-name" ng-bind="item.name"></span> </li> </ul> </div></div>
总结
- 下拉列表打开后添加遮罩层
- 遮罩层插入到
body
下,body
的position
属性为relative
,遮罩层的position
属性为absolute
,以确保遮盖整个页面 - 在创建遮罩层时,需要判断是否已经存在遮罩,在这里,因为打开下拉列表表示遮罩层已经创建,所以判断下拉列表是否打开和判断遮罩层是否已经存在具有等同效果。如果未做判断,则会出现多次点击生成多个遮罩层的效果,从而在点击遮罩层时,需要多次点击才能保证其他组件的可用性
- 在关闭下拉列表的同时,一定要移除遮罩层的存在
缺陷:因为有遮罩层的存在所以在点击非下拉列表的位置时,点击事件发生在遮罩层上,如果想要在下拉列表打开的情况下,将焦点定位到其他组件,则需要二次点击。
TIP:
此方法是select2组件所采用的方式,可通过链接查看官网。
方法三
基本思路
为div
添加tabindex
属性,使其可以获得和失去焦点。监听blur
事件做到自动关闭下拉列表的效果
主要代码
JavaScript
/*** 关闭列表* @param {Object} event 事件参数,用于阻止事件冒泡*/$scope.closeList = function(event) { event.stopPropagation(); _closeList();}/*** 切换列表关闭和打开状态* @param {Object} event 事件参数,用于阻止事件冒泡*/$scope.toggleList = function(event) { event.stopImmediatePropagation(); if ($scope.flag.showList) { _closeList(); } else { $scope.flag.showList = true; }};/*** 关闭列表函数*/function _closeList() { $scope.flag.showList = false;}
HTML
<div class="main" tabindex="-1" ng-blur="closeList($event)" ng-click="toggleList($event)"> <h4 class="open-btn">选择列表2</h4> <div class="list-wrapper" ng-show="flag.showList"> <ul class="list"> <li class="item" ng-repeat="item in list" ng-click="selectItem($event,item)"> <span class="item-name" ng-bind="item.name"></span> </li> </ul> </div></div>
总结
- 在最外层包裹层,添加
tabindex
属性,这里将其值置为-1
,目的是保证在使用tab
键进行组件焦点切换时不会切换到本组件 - 监听
blur
事件而非click
事件 - 对按钮部分监听
click
事件,以实现点击按钮切换下拉列表打开状态的效果
TIP:
为什么不监听focus
事件:因为在获取焦点后,focus
事件步不再会被触发,则无法通过点击按钮来关闭下拉列表。同时focus
事件发生在click
事件之前,如果两个事件同时绑定打开下拉列表的处理函数,则会产生闪烁效果,具体情况,看官可自行尝试~~
tabindex
属性:请查看W3CSchool
如有错误请多多包涵,敬请反馈,期待一起进步~~~
再见,祝好~~!
- 实现下拉列表,点击其他位置自动隐藏效果的三种方式比较
- 控件显示之后,点击其他位置隐藏的实现
- jquery实现点击其他区域时隐藏下拉div和遮罩层的方法
- 实现下拉列表的两种方式
- 用Ajax技术和dwr框架两种方式实现下拉列表的级联效果
- 下拉刷新的三种实现方式
- 三种实现下拉菜单的方式
- 实现下拉列表效果
- 实现google的下拉列表效果
- javascript 实现 下拉列表的链接效果
- 实现google的下拉列表效果
- 下拉列表dropdown取消默认点击隐藏及修复需要二次点击的方法
- JQuery实现点击div以外的位置隐藏该div
- Android 点击屏幕其他位置隐藏Floating Action Button
- WinForm两种方式实现控件拖动效果的比较
- Java实现按钮隐藏点击动态效果的另类方法
- html怎样实现数据列表的下拉效果
- Button点击事件的三种实现方式
- POJ2376——Cleaning Shifts(贪心)
- 灰度测试,灰度发布
- 【hrbust】2298 Diamond 【数学+暴力】
- 问答与思考--迷茫?
- 数据结构——二叉树
- 实现下拉列表,点击其他位置自动隐藏效果的三种方式比较
- 怎样制作FL Studio步进音序器中的节奏
- 物联卡
- Android Studio添加第三方库(.jar && .so)
- windows核心编程-获取进程中堆的分配情况
- Android Studio修改包名不成功怎么办
- Dynamics 365 Business Process Flow -- 让你不再惧怕复杂的业务流程!
- Hexo介绍及常用安装使用
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算