feat(dropdown): 支持自定义自动关闭功能 (#2274)

* feat(dropdown): 增强 dropdown 功能

1. 新增 closeOnClick 选项
2. 新增 onClickOutside 回调
3. 修复自定义 content 的上下文菜单异常关闭问题

* Update docs/dropdown/detail/options.md

Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>

* Update docs/dropdown/detail/options.md

Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>

* Update src/modules/dropdown.js

Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>

---------

Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>
pull/2284/head
morning-star 1 month ago committed by GitHub
parent 6159468f82
commit c781567a68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -60,6 +60,20 @@
`click` `click`
</td>
</tr>
<tr>
<td>closeOnClick <sup>2.9.18+</sup></td>
<td>
下拉面板打开后,再次点击目标元素时是否关闭该面板。
</td>
<td>boolean</td>
<td>
`false`
</td> </td>
</tr> </tr>
<tr> <tr>
@ -317,6 +331,20 @@ close: function(elem){
} }
``` ```
</td>
</tr>
<tr>
<td>onClickOutside <sup>2.9.18+</sup></td>
<td colspan="3">
点击 dropdown 外部时的回调函数,返回 `false` 可阻止关闭。
```
onClickOutside: function(event){
- event: 当前点击的 `event` 对象
}
```
</td> </td>
</tr> </tr>
</tbody> </tbody>

@ -107,7 +107,8 @@ layui.define(['jquery', 'laytpl', 'lay', 'util'], function(exports){
data: [], // 菜单数据结构 data: [], // 菜单数据结构
delay: [200, 300], // 延时显示或隐藏的毫秒数,若为 number 类型则表示显示和隐藏的延迟时间相同trigger 为 hover 时才生效 delay: [200, 300], // 延时显示或隐藏的毫秒数,若为 number 类型则表示显示和隐藏的延迟时间相同trigger 为 hover 时才生效
shade: 0, // 遮罩 shade: 0, // 遮罩
accordion: false // 手风琴效果,仅菜单组生效。基础菜单需要在容器上追加 'lay-accordion' 属性。 accordion: false, // 手风琴效果,仅菜单组生效。基础菜单需要在容器上追加 'lay-accordion' 属性。
closeOnClick: false // 面板打开后,再次点击目标元素时是否关闭面板。行为取决于所使用的触发事件类型
}; };
// 重载实例 // 重载实例
@ -443,11 +444,17 @@ layui.define(['jquery', 'laytpl', 'lay', 'util'], function(exports){
that.e = e; that.e = e;
// 若为鼠标移入事件,则延迟触发 // 若为鼠标移入事件,则延迟触发
isMouseEnter ? ( if(isMouseEnter){
thisModule.timer = setTimeout(function(){ thisModule.timer = setTimeout(function(){
that.render(); that.render();
}, that.normalizedDelay().show) }, that.normalizedDelay().show)
) : that.render(); }else{
if(options.closeOnClick && options.elem.data(MOD_INDEX +'_opened') && options.trigger === 'click'){
that.remove();
}else{
that.render();
}
}
e.preventDefault(); e.preventDefault();
}; };
@ -538,21 +545,24 @@ layui.define(['jquery', 'laytpl', 'lay', 'util'], function(exports){
if(!that) return; if(!that) return;
var options = that.config; var options = that.config;
var isTopElem = lay.isTopElem(options.elem[0]);
var isCtxMenu = options.trigger === 'contextmenu';
// 若触发的是绑定的元素,或者属于绑定元素的子元素,则不关闭 // 若触发的是绑定的元素,或者属于绑定元素的子元素,则不关闭
// 满足条件:当前绑定的元素不是 body document或者不是鼠标右键事件 // 满足条件:当前绑定的元素是 body document或者是鼠标右键事件时忽略绑定元素
if(!(lay.isTopElem(options.elem[0]) || options.trigger === 'contextmenu')){ var isTriggerTarget = !(isTopElem || isCtxMenu) && (options.elem[0] === e.target || options.elem.find(e.target)[0]);
if( var isPanelTarget = that.elemView && (e.target === that.elemView[0] || that.elemView.find(e.target)[0]);
e.target === options.elem[0] || if(isTriggerTarget || isPanelTarget) return;
options.elem.find(e.target)[0] || // 处理移动端点击穿透问题
(that.elemView && e.target === that.elemView[0]) ||
(that.elemView && that.elemView.find(e.target)[0])
) return;
}
if(e.type === 'touchstart' && options.elem.data(MOD_INDEX +'_opened')){ if(e.type === 'touchstart' && options.elem.data(MOD_INDEX +'_opened')){
$(e.target).hasClass(STR_ELEM_SHADE) && e.preventDefault(); $(e.target).hasClass(STR_ELEM_SHADE) && e.preventDefault();
} }
// 点击 dropdown 外部时的回调
if(typeof options.onClickOutside === 'function'){
var shouldClose = options.onClickOutside(e);
if(shouldClose === false) return;
}
that.remove(); that.remove();
}, {passive: false}); }, {passive: false});

Loading…
Cancel
Save