jquery点击事件模糊后丢失

问题描述:

我有一个textarea字段,我希望它在获得焦点时展开,并在失去焦点时收缩。这里是我的测试代码:jquery点击事件模糊后丢失

$(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和SO搜索相关的问题,并没有发现在模糊的顺序了多次讨论,并单击事件。通常,解决方案似乎涉及在blur()操作上添加延迟,或者在其他页面元素上绑定事件以跟踪发生的事件。

这两种方法看起来相当脆弱和容易出错。这种行为实际上只是一个很好的做法,所以如果没有“干净”的方式去做,我宁愿完全放弃它。

仅供参考,延迟的方法做工作,可以在这个小提琴可以看出: http://jsfiddle.net/p0t1pzh7/5/

我明白为什么模糊点击之前触发,但发现它令人惊讶的是,点击事件”不是个目标t在模糊被触发之前“设置”。这是预期的行为还是不同浏览器之间?

你可以使用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); 

demo

+0

谢谢,但我希望有一个不依赖于延迟的解决方案。我在问题结束时提到我已确认延迟方法确实有效,并与一个小提琴例子相关联。 – mla 2014-09-28 22:31:49

+0

没有任何其他选择,因为您必须管理代码之间的差距...... – 2014-09-28 22:41:51

+0

我意识到最初我希望没有超时的解决方案,但实际上,这似乎是最简单的方法。我已经有一段时间在生产中运行,没有用户的投诉。 – mla 2015-02-20 03:07:24

Try this solution

$(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; 
} 
+0

这似乎不适用于我。编辑示例小提琴包括一堆链接:http://jsfiddle.net/JdA6L/45/ 至少对我来说,当我在textarea并点击其中一个链接时,textarea会崩溃,但我不要警惕。 – mla 2014-09-28 22:25:52

+0

评论这条线它的工作// $(this).removeClass(“扩大”) – 2014-09-28 22:40:26

+0

嘿,这对我有用:)你明白为什么注释掉removeClass()修复它? – mla 2014-09-28 22:45:52

引入的延迟作品:

$(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); 
    }); 
}); 

他re是一种不使用任何超时的解决方案。见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; 
     } 
    }); 

}); 

我beleive你是在假设原始点击事件正确不点火,因为目标区域移出的位置之前的事件可以是评估。'mousedown'似乎在模糊之前评估,因此我们可以用'mousedown'捕获点击目标信息,然后在'mouseup'上操作事件。拥有更大的目标,更少戏剧性的动画和更慢的动画也可以解决这个问题。