Chrome 更新后(angularjs 和 bootstrap-ui),当光标在模态外释放时模态关闭
Modal is closed when cursor is released outside the modal after Chrome update (angularjs and bootstrap-ui)
有时当我想 quickly select 输入的整个文本(在模态内)时,我开始 select 从文本末尾开始,将鼠标向左移动,直到整个文本被 selected 然后我释放 .
有时这个release会出现在modal之外,因为鼠标移动很快
运动描述图片:
问题是我在外面释放时模态框关闭了
问:如何防止模态框在外面释放时关闭?
我同意在外面点击关闭模式。但对发布事件不满意。
我正在使用:
- angularjs 1.5.8
- angular-bootstrap 2.5.0(又名 bootstrap-ui)
- bootstrap3.3.7(只有css!!!不是js,因为js是上面提供的)
更新:
我创建了一个 plunkr 和一个 GIF:
https://plnkr.co/edit/mxDLAdnrQ4p0KKyw?p=info
<div class="modal-body">
<div class="form-group">
<label for="">Foo</label>
<input type="text" class="form-control input-sm" ng-model="foo">
<p>Do this: select the text from right to left and release the mouse outside the modal.</p>
</div>
</div>
动图:
更新 2
我有新消息!在上次 Goole Chrome 更新后 开始发生这种情况! 我尝试使用另一台具有先前版本 Chrome 的计算机并且模式没有关闭。
您是否尝试过使用 backdrop: 'static'
。我认为这应该可以解决问题。它存在于文档中 here
我只更新了 bootstrap.js 和 bootstrap.min.js
中引用 "Modal.js" 的代码
更正版本:
* Bootstrap: modal.js v3.4.1
* https://getbootstrap.com/docs/3.4/javascript/#modals
bootstrap.js print
在模态 window 周围添加 css 填充并将其调整得更大。在外部单击仍然有效,但在边缘上拖动时释放鼠标不会将其关闭。
是的,在上次 Goole Chrome 更新版本 74.0.3729.169 后,这种情况再次发生,这是 Chrome 我们无法修复的错误,我们只能等待需要 Chrome 更新才能解决?
或者 bootstrap 维护者会更新代码来解决这个问题?
//prevent modal close when click starts in modal and ends on backdrop
$(document).on('mousedown', '.modal', function(e){
window.clickStartedInModal = $(e.target).is('.modal-dialog *');
});
$(document).on('mouseup', '.modal', function(e){
if(!$(e.target).is('.modal-dialog *') && window.clickStartedInModal) {
window.preventModalClose = true;
}
});
$("#modal").on("hide.bs.modal", function (e) {
if(window.preventModalClose){
window.preventModalClose = false;
return false;
}
});
github
上已经提到了这个问题不是最近出现的
https://github.com/angular-ui/bootstrap/issues/5810
以下解决方案效果很好,必要时稍作改进。
$rootScope.$watch(() => document.querySelectorAll('.modal').length, val => {
//everytime the number of modals changes
for (let modal of document.querySelectorAll('.modal')) {
if ($uibModalStack.getTop().value.backdrop !== 'static') { // Testing if the
modal is supposed to be static before attaching the event
modal.addEventListener('mousedown', e => {
if (e.which === 1) {
$uibModalStack.getTop().key.dismiss()
}
})
modal.querySelector('.modal-content').addEventListener('mousedown', e => {
e.stopPropagation()
})
}
}
if (val > 0) {
$uibModalStack.getTop().value.backdrop = 'static'
}
})
基于相同原理的另一个解决方案,保留模态的可拖动页脚和页眉
$rootScope.$watch(function () {
return $document.find('.modal').length;
}, function (val) {
if(openedWindows.top() ) {
var modal = $document.find('.modal');
angular.forEach(modal, function(value) {
if ($modalStack.getTop().value.backdrop !== 'static') {
value.addEventListener('mousedown', function (e) {
if (value === e.target && e.which === 1 && openedWindows.top()) {
$modalStack.getTop().key.dismiss();
}
});
}
});
if (val>0) {
$modalStack.getTop().value.backdrop = 'static';
}
}
});
我对范围滑块有类似的情况。在模态外的滑动过程中单击将关闭它。所以我删除了 data-toggle="modal"
和 data-target="#mymodal"
并添加了一个带有额外参数的点击事件
jQuery('button#modal_toggler').click(function(){
jQuery('#myModal').modal({
backdrop: 'static',
keyboard: false
})
})
backdrop
禁用点击外部模式关闭
keyboard
这适用于我的场景,禁用关闭模式的键盘输入
我正在使用 Bootstrap v3.0.0 和 运行 遇到同样的问题。最后,我不得不将 click 事件更改为 mousedown 事件。
在我的 bootstrap.js 文件中,在 modal.js 部分下,我将 this.$element.on('click.dismiss.modal', $.proxy(function (e)
更改为 this.$element.on('mousedown.dismiss.modal', $.proxy(function (e)
。一切似乎都在运作。您可能还需要在 bootstrap.min.js 文件中进行更改。
请注意,这将在鼠标按下背景时立即关闭模态,因此如果出于某种原因您希望用户能够在背景上单击,然后在模态上拖动鼠标并释放,这不会工作。
original repository 已存档,不接受投稿。
我分叉了一个版本并为感兴趣的人添加了我的修复程序:
https://github.com/peteriman/bootstrap
比较如下:
https://github.com/angular-ui/bootstrap/compare/master...peteriman:modal-patch
= // moved from template to fix issue #2280
- element.on('click', scope.close);
+ var ignoreClick = false;
+ element.on('mousedown', function(evt1) {
+ element.one('mouseup', function(evt2) {
+ if (evt1.target !== evt2.target)
+ ignoreClick = true;
+ });
+ });
+ element.on('click', function(){
+ if (ignoreClick) ignoreClick = false;
+ else scope.close.apply(this, arguments);
+ });
由于 mousedown
和 mouseup
事件在 click
事件之前触发,代码检查 mousedown
和 mouseup
是否在同一元素上。如果在不同的元素上,它会为 click
事件设置 ignoreClick=true
不触发。
为以编程方式调用 element.click()
的现有代码维护 click
事件的向后兼容性。
原题:
https://plnkr.co/edit/mxDLAdnrQ4p0KKyw?p=info&preview
我的解决方案:(plkr,modal.js,第 103-114 行)
https://plnkr.co/edit/V42G9NcTUnH9n9M4?p=info&preview
有时当我想 quickly select 输入的整个文本(在模态内)时,我开始 select 从文本末尾开始,将鼠标向左移动,直到整个文本被 selected 然后我释放 .
有时这个release会出现在modal之外,因为鼠标移动很快
运动描述图片:
问题是我在外面释放时模态框关闭了
问:如何防止模态框在外面释放时关闭?
我同意在外面点击关闭模式。但对发布事件不满意。
我正在使用:
- angularjs 1.5.8
- angular-bootstrap 2.5.0(又名 bootstrap-ui)
- bootstrap3.3.7(只有css!!!不是js,因为js是上面提供的)
更新: 我创建了一个 plunkr 和一个 GIF: https://plnkr.co/edit/mxDLAdnrQ4p0KKyw?p=info
<div class="modal-body">
<div class="form-group">
<label for="">Foo</label>
<input type="text" class="form-control input-sm" ng-model="foo">
<p>Do this: select the text from right to left and release the mouse outside the modal.</p>
</div>
</div>
动图:
更新 2
我有新消息!在上次 Goole Chrome 更新后 开始发生这种情况! 我尝试使用另一台具有先前版本 Chrome 的计算机并且模式没有关闭。
您是否尝试过使用 backdrop: 'static'
。我认为这应该可以解决问题。它存在于文档中 here
我只更新了 bootstrap.js 和 bootstrap.min.js
中引用 "Modal.js" 的代码更正版本:
* Bootstrap: modal.js v3.4.1
* https://getbootstrap.com/docs/3.4/javascript/#modals
bootstrap.js print
在模态 window 周围添加 css 填充并将其调整得更大。在外部单击仍然有效,但在边缘上拖动时释放鼠标不会将其关闭。
是的,在上次 Goole Chrome 更新版本 74.0.3729.169 后,这种情况再次发生,这是 Chrome 我们无法修复的错误,我们只能等待需要 Chrome 更新才能解决?
或者 bootstrap 维护者会更新代码来解决这个问题?
//prevent modal close when click starts in modal and ends on backdrop
$(document).on('mousedown', '.modal', function(e){
window.clickStartedInModal = $(e.target).is('.modal-dialog *');
});
$(document).on('mouseup', '.modal', function(e){
if(!$(e.target).is('.modal-dialog *') && window.clickStartedInModal) {
window.preventModalClose = true;
}
});
$("#modal").on("hide.bs.modal", function (e) {
if(window.preventModalClose){
window.preventModalClose = false;
return false;
}
});
github
上已经提到了这个问题不是最近出现的https://github.com/angular-ui/bootstrap/issues/5810
以下解决方案效果很好,必要时稍作改进。
$rootScope.$watch(() => document.querySelectorAll('.modal').length, val => {
//everytime the number of modals changes
for (let modal of document.querySelectorAll('.modal')) {
if ($uibModalStack.getTop().value.backdrop !== 'static') { // Testing if the
modal is supposed to be static before attaching the event
modal.addEventListener('mousedown', e => {
if (e.which === 1) {
$uibModalStack.getTop().key.dismiss()
}
})
modal.querySelector('.modal-content').addEventListener('mousedown', e => {
e.stopPropagation()
})
}
}
if (val > 0) {
$uibModalStack.getTop().value.backdrop = 'static'
}
})
基于相同原理的另一个解决方案,保留模态的可拖动页脚和页眉
$rootScope.$watch(function () {
return $document.find('.modal').length;
}, function (val) {
if(openedWindows.top() ) {
var modal = $document.find('.modal');
angular.forEach(modal, function(value) {
if ($modalStack.getTop().value.backdrop !== 'static') {
value.addEventListener('mousedown', function (e) {
if (value === e.target && e.which === 1 && openedWindows.top()) {
$modalStack.getTop().key.dismiss();
}
});
}
});
if (val>0) {
$modalStack.getTop().value.backdrop = 'static';
}
}
});
我对范围滑块有类似的情况。在模态外的滑动过程中单击将关闭它。所以我删除了 data-toggle="modal"
和 data-target="#mymodal"
并添加了一个带有额外参数的点击事件
jQuery('button#modal_toggler').click(function(){
jQuery('#myModal').modal({
backdrop: 'static',
keyboard: false
})
})
backdrop
禁用点击外部模式关闭
keyboard
这适用于我的场景,禁用关闭模式的键盘输入
我正在使用 Bootstrap v3.0.0 和 运行 遇到同样的问题。最后,我不得不将 click 事件更改为 mousedown 事件。
在我的 bootstrap.js 文件中,在 modal.js 部分下,我将 this.$element.on('click.dismiss.modal', $.proxy(function (e)
更改为 this.$element.on('mousedown.dismiss.modal', $.proxy(function (e)
。一切似乎都在运作。您可能还需要在 bootstrap.min.js 文件中进行更改。
请注意,这将在鼠标按下背景时立即关闭模态,因此如果出于某种原因您希望用户能够在背景上单击,然后在模态上拖动鼠标并释放,这不会工作。
original repository 已存档,不接受投稿。
我分叉了一个版本并为感兴趣的人添加了我的修复程序:
https://github.com/peteriman/bootstrap
比较如下:
https://github.com/angular-ui/bootstrap/compare/master...peteriman:modal-patch
= // moved from template to fix issue #2280
- element.on('click', scope.close);
+ var ignoreClick = false;
+ element.on('mousedown', function(evt1) {
+ element.one('mouseup', function(evt2) {
+ if (evt1.target !== evt2.target)
+ ignoreClick = true;
+ });
+ });
+ element.on('click', function(){
+ if (ignoreClick) ignoreClick = false;
+ else scope.close.apply(this, arguments);
+ });
由于 mousedown
和 mouseup
事件在 click
事件之前触发,代码检查 mousedown
和 mouseup
是否在同一元素上。如果在不同的元素上,它会为 click
事件设置 ignoreClick=true
不触发。
为以编程方式调用 element.click()
的现有代码维护 click
事件的向后兼容性。
原题:
https://plnkr.co/edit/mxDLAdnrQ4p0KKyw?p=info&preview
我的解决方案:(plkr,modal.js,第 103-114 行)
https://plnkr.co/edit/V42G9NcTUnH9n9M4?p=info&preview