From 1fe122bbb4f6390c61f61114df0d7a37127593e6 Mon Sep 17 00:00:00 2001 From: sight <26325820+Sight-wcg@users.noreply.github.com> Date: Sat, 25 May 2024 04:05:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20lay.onClickOutside=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20detectIframe=20=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/form.js | 2 +- src/modules/lay.js | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/modules/form.js b/src/modules/form.js index c866c06f..34cbd936 100644 --- a/src/modules/form.js +++ b/src/modules/form.js @@ -457,7 +457,7 @@ layui.define(['lay', 'layer', 'util'], function(exports){ hideDown(); initValue && input.val(initValue); }, - {ignore: title} + {ignore: title, detectIframe: true} ); }; diff --git a/src/modules/lay.js b/src/modules/lay.js index f0c369d9..ed3e1977 100644 --- a/src/modules/lay.js +++ b/src/modules/lay.js @@ -629,6 +629,7 @@ * @param {HTMLElement | Window} [options.scope=document] - 监听范围 * @param {Array} [options.ignore] - 忽略监听的元素或选择器字符串 * @param {boolean} [options.capture=true] - 对内部事件侦听器使用捕获阶段 + * @param {boolean} [options.detectIframe] - 是否检测 iframe * @returns {() => void} - 返回一个停止事件监听的函数 */ lay.onClickOutside = function(target, handler, options){ @@ -637,6 +638,7 @@ var scopeTarget = options.scope || document; var ignore = options.ignore || []; var useCapture = 'capture' in options ? options.capture : true; + var detectIframe = options.detectIframe; var listener = function(event){ var el = target; @@ -693,21 +695,36 @@ return [eventTarget].concat(getParents(eventTarget)); } - if(document.addEventListener){ - scopeTarget.addEventListener(eventType, listener, useCapture); - }else{ - scopeTarget.attachEvent('on' + eventType, listener); - } + function bindEventListener(elem, eventName, handler, opts){ + elem.addEventListener + ? elem.addEventListener(eventName, handler, opts) + : elem.attachEvent('on' + eventName, handler); - var stop = function(){ - if(document.removeEventListener){ - scopeTarget.removeEventListener(eventType, listener, useCapture); - }else{ - scopeTarget.detachEvent('on' + eventType, listener); + return function(){ + elem.removeEventListener + ? elem.removeEventListener(eventName, handler, opts) + : elem.detachEvent('on' + eventName, handler); } } - return stop; + var cleanup = [ + bindEventListener(scopeTarget, eventType, listener, lay.passiveSupported ? { passive: true, capture: useCapture } : useCapture), + detectIframe && bindEventListener(window, 'blur', function(event){ + setTimeout(function(){ + if(document.activeElement && document.activeElement.tagName === 'IFRAME' + && target.contains && !target.contains(document.activeElement) + ){ + handler(event); + } + }, 0); + }) + ] + + return function(){ + for(var i=0; i < cleanup.length; i++){ + cleanup[i] && cleanup[i](); + } + } };