contenteditable
要素があり、何かを入力してENTER
を押すと、新しい<div>
が作成され、そこに新しい行テキストが配置されます。私はこれが少し好きではありません。
これを防ぐことはできますか、少なくとも<br>
に置き換えてください。
注:これはfirefoxの問題ではありません。
これを試して
$('div[contenteditable]').keydown(function(e) {
// trap the return key being pressed
if (e.keyCode === 13) {
// insert 2 br tags (if only one br tag is inserted the cursor won't go to the next line)
document.execCommand('insertHTML', false, '<br><br>');
// prevent the default behaviour of return key pressed
return false;
}
});
CSSを変更するだけでこれを実行できます。
div{
background: skyblue;
padding:10px;
display: inline-block;
}
pre{
white-space: pre-wrap;
background: #EEE;
}
スタイルdisplay:inline-block;
をcontenteditable
に追加すると、Chromeでdiv
、p
、およびspan
が自動的に生成されません。
これを試して:
$('div[contenteditable="true"]').keypress(function(event) {
if (event.which != 13)
return true;
var docFragment = document.createDocumentFragment();
//add a new line
var newEle = document.createTextNode('\n');
docFragment.appendChild(newEle);
//add the br, or p, or something else
newEle = document.createElement('br');
docFragment.appendChild(newEle);
//make the br replace selection
var range = window.getSelection().getRangeAt(0);
range.deleteContents();
range.insertNode(docFragment);
//create a new range
range = document.createRange();
range.setStartAfter(newEle);
range.collapse(true);
//make the cursor there
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
return false;
});
document.execCommand('defaultParagraphSeparator', false, 'p');
代わりに段落を持つようにデフォルトの動作をオーバーライドします。
chromeでは、Enterのデフォルトの動作は次のとおりです。
<div>
<br>
</div>
そのコマンドでそれはなるだろう
<p>
<br>
</p>
全体的に線形になったので、必要なのは<br>
だけにするのは簡単です。
つかいます shift+enter の代わりに enter 単一の<br>
タグを挿入するか、<p>
タグでテキストをラップするだけです。
を押したときのcontenteditable
の動作 enter ブラウザに依存し、<div>
はWebkit(chrome、safari)およびIEで発生します。
私はこの数ヶ月前に苦労し、このように修正しました:
//I recommand you trigger this in case of focus on your contenteditable
if( navigator.userAgent.indexOf("msie") > 0 || navigator.userAgent.indexOf("webkit") > 0 ) {
//Add <br> to the end of the field for chrome and safari to allow further insertion
if(navigator.userAgent.indexOf("webkit") > 0)
{
if ( !this.lastChild || this.lastChild.nodeName.toLowerCase() != "br" ) {
$(this).html( $(this).html()+'<br />' );
}
}
$(this).keypress( function(e) {
if( ( e.keyCode || e.witch ) == 13 ) {
e.preventDefault();
if( navigator.userAgent.indexOf("msie") > 0 ) {
insertHtml('<br />');
}
else {
var selection = window.getSelection(),
range = selection.getRangeAt(0),
br = document.createElement('br');
range.deleteContents();
range.insertNode(br);
range.setStartAfter(br);
range.setEndAfter(br);
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
}
});
}
それが助けになることを望み、必要に応じて明確でない場合は私の英語を申し訳ありません。
EDIT:削除されたjQuery関数の修正jQuery.browser
この問題を解決するには、スタイリング(Css)を使用します。
div[contenteditable=true] > div {
padding: 0;
}
Firefoxは実際にブロック要素ブレークを追加します
に対して、Chromeはタグ内の各セクションをラップします。 cssは、divに背景色と共に10pxのパディングを与えます。
div{
background: skyblue;
padding:10px;
}
または、jQueryで同じ目的の効果を複製できます。
var style = $('<style>p[contenteditable=true] > div { padding: 0;}</style>');
$('html > head').append(style);
ここにあなたのフィドルのフォークがあります http://jsfiddle.net/R4Jdz/7/
divに防ぐデフォルトを追加します
document.body.div.onkeydown = function(e) {
if ( e.keycode == 13 ){
e.preventDefault();
//add a <br>
div = document.getElementById("myDiv");
div.innerHTML += "<br>";
}
}
<p>
タグを使用するのではなく、各行に個別の<br>
タグを付けて、すぐに使用できるブラウザーの互換性を高めることができます。
これを行うには、contenteditable div内にいくつかのデフォルトテキストを含む<p>
タグを配置します。
たとえば、次の代わりに:
<div contenteditable></div>
つかいます:
<div contenteditable>
<p>Replace this text with something awesome!</p>
</div>
Chrome、Firefox、およびEdgeでテストされ、2番目はそれぞれ同じ動作をします。
ただし、1つ目は、Chromeでdivを作成し、Firefoxで改行を作成し、Edgeでdivを作成しますandカーソルは先頭に戻されます次のdivに移動する代わりに現在のdiv。
Chrome、Firefox、およびEdgeでテスト済み。
Ckeditorを使用してみてください。また、SOFでこのようなフォーマットを提供します。
段落を<p>
タグでラップできます。たとえば、divの代わりに新しい行に配置されます。例:<div contenteditable="true"><p>Line</p></div>
新しい文字列を挿入した後:<div contenteditable="true"><p>Line</p><p>New Line</p></div>
最初にすべてのキーユーザーEnterをキャプチャしてEnterが押されたかどうかを確認し、次に<div>
の作成を禁止し、独自の<br>
タグを作成します。
1つの問題があります。それを作成するとき、カーソルは同じ位置に留まるため、 Selection API を使用してカーソルを最後に配置します。
テキストの最後に<br>
タグを追加することを忘れないでください。最初に入力しないと新しい行が作成されないためです。
$('div[contenteditable]').on('keydown', function(e) {
var key = e.keyCode,
el = $(this)[0];
// If Enter
if (key === 13) {
e.preventDefault(); // Prevent the <div /> creation.
$(this).append('<br>'); // Add the <br at the end
// Place selection at the end
// http://stackoverflow.com/questions/4233265/contenteditable-set-caret-at-the-end-of-the-text-cross-browser
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
});
if (navigator.userAgent.toLowerCase().indexOf('msie') > -1) {
var range = document.getSelection();
range.pasteHTML(range.htmlText + '<br><br>');
}
else if(navigator.userAgent.toLocaleLowerCase().indexOf('trident') > -1) {
var range = document.getSelection().getRangeAt(0); //get caret
var nnode = document.createElement('br');
var bnode = document.createTextNode('\u00A0'); //
range.insertNode(nnode);
this.appendChild(bnode);
range.insertNode(nnode);
}
else
document.execCommand('insertHTML', false, '<br><br>')
ここで、this
は、document.getElementById('test');
を意味する実際のコンテキストです。
inserHTML
コマンドソリューションは、contenteditable
要素をネストしている場合にいくつかの奇妙なことを行います。
ここで複数の回答からいくつかのアイデアを取りましたが、これは今のところ私のニーズに合っているようです:
element.addEventListener('keydown', function onKeyDown(e) {
// Only listen for plain returns, without any modifier keys
if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) {
return;
}
let doc_fragment = document.createDocumentFragment();
// Create a new break element
let new_ele = document.createElement('br');
doc_fragment.appendChild(new_ele);
// Get the current selection, and make sure the content is removed (if any)
let range = window.getSelection().getRangeAt(0);
range.deleteContents();
// See if the selection container has any next siblings
// If not: add another break, otherwise the cursor won't move
if (!hasNextSibling(range.endContainer)) {
let extra_break = document.createElement('br');
doc_fragment.appendChild(extra_break);
}
range.insertNode(doc_fragment);
//create a new range
range = document.createRange();
range.setStartAfter(new_ele);
range.collapse(true);
//make the cursor there
let sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
e.stopPropagation();
e.preventDefault();
return false;
});
// See if the given node has a next sibling.
// Either any element or a non-empty node
function hasNextSibling(node) {
if (node.nextElementSibling) {
return true;
}
while (node.nextSibling) {
node = node.nextSibling;
if (node.length > 0) {
return true;
}
}
return false;
}
これはブラウザー向けのHTML5エディターです。テキストを<p>...</p>
でラップすると、Enterキーを押すたびに<p></p>
を取得できます。また、エディターはこのように動作し、SHIFT + ENTERを押すたびに<br />
が挿入されます。
<div contenteditable="true"><p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor veniam asperiores laudantium repudiandae doloremque sed perferendis obcaecati delectus autem perspiciatis aut excepturi et nesciunt error ad incidunt impedit quia dolores rerum animi provident dolore corporis libero sunt enim. Ad magnam omnis quidem qui voluptas ut minima similique obcaecati doloremque atque!
<br /><br />
Type some stuff, hit ENTER a few times, then press the button.
</p>
</div>
これを確認してください: http://jsfiddle.net/ZQztJ/
これと同じ問題があり、解決策(CHROME、MSIE、FIREFOX)が見つかりました。リンクのコードに従ってください。
$(document).on('click','#myButton',function() {
if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1)
var str = $('#myDiv').html().replace(/<br>/gi,'').replace(/<div>/gi,'<br>').replace(/<\/div>/gi,'');
else if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1)
var str = $('#myDiv').html().replace(/<\/br>/gi,'').replace(/<br>/gi,'<br>').replace(/<\/br>/gi,'');
else if (navigator.userAgent.toLowerCase().indexOf("msie") == -1)
var str = $('#myDiv').html().replace(/<br>/gi,'').replace(/<p>/gi,'<br>').replace(/<\/p>/gi,'');
$('#myDiv2').removeClass('invisible').addClass('visible').text(str);
$('#myDiv3').removeClass('invisible').addClass('visible').html(str);
});
別の方法
$('button').click(function(){
$('pre').text($('div')[0].outerHTML)
});
$("#content-edit").keydown(function(e) {
if(e.which == 13) {
$(this).find("div").prepend('<br />').contents().unwrap();
}
});
各Enterキーでコンテンツ編集可能なDivで新しいDivが作成されないようにする:私が見つけた解決策は非常に簡単です:
var newdiv = document.createElement("div");
newdiv.innerHTML = "Your content of div goes here";
myEditablediv.appendChild(newdiv);
この--- innerHTMLコンテンツは、各Enterキーで編集可能なコンテンツDivでの新規Div作成を防ぎます。
ホットキーの処理にMousetrapを使用するのが好きです: https://craig.is/killing/mice
次に、Enterイベントをインターセプトして、コマンドinsertLineBreakを実行します。
Mousetrap.bindGlobal('enter', (e)=>{
window.document.execCommand('insertLineBreak', false, null);
e.preventDefault();
});
すべてのコマンド: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
Chrome 75と次の編集可能な要素を使用して機能します。
<pre contenteditable="true"></pre>
insertHTMLを使用することもできます:
window.document.execCommand('insertHTML', false, "\n");