开发者

Bug w IE8 Using Javascript to Insert Text at Caret

Focusing on IE, I have a textbox (single line <input/>) for which I need to insert text where the caret/cursor is. The text within a div is inserted at the caret position when the div is double clicked.

Bug: Text is inserted into the textbox, but at the beginning of the string in the textbox and not where the caret position is.

The following code works fine using the multiline input (no bug), the bug only occurs with the single line input.

Here is the simple Javascript for IE (other browser support has been removed for simplicity):

$.fn.insertAtCaret = function (tagName) {
    return this.each(function () {
        if (this.selectionStart || this.selectionStart == '0') {
            //MOZILLA support
        } else if (document.selection) {
            //IE support
         开发者_如何学Go   this.focus();
            sel = document.selection.createRange();
            sel.text = tagName;
        } else {
            //ELSE
        }
    });
};

Just so you have everything in front of you, here is the JQuery that calls $.fn.insertAtCaret:

$("#Subject").mousedown(function () { $("#InsertAtCaretFor").val("Subject"); });
$("#Subject").bind('click, focus, keyup', function () { $("#InsertAtCaretFor").val("Subject"); });

$("#Comment").mousedown(function () { $("#InsertAtCaretFor").val("Comment"); });
$("#Comment").bind('click, focus, keyup', function () { $("#InsertAtCaretFor").val("Comment"); });

$(".tag").dblclick(function () {
    if ($("#InsertAtCaretFor").val() == "Comment") $("#Comment").insertAtCaret($(this).text());
    if ($("#InsertAtCaretFor").val() == "Subject") $("#Subject").insertAtCaret($(this).text());
});

As you can see, when one of the two <input/>s are clicked, focused, etc., a hidden field (ID="InsertAtCaretFor") value is set to either "Subject" or "Comment". When the tag is double-clicked, its .text() is inserted at the caret position within the <input/> specified by the hidden field's value.

Here are the fields:

<%=Html.Hidden("InsertAtCaretFor") %>
<div class="form_row">
    <label for="Subject" class="forField">
        Subject:</label>
    <%= Html.TextBox("Subject", "", new Dictionary<string, object> { { "class", "required no-auto-validation" }, { "style", "width:170px;" }, { "maxlength", "200" } })%>
</div>
<div class="form_row">
    <label for="Comment" class="forField">
        Comment:</label>
    <%= Html.TextArea("Comment", new Dictionary<string,object> { {"rows","10"}, {"cols","50"}, { "class", "required"} })%>
</div>

Finally, here is an image so you can visually understand what I'm doing:

http://www.danielmckenzie.net/ie8bug.png

Bug w IE8 Using Javascript to Insert Text at Caret


I'm using a different insertAtCaret code I found from googling around. Works on single inputs and textareas just fine.

 $.fn.extend({
 insertAtCaret: function (myValue) {
    var $input;
    if (typeof this[0].name != 'undefined')
        $input = this[0];
    else
        $input = this;

    if ($.browser.msie) {
        $input.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
        $input.focus();
    }
    else if ($.browser.mozilla || $.browser.webkit) {
        var startPos = $input.selectionStart;
        var endPos = $input.selectionEnd;
        var scrollTop = $input.scrollTop;
        $input.value = $input.value.substring(0, startPos) + myValue + $input.value.substring(endPos, $input.value.length);
        $input.focus();
        $input.selectionStart = startPos + myValue.length;
        $input.selectionEnd = startPos + myValue.length;
        $input.scrollTop = scrollTop;
    } else {
        $input.value += myValue;
        $input.focus();
    }
}
});

After looking at your js code I'd change:

$(".tag").dblclick(function () {
 if ($("#InsertAtCaretFor").val() == "Comment")     $("#Comment").insertAtCaret($(this).text());
if ($("#InsertAtCaretFor").val() == "Subject")     $("#Subject").insertAtCaret($(this).text());
});

To the following:

$(".tag").dblclick(function () {
     if ($("#InsertAtCaretFor").val() == "Comment") {    
           $("#Comment").insertAtCaret($(this).text());
     }
     if ($("#InsertAtCaretFor").val() == "Subject") {                  
           $("#Subject").insertAtCaret($(this).text());
     }
});

Those two inline if statements with no ending curly brace look dangerous!


I've come the same problem myself in IE8. It seems that for INPUT type="text", it does not fill in selectionStart and selectionEnd. IE9 does, however.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