컨텐츠 편집 가능한 엔티티의 끝으로 커서를 이동하는 방법
contenteditable
Gmail 노트 위젯 에서처럼 캐럿을 노드 끝으로 이동해야합니다 .
StackOverflow에서 스레드를 읽었지만 해당 솔루션은 입력 사용을 기반으로하며 contenteditable
요소 와 함께 작동하지 않습니다 .
또 다른 문제가 있습니다.
니코 화상 경우의 솔루션은 작동 contenteditable
사업부 다른 multilined 요소를 포함하지 않습니다.
예를 들어 div에 다른 div가 포함되어 있고 이러한 다른 div에 다른 내용이 포함되어 있으면 몇 가지 문제가 발생할 수 있습니다.
이를 해결하기 위해 다음과 같은 해결책을 마련했습니다. 이것은 Nico 의 개선입니다 .
//Namespace management idea from http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/
(function( cursorManager ) {
//From: http://www.w3.org/TR/html-markup/syntax.html#syntax-elements
var voidNodeTags = ['AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX'];
//From: https://stackoverflow.com/questions/237104/array-containsobj-in-javascript
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
//Basic idea from: https://stackoverflow.com/questions/19790442/test-if-an-element-can-contain-text
function canContainText(node) {
if(node.nodeType == 1) { //is an element node
return !voidNodeTags.contains(node.nodeName);
} else { //is not an element node
return false;
}
};
function getLastChildElement(el){
var lc = el.lastChild;
while(lc && lc.nodeType != 1) {
if(lc.previousSibling)
lc = lc.previousSibling;
else
break;
}
return lc;
}
//Based on Nico Burns's answer
cursorManager.setEndOfContenteditable = function(contentEditableElement)
{
while(getLastChildElement(contentEditableElement) &&
canContainText(getLastChildElement(contentEditableElement))) {
contentEditableElement = getLastChildElement(contentEditableElement);
}
var range,selection;
if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
{
range = document.createRange();//Create a range (a range is a like the selection but invisible)
range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
selection = window.getSelection();//get the selection object (allows you to change selection)
selection.removeAllRanges();//remove any selections already made
selection.addRange(range);//make the range you have just created the visible selection
}
else if(document.selection)//IE 8 and lower
{
range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
range.select();//Select the range (make it the visible selection
}
}
}( window.cursorManager = window.cursorManager || {}));
용법:
var editableDiv = document.getElementById("my_contentEditableDiv");
cursorManager.setEndOfContenteditable(editableDiv);
이런 식으로 커서는 확실히 마지막 요소의 끝에 위치하며 결국 중첩됩니다.
편집 # 1 : 더 일반적으로 사용하려면 while 문은 텍스트를 포함 할 수없는 다른 모든 태그도 고려해야합니다. 이러한 요소는 명명 된 무효 요소를 , 그리고에서 이 문제 요소가 무효 인 경우 테스트하는 방법에 대한 몇 가지 방법이 있습니다. 따라서 인수가 void 요소가 아닌 경우 canContainText
반환 하는 함수가 있다고 가정 true
하면 다음 코드 줄이 표시됩니다.
contentEditableElement.lastChild.tagName.toLowerCase() != 'br'
다음으로 교체해야합니다.
canContainText(getLastChildElement(contentEditableElement))
편집 # 2 : 위의 코드는 모든 변경 사항을 설명하고 논의하면서 완전히 업데이트되었습니다.
Geowa4의 솔루션은 텍스트 영역에서는 작동하지만 콘텐츠 편집 가능한 요소에는 작동하지 않습니다.
이 솔루션은 캐럿을 contenteditable 요소의 끝으로 이동하기위한 것입니다. contenteditable을 지원하는 모든 브라우저에서 작동합니다.
function setEndOfContenteditable(contentEditableElement)
{
var range,selection;
if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
{
range = document.createRange();//Create a range (a range is a like the selection but invisible)
range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
selection = window.getSelection();//get the selection object (allows you to change selection)
selection.removeAllRanges();//remove any selections already made
selection.addRange(range);//make the range you have just created the visible selection
}
else if(document.selection)//IE 8 and lower
{
range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
range.select();//Select the range (make it the visible selection
}
}
다음과 유사한 코드에서 사용할 수 있습니다.
elem = document.getElementById('txt1');//This is the element that you want to move the caret to the end of
setEndOfContenteditable(elem);
If you don't care about older browsers, this one did the trick for me.
// [optional] make sure focus is on the element
yourContentEditableElement.focus();
// select all the content in the element
document.execCommand('selectAll', false, null);
// collapse selection to the end
document.getSelection().collapseToEnd();
It's possible to do set cursor to the end through the range:
setCaretToEnd(target/*: HTMLDivElement*/) {
const range = document.createRange();
const sel = window.getSelection();
range.selectNodeContents(target);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
target.focus();
range.detach(); // optimization
// set scroll to the end if multiline
target.scrollTop = target.scrollHeight;
}
I had a similar problem trying to make a element editable. It was possible in Chrome and FireFox but in FireFox the caret either went to the beginning of the input or it went one space after the end of the input. Very confusing to the end-user I think, trying to edit the content.
I found no solution trying several things. Only thing that worked for me was to "go around the problem" by putting a plain old text-input INSIDE my . Now it works. Seems like "content-editable" is still bleeding edge tech, which may or may not work as you would like it to work, depending on the context.
Moving cursor to the end of editable span in response to focus event:
moveCursorToEnd(el){
if(el.innerText && document.createRange)
{
window.setTimeout(() =>
{
let selection = document.getSelection();
let range = document.createRange();
range.setStart(el.childNodes[0],el.innerText.length);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
}
,1);
}
}
And calling it in event handler (React here):
onFocus={(e) => this.moveCursorToEnd(e.target)}}
참고URL : https://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity
'Nice programing' 카테고리의 다른 글
현재 사용 중이므로 데이터베이스를 삭제할 수 없습니다. (0) | 2020.10.22 |
---|---|
Xcode 6 및 10.10 Yosemite가 포함 된 Cocoapods (0) | 2020.10.22 |
UICollectionViewController에서 당겨서 새로 고침 (0) | 2020.10.22 |
쉼표로 구분 된 쉘 변수를 통해 루프 (0) | 2020.10.22 |
Chrome DevTools를 열 때마다 기본적으로 "콘솔 드로어"를 숨기려면 어떻게해야합니까? (0) | 2020.10.22 |