「Shift + Enter」を検出してTextareaに新しい行を生成するにはどうすればよいですか?


145

現在、ユーザーがenterテキスト領域内を押すと、フォームが送信されます。
いいですね。

しかし、彼らがshift+ をタイプしたときenter、私はtextareaを次の行に移動させたい:\n

これをJQueryプレーンJavaScriptでできるだけ簡単に行うにはどうすればよいですか?


3
ああ、私はそのような変化した行動をどのように嫌うのですか... ^^なぜあなたはそうするのですか?単語で文字を書く場合、Enterキーを押したときにテキストがファイルに保存されると思いますか、それとも新しい行を開始する必要がありますか?
Andreas

18
チャットルームを構築しています。Skypeはこのように座っています。
TIMEX、

10
を確認しe.shiftKeyます。
タイの

6
Enterがフォームを送信しないようにするコードを見つけ、イベントのshiftKeyプロパティを確認するだけです。
Tim Down、

3
テキストフィールドの新しい行のShift Enterキーは「変更」されません。それは、ロバの何年にもわたってあらゆる種類の行動に期待されてきました。数十年前にスプレッドシートにテキストを入力するときに使用しました。
キプロスでリラックス2016年

回答:


81

よりシンプルなソリューションを使用する方が良い:

以下のティムの解決策は私がそれを使用することをお勧めしますhttps : //stackoverflow.com/a/6015906/4031815


私の解決策

こんなことができると思います。

編集:キャレット位置に関係なく機能するようにコードを変更しました

コードの最初の部分は、キャレットの位置を取得することです。

参考:テキスト領域のキャレット列(ピクセルではない)の位置を文字で取得するにはどうすればよいですか?

