JavaScript를 사용한 Textarea Selection에서 진행되는 일을 이해합니다
-
03-07-2019 - |
문제
나는 a 내에서 브라우저 편집자를 작업하고 있습니다 textarea
. 나는 다루기위한 정보를 찾기 시작했다. textarea
선택 및 발견 이 jQuery 플러그인, 필드 선택 그것은 간단한 조작을합니다.
그러나 무슨 일이 일어나고 있는지 설명하지 않습니다.
JavaScript의 TextRea 선택에 대해 더 많이 이해하고 싶습니다.
해결책
PPK로 시작하십시오 범위 소개. Mozilla Developer Connection에는 정보가 있습니다 W3C 선택. Microsoft에는 시스템이 있습니다 MSDN에 문서화되었습니다. 더 많은 트릭을 찾을 수 있습니다 여기서 답에.
호환되지 않는 인터페이스 외에도 여분의 기괴함이 함께 있음을 알게되어 기쁩니다. textarea
노드. 내가 올바르게 기억한다면 IE에서 선택할 때 다른 노드처럼 행동하지만 다른 브라우저에는 독립적 인 선택 범위가 있습니다. .selectionEnd
그리고 .selectionStart
노드의 속성.
또한 실제로 살펴 봐야합니다 .contentEditable
사물을 편집하는 수단으로 살아갑니다. Firefox3의 릴리스에서 이것은 이제 모든 브라우저에서 지원됩니다.
다른 팁
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가 제시 한 솔루션을 채택하고 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));
누군가가 유용하다는 것을 알게되기를 바랍니다!
내가 추가 할 수있는 유일한 것은 콘텐츠를 구분할 때마다 이것이 완전히 스크롤해야한다는 것이 (AC에서 시도하지 않은 것처럼 보인다는 것입니다. eay 구제책은 그 선을 마무리하는 것입니다.
e.value =
Scrolltop을 복사하고 복원 할 두 줄이 있습니다.
var rememberScrollTop = e.scrollTop;
e.value = .... (same as in user357565 snippet)
e.scrollTop = rememberScrollTop;