为啥这个 textarea 不使用 .focus() 聚焦?

Posted

技术标签:

【中文标题】为啥这个 textarea 不使用 .focus() 聚焦?【英文标题】:Why isn't this textarea focusing with .focus()?为什么这个 textarea 不使用 .focus() 聚焦? 【发布时间】:2012-01-12 22:11:19 【问题描述】:

当用户点击“回复”按钮时,我有这段代码来聚焦文本区域:

    $('#reply_msg').live('mousedown', function() 
        $(this).hide();
        $('#reply_holder').show();
        $('#reply_message').focus();
    );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<div id="reply_msg">
      <div class="replybox">
      <span>Click here to <span class="link">Reply</span></span>
      </div>
      </div>
      <div id="reply_holder" style="display: none;">
      <div id="reply_tab"><img src="images/blank.gif" /> Reply</div>
      <label class="label" for="reply_subject" style="padding-top: 7px; width: 64px; color: #999; font-weight: bold; font-size: 13px;">Subject</label>
      <input type="text" id="reply_subject" class="input" style="width: 799px;" value="Re: <?php echo $info['subject']; ?>" />
      <br /><br />
      <textarea name="reply" id="reply_message" class="input" spellcheck="false"></textarea>
      <br />
      <div id="reply_buttons">
      <button type="button" class="button" id="send_reply">Send</button>
      <button type="button" class="button" id="cancel_reply_msg">Cancel</button>
      <!--<button type="button" class="button" id="save_draft_reply">Save Draft</button>-->
      </div>
    </div>

它显示回复表单,但文本区域不会聚焦。我通过 AJAX 添加文本区域,这就是我使用 .live() 的原因。我添加的框显示(我什至通过 AJAX 添加了#reply_msg,当我将鼠标放在它上面时会发生一些事情),但它不会专注于文本区域。

【问题讨论】:

【参考方案1】:

在可聚焦元素上单击鼠标会按以下顺序引发事件:

    鼠标按下 聚焦 鼠标移动 点击

所以,这就是发生的事情:

    mousedown&lt;a&gt; 提出 您的事件处理程序尝试聚焦&lt;textarea&gt; mousedown 的默认事件行为尝试聚焦 &lt;a&gt;(从 &lt;textarea&gt; 获取焦点)

这是一个演示此行为的演示:

$("a,textarea").on("mousedown mouseup click focus blur", function(e) 
  console.log("%s: %s", this.tagName, e.type);
)
$("a").mousedown(function(e) 
  $("textarea").focus();
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="javascript:void(0)">reply</a>
<textarea></textarea>

那么,我们如何解决这个问题?

使用event.@987654321@ 抑制mousedown 的默认行为:

$(document).on("mousedown", "#reply_msg", function(e) 
    e.preventDefault();
    $(this).hide();
    $("#reply_message").show().focus();
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="javascript:void(0)" id="reply_msg">reply</a>
<textarea id="reply_message"></textarea>

【讨论】:

我已经在这样做了,但它不起作用,但感谢您的回答:) 哦,是的,mouseup 确实有效 - 并且没有任何超时。谢谢:) 我知道这个答案发布已经有好几年了。我正在寻找有关事件引发顺序的信息,例如:mousedownfocusmouseupclick。 @canon 你能分享你从哪里拿来的吗?我在规范的两个部分都找不到它:w3.org/TR/uievents/#events-focusevent-event-order、w3.org/TR/uievents/#legacy-uievent-event-order、w3.org/TR/uievents/#events-mouseevent-event-order @Chris92 测试和观察。 这不是标准化的浏览器行为吗?我希望这可以在规范中找到。【参考方案2】:

从一个事件处理程序中关注某些本身就授予焦点的东西总是有问题的。一般的解决方案是在超时后设置焦点:

setTimeout(function() 
  $('#reply_message').focus();
, 0);

这让浏览器做它的事,然后你回来把焦点拉到你想要的地方。

【讨论】:

既然可以一开始就使用适当的事件,为什么还要使用超时? @antisanity - 很好,如果这是 OP 真正感兴趣的内容。也就是说,如果对于这种特殊情况,“mouseup”事件与“mousedown”一样适用于所需的交互。 @canon 因为此解决方案适用于 OP 的特定情况之外。 为什么“总是有问题”?【参考方案3】:

会不会是和这个一样的问题? jQuery Textarea focus

.show() 完成后尝试调用.focus()

$('#reply_msg').live('mousedown', function() 
    $(this).hide();
    $('#reply_holder').show("fast", function()
        $('#reply_message').focus();
    ); 
);

【讨论】:

【参考方案4】:

我今天遇到了这个问题,就我而言,它是由 jQuery UI (v1.11.4) 中的一个错误引起的,它导致可拖动/可放置元素内的 textarea 元素在 textarea 之前停止默认点击行为接收焦点点击。

解决方案是重新设计 UI,使 textarea 不再出现在可拖动元素内。

这是一个特别难以调试的问题,因此我将在此处留下答案,以防其他人发现它有帮助。

【讨论】:

以上是关于为啥这个 textarea 不使用 .focus() 聚焦?的主要内容,如果未能解决你的问题,请参考以下文章

使用 :focus 设置外部 div 的样式?

如何自动对焦反应textarea?

使用 jQuery 为啥 IE/Chrome 最初会为 textarea 提供不正确的 clientHeight 和 scrollHeight?

为啥使用 novalidate 时会触发 twitter bootstrap input:focus:invalid:focus?

为啥这个 textarea 不能假设它在 Chrome 中的父级的全部高度?

为啥 textarea 不支持 iframe 嵌入? [复制]