function getCaret(el) { 
    if (el.selectionStart) { 
        return el.selectionStart; 
    } else if (document.selection) { 
        el.focus();
        var r = document.selection.createRange(); 
        if (r == null) { 
            return 0;
        }
        var re = el.createTextRange(), rc = re.duplicate();
        re.moveToBookmark(r.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
    }  
    return 0; 
}

そして、Shift+がEnter一緒の場合、それに応じてtextarea値を置き換え、Enterが単独で押された場合にフォームを送信します。

$('textarea').keyup(function (event) {
    if (event.keyCode == 13) {
        var content = this.value;  
        var caret = getCaret(this);          
        if(event.shiftKey){
            this.value = content.substring(0, caret - 1) + "\n" + content.substring(caret, content.length);
            event.stopPropagation();
        } else {
            this.value = content.substring(0, caret - 1) + content.substring(caret, content.length);
            $('form').submit();
        }
    }
});

ここにデモがあります


キャレットがtextareaのコンテンツの最後にない場合、これは機能しません。
Tim Down、

また、タイプミス(つまりevent.keyCode == 13)があり、おそらくではevent.preventDefault()なく、あなたも欲しかったと思いますevent.stopPropagation()
Tim Down、

私はそれを変えた。これで、キャレットの位置に関係なく機能します。そして、event.stopPropagation()私はフォームを送信するために彼が書いたかもしれない他のいくつかのコードを停止するつもりでした。
Jishnu AP、

7
そのキャレット位置関数には欠陥があり(リンクされたキャレット位置の質問についての私のコメントと回答を参照)、とにかくこれを行うためにキャレット位置は必要ありません。ここで私の答えを参照してください。Re event.stopPropagation()を使用すると、イベントがDOMの上方に移動するのを防ぐことができますが、キープレスが改行を挿入するデフォルトのアクションを実行するのを防ぐことはできません(ただし、keyup私の提案でevent.preventDefault()は実際にはそうしません)。
Tim Down、

2
正常に動作しましたが、carent定義されていないエラーが発生しましたが、キャレットに変更すると、2つの新しい行が追加されます
Aamir Mahmood 2012

164

簡単でエレガントなソリューション:

まず、Entertextarea内を押しても、それを実行するためのスクリプトがない限り、フォームは送信されません。これはユーザーが期待する動作であり、変更しないことをお勧めします。ただし、これを行う必要がある場合、最も簡単な方法はEnter、フォームを送信しているスクリプトを見つけて変更することです。コードは次のようなものになります

if (evt.keyCode == 13) {
    form.submit();
}

...そしてそれを次のように変更することができます

if (evt.keyCode == 13 && !evt.shiftKey) {
    form.submit();
}

一方、何らかの理由でこのコードにアクセスできない場合は、キャレットがテキストの最後にない場合でも、すべての主要ブラウザで機能するように次の操作を行う必要があります。

jsFiddle:http ://jsfiddle.net/zd3gA/1/

コード:

function pasteIntoInput(el, text) {
    el.focus();
    if (typeof el.selectionStart == "number"
            && typeof el.selectionEnd == "number") {
        var val = el.value;
        var selStart = el.selectionStart;
        el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
        el.selectionEnd = el.selectionStart = selStart + text.length;
    } else if (typeof document.selection != "undefined") {
        var textRange = document.selection.createRange();
        textRange.text = text;
        textRange.collapse(false);
        textRange.select();
    }
}

function handleEnter(evt) {
    if (evt.keyCode == 13 && evt.shiftKey) {
        if (evt.type == "keypress") {
            pasteIntoInput(this, "\n");
        }
        evt.preventDefault();
    }
}

// Handle both keydown and keypress for Opera, which only allows default
// key action to be suppressed in keypress
$("#your_textarea_id").keydown(handleEnter).keypress(handleEnter);

42

これらの回答のほとんどは、これを複雑にしています。このようにしてみませんか?

$("textarea").keypress(function(event) {
        if (event.keyCode == 13 && !event.shiftKey) {
         submitForm(); //Submit your form here
         return false;
         }
});

キャレットの位置をいじったり、JSに改行を押し込んだりする必要はありません。基本的に、Shiftキーが押されている場合、関数は実行されないため、Enter / Returnキーで通常の機能を実行できます。


これはまさに私が欲しかったものです。ありがとう。
タクヨシ

18

なぜか

$(".commentArea").keypress(function(e) {
    var textVal = $(this).val();
    if(e.which == 13 && e.shiftKey) {

    }
    else if (e.which == 13) {
       e.preventDefault(); //Stops enter from creating a new line
       this.form.submit(); //or ajax submit
    }
});

2
(event.keyCode == 13 &&!event.shiftKey)のような1つの条件のみを使用できます。ヒント:nockoutjsを使用する場合は、textarea fistのフォーカスを外して値を更新する必要があります。jQuery(this).blur();
ジャスティン

4

jQuery hotkeysプラグインとこ​​のコードを使用する

jQuery(document).bind('keydown', 'shift+enter', 
         function (evt){ 
             $('textarea').val($('#textarea').val() + "\n");// use the right id here
             return true;
         }
);


3

ReactJS ES6を使用するのが最も簡単な方法です

shift + enter任意の位置に改行

enter ブロックされました

class App extends React.Component {

 constructor(){
    super();
    this.state = {
      message: 'Enter is blocked'
    }
  }
  onKeyPress = (e) => {
     if (e.keyCode === 13 && e.shiftKey) {
        e.preventDefault();
        let start = e.target.selectionStart,
            end = e.target.selectionEnd;
        this.setState(prevState => ({ message:
            prevState.message.substring(0, start)
            + '\n' +
            prevState.message.substring(end)
        }),()=>{
            this.input.selectionStart = this.input.selectionEnd = start + 1;
        })
    }else if (e.keyCode === 13) { // block enter
      e.preventDefault();
    }
    
  };

  render(){
    return(
      <div>
      New line with shift enter at any position<br />
       <textarea 
       value={this.state.message}
       ref={(input)=> this.input = input}
       onChange={(e)=>this.setState({ message: e.target.value })}
       onKeyDown={this.onKeyPress}/>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='root'></div>


2

このスレッドは、Shift +任意のキーを制御する方法を探していました。他のソリューションを貼り付けて、この複合機能を実現し、必要なものを実現しました。それが他の誰かの役に立つことを願っています。

function () {
    return this.each(function () {
    $(this).keydown(function (e) {
        var key = e.charCode || e.keyCode || 0;
        // Shift + anything is not desired
        if (e.shiftKey) {
            return false;
        }
        // allow backspace, tab, delete, enter, arrows, numbers 
        //and keypad numbers ONLY
        // home, end, period, and numpad decimal
        return (
            key == 8 ||
            key == 9 ||
            key == 13 ||
            key == 46 ||
            key == 110 ||
            key == 190 ||
            (key >= 35 && key <= 40) ||
            (key >= 48 && key <= 57) ||
            (key >= 96 && key <= 105));
    });
});

1

誰かがjQueryなしでこれを行う方法をまだ疑問に思っている場合に備えて。

HTML

<textarea id="description"></textarea>

JavaScript

const textarea = document.getElementById('description');

textarea.addEventListener('keypress', (e) => {
    e.keyCode === 13 && !e.shiftKey && e.preventDefault(); 
})

バニラJS

var textarea = document.getElementById('description');

textarea.addEventListener('keypress', function(e) {
    if(e.keyCode === 13 && !e.shiftKey) {
      e.preventDefault();
    }
})

1

textareaの代わりにcontenteditable trueを追加してdivを使用しています。

希望があなたを助けることができます。

$("#your_textarea").on('keydown', function(e){//textarea keydown events
  if(e.key == "Enter")
  {
    if(e.shiftKey)//jump new line
    {
     // do nothing
    }
    else  // do sth,like send message or else
    {
       e.preventDefault();//cancell the deafult events
    }
  }
})

1

これは私にとってはうまくいきます!

$("#your_textarea").on('keydown', function(e){
    if(e.keyCode === 13 && !e.shiftKey) 
    {

          $('form').submit();

    }
});

0

使用ng-keyupangularJSにディレクティブを、唯一の押しにメッセージを送信するEnterキーをし、Shift+Enterちょうど新しい行がかかります。

ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.