我有以下情况:textarea当前绑定到change事件的自动保存。当textarea获得焦点时,它还会显示从底部悬挂的“保存”和“取消”按钮,以便用户可以点击一些内容,以防他们感到不舒服,只需移开控件或在外面点击它进入空白区域。
保存按钮基本上只是一个虚拟按钮。当用户单击它时,焦点自然会从textarea中丢失,并且触发更改事件。一切也适用于在textarea外部点击以进行保存。
问题出在“取消”按钮上。单击“取消”按钮会导致textarea失去焦点,从而触发更改事件,该事件在按钮的单击事件之前处理。由于几乎同时将保存和取消事件发送到服务器,因此无法确定它们的处理顺序。
这个例子可以在这里看到:http://jsfiddle.net/vwu79wd1/1/
HTML
<div class="largerEventContainer">
<div class="inlineControls" style="width:200px;">
<textarea name="SomeText" data-prevvalue="Original Text" style="width:100%">Original Text</textarea>
</div>
</div>
<div id="log"></div>
CSS
.inlineControls {
position:relative;
margin-bottom:1em;
}
.inlineControls textarea, .inlineControls input {
margin-bottom: 0px;
}
.inlineControls textarea:focus ~ .saveOptions {
display: block;
}
.saveOptions:hover {
display:block;
}
.saveOptions {
display:none;
position:absolute;
right:0px;
top:100%;
background-color: #f0f0f0;
border: 1px solid #ccc;
padding: 3px;
outline: none;
border-top:none;
border-radius: 0 0 3px 3px;
}
的Javascript
$('.largerEventContainer').on('change', 'input, textarea', function () {
$('#log').append('<div>saving</div>');
});
$(document).on('focus', '.inlineControls textarea', function () {
var $control = $(this)
if ($(this).closest('.inlineControls').find('.saveOptions').length == 0) {
$(this).closest('.inlineControls')
.append($(document.createElement('div'))
.addClass('saveOptions')
.append($(document.createElement('span'))
.css('padding', '4px')
.html('Save')
.click(function () {
$(this).closest('.saveOptions').remove();
}))
.append($(document.createElement('span'))
.css('padding', '4px')
.html('Cancel'))
.click(function () {
var $control = $(this).closest('.inlineControls').find('textarea')
$control.val($control.data('prevvalue'));
$('#log').append('<div>reset</div>');
$(this).closest('.saveOptions').remove();
}));
}
});
我曾尝试或考虑过但被解雇为不工作或太笨重
在允许更改事件发生之前,我是否可以优雅地检测到(将会)点击取消按钮?
答案 0 :(得分:1)
我认为解决方案应该是一种不同的方法,例如实际上只保存更改&#39;保存&#39;按钮单击,或者可能使用本地存储在提交之前保存更改。显然,您应该在用户尝试从页面移出之前发出警报。
但无论如何,测试事件的顺序,我发现了一个令人惊讶的事情: &#39;鼠标按下&#39; CANCEL按钮上的事件首先触发,然后才发生变化&#39;在textarea上的活动。尝试一下,也许这样有效,即使没有意义......
答案 1 :(得分:0)
我建议您在mouseOut事件中将文本区域的内容保存到临时变量。
仅在点击“保存”按钮后才能将值保存到数据库
答案 2 :(得分:0)
根据我自己的测试和Jav Rok的回答,mousedown似乎是要走的路。浏览器确实表现得有点不同,具体取决于所做的事情。如果值恢复到原始值(而不是前一个值),则Firefox将触发更改事件,但chrome,IE和iPad Safari不会。此外,IE和iPad Safari需要手动调用.blur(),否则它实际上不会离开控件(因为屏幕键盘因此在iPad上特别烦人)。
因此,通过一些小的调整,可以使用以下小提琴来达到可接受的行为:http://jsfiddle.net/Lcyte5h5/14/
取消按钮处理程序如下:
$('.largerEventContainer').on('change', 'input, textarea', function () {
$('#log').append('<div>change</div>');
if ($(this).val() != $(this).data('prevvalue')) {
$('#log').append('<div>saving</div>');
$(this).data('prevvalue', $(this).val())
}
});
$(document).on('focus', '.inlineControls textarea', function () {
var $control = $(this)
if ($(this).closest('.inlineControls').find('.saveOptions').length == 0) {
$(this).closest('.inlineControls')
.append($(document.createElement('div'))
.addClass('saveOptions')
.append($(document.createElement('span'))
.css('padding', '4px')
.html('Save')
.click(function () {
$(this).closest('.saveOptions').remove();
}))
.append($(document.createElement('span'))
.css('padding', '4px')
.html('Cancel')
.on('mousedown', function () {
var $control = $(this).closest('.inlineControls').find('textarea')
$control.val($control.data('prevvalue'));
$('#log').append('<div>reset</div>');
$control.blur();
$(this).closest('.saveOptions').remove();
})));
}
});