execCommand에서 '일반 텍스트로 붙여 넣기'에 대한 Javascript 트릭
execCommand
여기에 소개 된 샘플을 기반으로 한 기본 편집기가 있습니다. execCommand
영역 내에 텍스트를 붙여 넣는 세 가지 방법이 있습니다.
- Ctrl+V
- 마우스 오른쪽 버튼 클릭-> 붙여 넣기
- 오른쪽 클릭-> 일반 텍스트로 붙여 넣기
HTML 마크 업없이 일반 텍스트 만 붙여 넣기를 허용하고 싶습니다. 처음 두 작업을 강제로 일반 텍스트를 붙여 넣을 수 있습니까?
가능한 해결책 : 내가 생각할 수있는 방법은 ( Ctrl+ V)에 대한 keyup 이벤트에 대한 리스너를 설정 하고 붙여 넣기 전에 HTML 태그를 제거하는 것입니다.
- 최상의 솔루션입니까?
- 붙여 넣을 때 HTML 마크 업을 피하는 것이 방탄입니까?
- 오른쪽 클릭-> 붙여 넣기에 리스너를 추가하는 방법은 무엇입니까?
paste
이벤트 를 가로 채고를 취소 paste
하고 클립 보드의 텍스트 표현을 수동으로 삽입합니다 :
http://jsfiddle.net/HBEzc/ . 가장 신뢰할 수 있어야합니다.
- 모든 종류의 붙여 넣기 ( Ctrl+ V, 컨텍스트 메뉴 등)를 포착합니다 .
- 클립 보드 데이터를 텍스트로 직접 가져올 수 있으므로 HTML을 대체하기 위해 추악한 해킹을 할 필요가 없습니다.
그래도 브라우저 간 지원이 확실하지 않습니다.
editor.addEventListener("paste", function(e) {
// cancel paste
e.preventDefault();
// get text representation of clipboard
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
// insert text manually
document.execCommand("insertHTML", false, text);
});
IE에서 작업하기 위해 여기에서 허용되는 답변을 얻을 수 없었기 때문에 몇 가지 정찰을 수행하고 IE11과 최신 버전의 Chrome 및 Firefox에서 작동하는이 답변에 도달했습니다.
$('[contenteditable]').on('paste', function(e) {
e.preventDefault();
var text = '';
if (e.clipboardData || e.originalEvent.clipboardData) {
text = (e.originalEvent || e).clipboardData.getData('text/plain');
} else if (window.clipboardData) {
text = window.clipboardData.getData('Text');
}
if (document.queryCommandSupported('insertText')) {
document.execCommand('insertText', false, text);
} else {
document.execCommand('paste', false, text);
}
});
pimvdb와 같은 가까운 솔루션. 그러나 FF, Chrome 및 IE 9에서 작동합니다.
editor.addEventListener("paste", function(e) {
e.preventDefault();
if (e.clipboardData) {
content = (e.originalEvent || e).clipboardData.getData('text/plain');
document.execCommand('insertText', false, content);
}
else if (window.clipboardData) {
content = window.clipboardData.getData('Text');
document.selection.createRange().pasteHTML(content);
}
});
물론 질문은 이미 답변되었고 주제는 매우 오래되었지만 간단하고 깨끗한 솔루션을 제공하고 싶습니다.
이것은 내 contenteditable-div의 붙여 넣기 이벤트 안에 있습니다.
var text = '';
var that = $(this);
if (e.clipboardData)
text = e.clipboardData.getData('text/plain');
else if (window.clipboardData)
text = window.clipboardData.getData('Text');
else if (e.originalEvent.clipboardData)
text = $('<div></div>').text(e.originalEvent.clipboardData.getData('text'));
if (document.queryCommandSupported('insertText')) {
document.execCommand('insertHTML', false, $(text).html());
return false;
}
else { // IE > 7
that.find('*').each(function () {
$(this).addClass('within');
});
setTimeout(function () {
// nochmal alle durchlaufen
that.find('*').each(function () {
// wenn das element keine klasse 'within' hat, dann unwrap
// http://api.jquery.com/unwrap/
$(this).not('.within').contents().unwrap();
});
}, 1);
}
다른 부분은 내가 더 이상 찾을 수없는 다른 SO- 포스트에서 가져온 것입니다 ...
업데이트 19.11.2014 : 다른 SO 포스트
Firefox는 클립 보드 데이터에 액세스하는 것을 허용하지 않으므로 작동하려면 '핵'을 만들어야합니다. 완전한 솔루션을 찾을 수 없었지만 텍스트 영역을 만들고 대신 붙여 넣어 ctrl + v 붙여 넣기로 해결할 수 있습니다.
//Test if browser has the clipboard object
if (!window.Clipboard)
{
/*Create a text area element to hold your pasted text
Textarea is a good choice as it will make anything added to it in to plain text*/
var paster = document.createElement("textarea");
//Hide the textarea
paster.style.display = "none";
document.body.appendChild(paster);
//Add a new keydown event tou your editor
editor.addEventListener("keydown", function(e){
function handlePaste()
{
//Get the text from the textarea
var pastedText = paster.value;
//Move the cursor back to the editor
editor.focus();
//Check that there is a value. FF throws an error for insertHTML with an empty string
if (pastedText !== "") document.execCommand("insertHTML", false, pastedText);
//Reset the textarea
paster.value = "";
}
if (e.which === 86 && e.ctrlKey)
{
//ctrl+v => paste
//Set the focus on your textarea
paster.focus();
//We need to wait a bit, otherwise FF will still try to paste in the editor => settimeout
window.setTimeout(handlePaste, 1);
}
}, false);
}
else //Pretty much the answer given by pimvdb above
{
//Add listener for paster to force paste-as-plain-text
editor.addEventListener("paste", function(e){
//Get the plain text from the clipboard
var plain = (!!e.clipboardData)? e.clipboardData.getData("text/plain") : window.clipboardData.getData("Text");
//Stop default paste action
e.preventDefault();
//Paste plain text
document.execCommand("insertHTML", false, plain);
}, false);
}
게시 된 답변 중 어떤 것도 브라우저 간 작동하지 않거나 솔루션이 너무 복잡합니다.
- 이 명령
insertText
은 IE에서 지원되지 않습니다. paste
명령을 사용하면 IE11에서 스택 오버플로 오류가 발생합니다.
나를 위해 일한 것 (IE11, Edge, Chrome 및 FF)은 다음과 같습니다.
$("div[contenteditable=true]").off('paste').on('paste', function(e) {
e.preventDefault();
var text = e.originalEvent.clipboardData ? e.originalEvent.clipboardData.getData('text/plain') : window.clipboardData.getData('Text');
_insertText(text);
});
function _insertText(text) {
// use insertText command if supported
if (document.queryCommandSupported('insertText')) {
document.execCommand('insertText', false, text);
}
// or insert the text content at the caret's current position
// replacing eventually selected content
else {
var range = document.getSelection().getRangeAt(0);
range.deleteContents();
var textNode = document.createTextNode(text);
range.insertNode(textNode);
range.selectNodeContents(textNode);
range.collapse(false);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<textarea name="t1"></textarea>
<div style="border: 1px solid;" contenteditable="true">Edit me!</div>
<input />
</body>
Note that the custom paste handler is only needed/working for contenteditable
nodes. As both textarea
and plain input
fields don't support pasting HTML content at all, so nothing needs to be done here.
I was also working on a plain text paste and I started to hate all the execCommand and getData errors, so I decided to do it the classic way and it works like a charm:
$('#editor').bind('paste', function(){
var before = document.getElementById('editor').innerHTML;
setTimeout(function(){
var after = document.getElementById('editor').innerHTML;
var pos1 = -1;
var pos2 = -1;
for (var i=0; i<after.length; i++) {
if (pos1 == -1 && before.substr(i, 1) != after.substr(i, 1)) pos1 = i;
if (pos2 == -1 && before.substr(before.length-i-1, 1) != after.substr(after.length-i-1, 1)) pos2 = i;
}
var pasted = after.substr(pos1, after.length-pos2-pos1);
var replace = pasted.replace(/<[^>]+>/g, '');
var replaced = after.substr(0, pos1)+replace+after.substr(pos1+pasted.length);
document.getElementById('editor').innerHTML = replaced;
}, 100);
});
The code with my notations can be found here: http://www.albertmartin.de/blog/code.php/20/plain-text-paste-with-javascript
function PasteString() {
var editor = document.getElementById("TemplateSubPage");
editor.focus();
// editor.select();
document.execCommand('Paste');
}
function CopyString() {
var input = document.getElementById("TemplateSubPage");
input.focus();
// input.select();
document.execCommand('Copy');
if (document.selection || document.textSelection) {
document.selection.empty();
} else if (window.getSelection) {
window.getSelection().removeAllRanges();
}
}
Above code works for me in IE10 and IE11 and now also works in Chrome and Safari. Not tested in Firefox.
In IE11, execCommand doesn't work well. I use below code for IE11 <div class="wmd-input" id="wmd-input-md" contenteditable=true>
is my div box.
I read clipboard data from window.clipboardData and modify div's textContent and give caret.
I give timeout for setting caret, because if I don't set timeout, a caret goes to end of div.
and you should read clipboardData in IE11 in below way. If you don't do it, newline caracter is not handled properly, so caret goes wrong.
var tempDiv = document.createElement("div");
tempDiv.textContent = window.clipboardData.getData("text");
var text = tempDiv.textContent;
Tested on IE11 and chrome. It may not work on IE9
document.getElementById("wmd-input-md").addEventListener("paste", function (e) {
if (!e.clipboardData) {
//For IE11
e.preventDefault();
e.stopPropagation();
var tempDiv = document.createElement("div");
tempDiv.textContent = window.clipboardData.getData("text");
var text = tempDiv.textContent;
var selection = document.getSelection();
var start = selection.anchorOffset > selection.focusOffset ? selection.focusOffset : selection.anchorOffset;
var end = selection.anchorOffset > selection.focusOffset ? selection.anchorOffset : selection.focusOffset;
selection.removeAllRanges();
setTimeout(function () {
$(".wmd-input").text($(".wmd-input").text().substring(0, start)
+ text
+ $(".wmd-input").text().substring(end));
var range = document.createRange();
range.setStart(document.getElementsByClassName("wmd-input")[0].firstChild, start + text.length);
range.setEnd(document.getElementsByClassName("wmd-input")[0].firstChild, start + text.length);
selection.addRange(range);
}, 1);
} else {
//For Chrome
e.preventDefault();
var text = e.clipboardData.getData("text");
var selection = document.getSelection();
var start = selection.anchorOffset > selection.focusOffset ? selection.focusOffset : selection.anchorOffset;
var end = selection.anchorOffset > selection.focusOffset ? selection.anchorOffset : selection.focusOffset;
$(this).text($(this).text().substring(0, start)
+ text
+ $(this).text().substring(end));
var range = document.createRange();
range.setStart($(this)[0].firstChild, start + text.length);
range.setEnd($(this)[0].firstChild, start + text.length);
selection.removeAllRanges();
selection.addRange(range);
}
}, false);
After along search and trying I have found somehow kind of optimal solution
what is important to keep in mind
// /\x0D/g return key ASCII
window.document.execCommand('insertHTML', false, text.replace('/\x0D/g', "\\n"))
and give the css style white-space: pre-line //for displaying
var contenteditable = document.querySelector('[contenteditable]')
contenteditable.addEventListener('paste', function(e){
let text = ''
contenteditable.classList.remove('empty')
e.preventDefault()
text = (e.originalEvent || e).clipboardData.getData('text/plain')
e.clipboardData.setData('text/plain', '')
window.document.execCommand('insertHTML', false, text.replace('/\x0D/g', "\\n"))// /\x0D/g return ASCII
})
#input{
width: 100%;
height: 100px;
border: 1px solid black;
white-space: pre-line;
}
<div id="input"contenteditable="true">
<p>
</p>
</div>
참고URL : https://stackoverflow.com/questions/12027137/javascript-trick-for-paste-as-plain-text-in-execcommand
'program story' 카테고리의 다른 글
HttpClient로 신뢰할 수없는 SSL 인증서 허용 (0) | 2020.08.31 |
---|---|
src / lxml / etree_defs.h : 9 : 31 : 치명적인 오류 : libxml / xmlversion.h : 해당 파일 또는 디렉터리가 없습니다. (0) | 2020.08.31 |
Elasticsearch 최대 메모리 크기를 변경하는 방법 (0) | 2020.08.31 |
E : mongodb-org 패키지를 찾을 수 없습니다. (0) | 2020.08.31 |
RecyclerView에서 마지막 자식의 여백 / 패딩 (0) | 2020.08.31 |