了解如何使用JavaScriptselecttextarea
我正在一个textarea
内的浏览器内编辑器工作。 我已经开始寻找处理textarea
select的一些信息,并发现这个jQuery插件,fieldSelection ,做一些简单的操作。
但是,这并没有解释发生了什么事情。
我想了解更多关于在JavaScript中的textareaselect,最好与前DOM3和后DOM30scheme的描述。
从PPK 介绍范围开始 。 Mozilla开发人员连接有关于W3Cselect的信息。 Microsoft 在MSDN上logging了他们的系统。 在这里的答案可以find更多的技巧。
除了不兼容的界面,你会很高兴知道textarea
节点还有额外的奇怪之处。 如果我没有记错的话,当你在IE中select它们时,它们的行为与其他节点一样,但在其他浏览器中,它们有一个独立的select范围,通过节点上的.selectionEnd
和.selectionStart
属性公开。
此外,你应该看看.contentEdiable
作为一种手段来编辑现场直播。 从Firefox3发布以来,所有浏览器都支持这一function。
function get_selection(the_id) { var e = document.getElementById(the_id); //Mozilla and DOM 3.0 if('selectionStart' in e) { var l = e.selectionEnd - e.selectionStart; return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) }; } //IE else if(document.selection) { e.focus(); var r = document.selection.createRange(); var tr = e.createTextRange(); var tr2 = tr.duplicate(); tr2.moveToBookmark(r.getBookmark()); tr.setEndPoint('EndToStart',tr2); if (r == null || tr == null) return { start: e.value.length, end: e.value.length, length: 0, text: '' }; var text_part = r.text.replace(/[\r\n]/g,'.'); //for some reason IE doesn't always count the \n and \r in the length var text_whole = e.value.replace(/[\r\n]/g,'.'); var the_start = text_whole.indexOf(text_part,tr.text.length); return { start: the_start, end: the_start + text_part.length, length: text_part.length, text: r.text }; } //Browser not supported else return { start: e.value.length, end: e.value.length, length: 0, text: '' }; } function replace_selection(the_id,replace_str) { var e = document.getElementById(the_id); selection = get_selection(the_id); var start_pos = selection.start; var end_pos = start_pos + replace_str.length; e.value = e.value.substr(0, start_pos) + replace_str + e.value.substr(selection.end, e.value.length); set_selection(the_id,start_pos,end_pos); return {start: start_pos, end: end_pos, length: replace_str.length, text: replace_str}; } function set_selection(the_id,start_pos,end_pos) { var e = document.getElementById(the_id); //Mozilla and DOM 3.0 if('selectionStart' in e) { e.focus(); e.selectionStart = start_pos; e.selectionEnd = end_pos; } //IE else if(document.selection) { e.focus(); var tr = e.createTextRange(); //Fix IE from counting the newline characters as two seperate characters var stop_it = start_pos; for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) start_pos = start_pos - .5; stop_it = end_pos; for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) end_pos = end_pos - .5; tr.moveEnd('textedit',-1); tr.moveStart('character',start_pos); tr.moveEnd('character',end_pos - start_pos); tr.select(); } return get_selection(the_id); } function wrap_selection(the_id, left_str, right_str, sel_offset, sel_length) { var the_sel_text = get_selection(the_id).text; var selection = replace_selection(the_id, left_str + the_sel_text + right_str ); if(sel_offset !== undefined && sel_length !== undefined) selection = set_selection(the_id, selection.start + sel_offset, selection.start + sel_offset + sel_length); else if(the_sel_text == '') selection = set_selection(the_id, selection.start + left_str.length, selection.start + left_str.length); return selection; }
我刚刚采用了user357565提供的解决scheme,并logging了jQuery直接使用:
(function ($) { $.fn.get_selection = function () { var e = this.get(0); //Mozilla and DOM 3.0 if('selectionStart' in e) { var l = e.selectionEnd - e.selectionStart; return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) }; } else if(document.selection) { //IE e.focus(); var r = document.selection.createRange(); var tr = e.createTextRange(); var tr2 = tr.duplicate(); tr2.moveToBookmark(r.getBookmark()); tr.setEndPoint('EndToStart',tr2); if (r == null || tr == null) return { start: e.value.length, end: e.value.length, length: 0, text: '' }; var text_part = r.text.replace(/[\r\n]/g,'.'); //for some reason IE doesn't always count the \n and \r in length var text_whole = e.value.replace(/[\r\n]/g,'.'); var the_start = text_whole.indexOf(text_part,tr.text.length); return { start: the_start, end: the_start + text_part.length, length: text_part.length, text: r.text }; } //Browser not supported else return { start: e.value.length, end: e.value.length, length: 0, text: '' }; }; $.fn.set_selection = function (start_pos,end_pos) { var e = this.get(0); //Mozilla and DOM 3.0 if('selectionStart' in e) { e.focus(); e.selectionStart = start_pos; e.selectionEnd = end_pos; } else if (document.selection) { //IE e.focus(); var tr = e.createTextRange(); //Fix IE from counting the newline characters as two seperate characters var stop_it = start_pos; for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) start_pos = start_pos - .5; stop_it = end_pos; for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) end_pos = end_pos - .5; tr.moveEnd('textedit',-1); tr.moveStart('character',start_pos); tr.moveEnd('character',end_pos - start_pos); tr.select(); } return this.get_selection(); }; $.fn.replace_selection = function (replace_str) { var e = this.get(0); selection = this.get_selection(); var start_pos = selection.start; var end_pos = start_pos + replace_str.length; e.value = e.value.substr(0, start_pos) + replace_str + e.value.substr(selection.end, e.value.length); this.set_selection(start_pos,end_pos); return {start: start_pos, end: end_pos, length: replace_str.length, text: replace_str}; }; $.fn.wrap_selection = function (left_str, right_str, sel_offset, sel_length) { var the_sel_text = this.get_selection().text; var selection = this.replace_selection(left_str + the_sel_text + right_str ); if(sel_offset !== undefined && sel_length !== undefined) selection = this.set_selection(selection.start + sel_offset, selection.start + sel_offset + sel_length); else if(the_sel_text == '') selection = this.set_selection(selection.start + left_str.length, selection.start + left_str.length); return selection; }; }(jQuery));
我希望有人发现它有用!
我唯一可以补充的是,它似乎(没有通过尝试),这应该滚动一直向上,无论何时你manpulate内容。 一个补偿办法是包装行
e.value =
用两行来复制和恢复scrollTop,就像这样:
var rememberScrollTop = e.scrollTop; e.value = .... (same as in user357565 snippet) e.scrollTop = rememberScrollTop;