我有一个textarea字段,我想在它获得焦点时扩展,并在失去焦点时收缩。这是我的测试代码:
$(function() {
var rows = parseInt(
$('textarea[name=details]').attr('rows')
);
$('textarea[name=details]').focus(function() {
$(this).animate({ rows: rows + 10 }, 250);
}).blur(function(e) {
$(this).animate({ rows: rows }, 250);
});
});
小提琴: http://jsfiddle.net/p0t1pzh7/3/
问题是当textarea具有焦点时,用户点击另一个输入元素。 在这种情况下,textarea会折回,但点击事件似乎丢失了。
我相信正在发生的事情,是blur()处理程序正在更改页面,以便点击目标更改位置。由于模糊在点击之前运行,因此实际上发生了点击,但由于目标已移动位置,因此点击不再是点击元素。这是在Linux下的Chrome 37.0.2062.120上。
我认为,如果你在模糊处理程序中注释掉textarea的大小调整,那么一切都按预期工作。
小提琴:http://jsfiddle.net/p0t1pzh7/4/
我用Google搜索并搜索了相关问题,并找到了关于模糊和点击事件排序的几个讨论。通常,解决方案似乎涉及在blur()操作上添加延迟,或在其他页面元素上绑定事件以跟踪正在发生的事情。
这两种方法都看起来相当脆弱且容易出错。这种行为实际上只是一种精确的行为,所以如果没有“干净”的方式去做,我宁愿放弃它。
作为参考,延迟方法确实有效,正如在这个小提琴中可以看到的那样: http://jsfiddle.net/p0t1pzh7/5/
我理解为什么在点击之前触发模糊,但是发现在触发模糊之前点击事件的目标没有“设置”是令人惊讶的。是预期的行为还是不同浏览器之间的差异?
答案 0 :(得分:2)
您可以使用setTimeout函数:
$('textarea[name=details]').focus(function() {
$(this).animate({ rows: rows + 10 }, 250);
}).blur(function(e) {
setTimeout(function(){
$(this).animate({ rows: rows }, 250);
}.bind(this),400);
答案 1 :(得分:1)
$(window).load(function () {
$('textarea.expand').focus(function () {
$(this).addClass("expanding")
$(this).animate({
height: "10em"
}, 500);
});
$('textarea.expand').blur(function () {
$(this).animate({
height: "1em"
}, 500);
// $(this).removeClass("expanding")
});
});
<table>
<tr>
<td>
<textarea class="expand" rows="1" cols="10"></textarea>
</td>
</tr>
<tr>
<td>Here is some text just below. Does it move?</td>
</tr>
</table>
.expand {
height: 1em;
line-height: 1em;
width: 300px;
padding: 3px;
}
.expanding {
position: absolute;
z-index: 9;
}
textarea {
resize: none;
}
答案 2 :(得分:1)
这是一个不使用任何超时的解决方案。见http://jsfiddle.net/29sw1abb/
HTML:
<textarea name="details" rows="5"></textarea>
<p>
<a href="#" class="button">click me</a>
</p>
JS
$(function() {
var target = undefined;
var rows = parseInt(
$('textarea[name=details]').attr('rows')
);
$('textarea[name=details]').focus(function() {
$(this).animate({ rows: rows + 10 }, 250);
}).blur(function(e) {
$(this).animate({ rows: rows }, 250);
});
$('.button').mousedown( function (e){
target = $(e.target).attr('class');
});
$(document).mouseup( function (e){
if (target) {
alert(target);
target = undefined;
}
});
});
我相信你是正确的假设原始点击事件没有被触发,因为目标区域在评估事件之前移出位置。 'mousedown'似乎在模糊之前进行评估,因此我们可以使用'mousedown'捕获点击目标信息,然后在'mouseup'上操作事件。拥有更大的目标,更少戏剧性的动画和更慢的动画也解决了这个问题。
答案 3 :(得分:0)
介绍延迟有效:
$(function() {
var rows = parseInt(
$('textarea[name=details]').attr('rows')
);
$('textarea[name=details]').focus(function() {
if (typeof(toDetails) != "undefined") { clearTimeout(toDetails); }
$(this).animate({ rows: rows + 10 }, 250);
}).blur(function(e) {
toDetails = setTimeout(function() { $(this).animate({ rows: rows }, 250); }.bind(this), 250);
});
});