操作:当点击下方 不X受理 按钮时,打开弹出框【居中显示,layerui】(如上左图),获取焦点(focus)时,弹出框居上显示(如上右图),失去焦点(blur)时,弹框居中显示,代码按照默认给某部分绑定相应处理事件【流转意见框 绑定 监听事件(失去焦点或内容改变时,将输入内容同步 另一区域div显示---此区域内容为提交后台数据库保存,并含有前端验证;而流转意见框做为 不进行验证数据保存);惯用语下方 内容绑定 click、focus事件;取消、确定按钮绑定click事件】,此时会出现 bug(操作不友好):1、当 流转意见框 为获取焦点状态时, 点击取消/确定按钮 不能达到 关闭弹框 效果,而需要点击两下才可关闭【第一次 弹框失去焦点居中(触发blur),第二次 弹框关闭】;2、当 流转意见框 为获取焦点状态时,点击惯用语,也出现1问题,会出现弹出框先下再上情况;十分头痛,昨天从4点-7点,尝试各种方法,什么延迟blur事件触发啦(setTimeout),先绑定再解绑啦【折腾focus、blur】,分别封装focus、blur事件【位置显示分别写个函数】,最后还是没解决,今早来,找了一篇 blur和click事件的先后顺序问题(https://www.cnblogs.com/xiaoweiy/p/4961450.html),理解后,终于写出了适合自己所需的效果,再此,由衷的感谢博主大大!!!开始上代码【只是部分啦,自己多练习,能从做过的项目中发现很多不合理的地方,慢慢改进代码,真是满满的成就感】
1)页面显示
请办理人员
请填写意见
2)particpant.js【部分】
$('.partContent .suggestArea').bind('blur', function(){
$('.layui-layer-iframe',parent.document).css({
'top': '50%',
'marginTop': -allH/2+'px' //iframe可见高度而不是内容高度
});
});
$('.partContent .suggestArea').bind('focus', function(){
$('.layui-layer-iframe',parent.document).css({
'top': '5%',
'marginTop': ''
});
});
/**
* 渲染惯用语及相应事件 todo 2018-12-11
* @param res []
*/
function createGyy(res) {
if(res && res.length) {
var gyyConTitle = '';
var gyyConVal = '
/**
* 将流转意见 同步给 办理意见 2018-11-12
* @param elem {HTMLElement} 流转意见 div元素
* @param currYjObj {nuiObj} 当前 可编辑的 办理意见
*/
function syncSug(elem, currYjObj){
if(currYjObj.getValue()) {
$(elem).html(currYjObj.getValue());
}
addCurEvent = function (type, callback) {
elem.addEventListener ?
elem.addEventListener(type, callback, false) :
elem.attachEvent('on' + type, callback);
}
//对比父页面与弹窗输入意见框值,如果值不同,则替换旧值
var change = function(){
if($(elem).text() != currYjObj.getValue()) {
currYjObj.setValue($(elem).text());
}
}
addCurEvent('propertychange', change);
addCurEvent('input', change);
addCurEvent('blur', change);
}
原因:由于JavaScript为单线程,同一时间只能执行处理一个事件。“blur优先于click执行”。而在本场景中,由于blur处理程序,会将弹出框居中显示,所以导致其后续click事件并不会执行,由此出现上文 需点击两下。
修改 流转框绑定
$('.partContent .suggestArea').bind('blur', function(){
setTimeout(function(){//当blur与 取消(click)事件同时触发时 延迟blur
$('.layui-layer-iframe',parent.document).css({
'top': '50%',
'marginTop': -allH/2+'px' //iframe可见高度而不是内容高度
});
}, 300);
});
等等方法不再展示,此解决方案适用于 简单的blur、click,无 惯用语 诸如此类的效果 !
背景知识:
mousedown事件:当鼠标指针移动到元素上方,并按下鼠标按键时,会发生mousedown事件。
mouseup事件:当在元素上放松鼠标按钮时,会发生mouseup事件。
注意:
(1)mousedown与click 事件不同,mousedown事件仅需要按键被按下,而不需要松开即可发生。
(2)mouseup与click事件不同,mouseup事件仅需要放松按钮。当鼠标指针位于元素上方时,放松鼠标按钮就会触发该事件。
其执行顺序为:mousedown >> mouseup >> click
参考网址:http://blog.csdn.net/ligang2585116/article/details/51764828
// 1、获取焦点时,弹出框移到界面最上方
$('.partContent .suggestArea').on('focus', function(){
$('.layui-layer-iframe',parent.document).css({
'top': '5%',
'marginTop': ''
});
}).on('blur',function(){// 失去焦点时,弹出框恢复在中央(ps:易产生冒泡)
$('.layui-layer-iframe',parent.document).css({
'top': '50%',
'marginTop': -allH/2+'px' //iframe可见高度而不是内容高度
});
});
// 2、取消/确定按钮 阻止冒泡后,绑定click
$('.topTip .cancelBtn').on('mousedown', function(event){
event.preventDefault();
}).on('click', function(){
closeWindow('cancel');
});
$('.topTip .submitBtn').on('mousedown', function(event){
event.preventDefault();
}).on('click', function(){
$('.partContent .suggestArea').blur();
ok();
});
// 3、 惯用语 (//阻止事件(blur)冒泡,再绑定所希望事件(click))
$(".eqYj").on('mousedown', function(event){
event.preventDefault();
}).on('click', function(){
var text=$(this).html();
//2019-3-1 获取焦点,定位光标在文字最右(若有监听则意见同步)
var el = $(".partContent .suggestArea").get(0);
$(el).html($(el).html()+text);
po_Last_Div(el);
//定位div(contenteditable = "true")
function po_Last_Div(el) {
if (window.getSelection) {//ie11 10 9 ff safari
$(el).focus(); //解决ff不获取焦点无法定位问题
var range = window.getSelection();//创建range
range.selectAllChildren(el);//range 选择el下所有子内容
range.collapseToEnd();//光标移至最后
}
else if (document.selection) {//ie10 9 8 7 6 5
var range = document.selection.createRange();//创建选择对象
//var range = document.body.createTextRange();
range.moveToElementText(el);//range定位到el
range.collapse(false);//光标移至最后
range.select();
}
}
});
总结:当遇到blur、click、focus3个事件同时触发时、简单场景可用,延迟 blur事件处理;期待效果较为繁琐时,可先 阻止冒泡事件(preventDefault),再绑定期待事件,稍微注意下 绑定对象---给谁绑,总之当使用blur事件时,尤其注意有没同时触发click、focus等,若有,则需考虑是否阻止冒泡。 方法都是一步步测验出来的,也要善于寻找解决方案,看看别人的做法,理解后整理适用于自己的系统。
备注:最近又看到 阻止冒泡和取消默认事件(默认行为) stopPropagation也是事件对象(Event)的一个方法,作用是阻止目标元素的冒泡事件,但是会不阻止默认行为;event.preventDefault()可以取消默认事件;在触发事件中返回 return false; 选取这些方式时注意适用w3c标准还是IE,参考文章http://caibaojian.com/javascript-stoppropagation-preventdefault.html