问题
I have this code to focus a textarea when the user clicks on the "Reply" button:
$('#reply_msg').live('mousedown', function() {
$(this).hide();
$('#reply_holder').show();
$('#reply_message').focus();
});
It shows the reply form, but the textarea won't focus. I'm adding the textarea via AJAX which is why I am using .live()
. The box that I add shows (I even add #reply_msg
via AJAX and stuff happens when I mouse down on it) but it won't focus on the textarea.
Edit
My HTML looks like:
<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>
回答1:
A mouse-click on a focusable element raises events in the following order:
- mousedown
- focus
- mouseup
- click
So, here's what's happening:
mousedown
is raised by<a>
- your event handler attempts to focus the
<textarea>
- the default event behavior of mousedown tries to focus
<a>
(which takes focus from the<textarea>
)
Here's a demo illustrating this behavior:
$("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>
So, how do we get around this?
Use event.preventDefault()
to suppress mousedown's default behavior:
$(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>
回答2:
Focusing on something from an event handler that, itself, grants focus, is always problematic. The general solution is to set focus after a timeout:
setTimeout(function() {
$('#reply_message').focus();
}, 0);
That lets the browser do its thing, and then you come back and yank focus over to where you want it.
回答3:
Could it be the same issue as this? jQuery Textarea focus
Try calling .focus()
after .show()
has completed.
$('#reply_msg').live('mousedown', function() {
$(this).hide();
$('#reply_holder').show("fast", function(){
$('#reply_message').focus();
});
});
回答4:
I ran into this issue today and in my case, it was caused by a bug in jQuery UI (v1.11.4) which causes textarea
elements inside of draggable/droppable elements to stop default click behavior before the textarea
receives the focus click.
The solution was to rework the UI so that the textarea
no longer appears inside the draggable element.
This was a particularly difficult issue to debug, so I am leaving an answer here in case others find it helpful.
来源:https://stackoverflow.com/questions/8380759/why-isnt-this-textarea-focusing-with-focus