Bagaimana cara mendeteksi "shift + enter" dan menghasilkan baris baru di Textarea?

145

Saat ini, jika orang tersebut menekan enterdi dalam area teks, formulir akan dikirimkan.
Bagus, aku mau itu.

Tetapi ketika mereka mengetik shift+ enter, saya ingin textarea pindah ke baris berikutnya:\n

Bagaimana saya bisa melakukannya di JQueryJavaScript biasa atau sesederhana mungkin?

TIMEX
sumber
3
Oh, betapa aku membenci perilaku yang berubah seperti itu ... ^^ Mengapa kamu melakukan itu? Jika Anda menulis huruf dalam kata, apakah Anda mengharapkannya untuk menyimpan teks dalam file ketika menekan enter atau haruskah memulai baris baru?
Andreas
18
Saya sedang membangun ruang obrolan. Begitulah cara Skype duduk.
TIMEX
10
Periksa e.shiftKey.
Thailand
6
Yang perlu Anda lakukan adalah menemukan kode yang mencegah Enter dari mengirimkan formulir dan memeriksa shiftKeyproperti acara .
Tim Down
3
Shift ENTER untuk baris baru di bidang teks bukan perilaku "berubah". Sudah perilaku yang diharapkan selama bertahun-tahun keledai, untuk segala macam hal. Saya menggunakannya beberapa dekade yang lalu ketika memasukkan teks dalam spreadsheet.
Bersantai Di Siprus

Jawaban:

81

Lebih baik gunakan solusi yang lebih sederhana:

Solusi Tim di bawah ini lebih baik saya sarankan menggunakan itu: https://stackoverflow.com/a/6015906/4031815


Solusi saya

Saya pikir Anda dapat melakukan sesuatu seperti ini ..

EDIT: Mengubah kode untuk bekerja terlepas dari posisi caret

Bagian pertama dari kode adalah untuk mendapatkan posisi tanda sisipan.

Ref: Bagaimana cara mendapatkan posisi kolom caret (bukan piksel) di textarea, dalam karakter, dari awal?

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; 
}

Dan kemudian mengganti nilai textarea yang sesuai saat Shift+ Enterbersama, kirimkan formulir jika Enterditekan sendirian.

$('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();
        }
    }
});

Ini demo

Jishnu AP
sumber
Itu tidak akan berhasil jika tanda sisipan tidak ada di akhir konten textarea.
Tim Down
Juga, ada kesalahan ketik (Anda maksud event.keyCode == 13) dan saya pikir Anda mungkin juga ingin event.preventDefault()bukan event.stopPropagation().
Tim Down
Saya mengubahnya. Sekarang akan berfungsi terlepas dari posisi caret. Dan event.stopPropagation()saya bermaksud menghentikan beberapa kode lain yang mungkin telah ditulisnya untuk menyerahkan formulir.
Jishnu AP
7
Fungsi posisi caret itu cacat (lihat komentar dan jawaban saya pada pertanyaan posisi caret terkait), dan Anda tetap tidak memerlukan posisi caret untuk melakukan ini. Lihat jawaban saya di sini. Re event.stopPropagation(), itu akan mencegah acara dari menggelembung lebih jauh DOM tetapi tidak akan mencegah penekanan tombol dari melakukan tindakan standarnya memasukkan garis istirahat (meskipun sebenarnya dalam keyupsaran saya event.preventDefault()tidak akan melakukannya juga).
Tim Down
2
Meskipun bekerja dengan baik, tapi itu memberikan kesalahan yang carenttidak didefinisikan, jika saya mengubahnya ke tanda sisipan menambahkan 2 baris baru
Aamir Mahmood
164

Solusi mudah & elegan:

Pertama, menekan Enterdi dalam textarea tidak mengirimkan formulir kecuali Anda memiliki skrip untuk membuatnya melakukannya. Itulah perilaku yang diharapkan pengguna dan saya sarankan untuk tidak mengubahnya. Namun, jika Anda harus melakukan ini, pendekatan termudah adalah dengan menemukan skrip yang membuat Entermengirimkan formulir dan mengubahnya. Kode akan memiliki sesuatu seperti

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

... dan Anda bisa mengubahnya menjadi

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

Di sisi lain, jika Anda tidak memiliki akses ke kode ini karena alasan tertentu, Anda perlu melakukan yang berikut untuk membuatnya berfungsi di semua browser utama bahkan jika tanda sisipan tidak ada di akhir teks:

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

Kode:

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);
Tim Down
sumber
42

Sebagian besar jawaban ini terlalu rumit. Mengapa tidak mencobanya dengan cara ini?

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

Tidak main-main dengan posisi tanda sisipan atau mendorong line break ke JS. Pada dasarnya, fungsi tidak akan berjalan jika tombol shift ditekan, sehingga memungkinkan tombol enter / return untuk melakukan fungsi normalnya.

Matt Goodwin
sumber
Inilah yang saya inginkan. Terima kasih.
Taku Yoshi
18

Kenapa tidak adil?

$(".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
    }
});
Liam Hall
sumber
2
Anda cukup menggunakan satu kondisi seperti (event.keyCode == 13 &&! Event.shiftKey). Hanya sebuah tip: jika Anda menggunakan knockoutjs, Anda perlu membatalkan fokus kepalan teks untuk memperbarui nilai: jQuery (this) .blur ();
Justin
4

Gunakan plugin hotkey jQuery dan kode ini

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

Berikut ini adalah solusi AngularJS menggunakan ng-keyup jika ada yang memiliki masalah yang sama menggunakan AngularJS.

ng-keyup="$event.keyCode == 13 && !$event.shiftKey && myFunc()"
Tombery
sumber
3

Menggunakan ReactJS ES6 di sini adalah cara paling sederhana

shift+ enterBaris Baru di posisi mana pun

enter Dicekal

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>

Shrroy
sumber
2

Saya menemukan utas ini mencari cara untuk mengontrol Shift + tombol apa saja. Saya menempelkan solusi lain untuk membuat fungsi gabungan ini untuk mencapai apa yang saya butuhkan. Saya harap ini membantu orang lain.

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));
    });
});
Spencer Sullivan
sumber
1

Dalam kasus seseorang masih bertanya-tanya bagaimana melakukan ini tanpa jQuery.

HTML

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

Javascript

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

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

Vanilla JS

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

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

Saya menggunakan div dengan menambahkan contenteditable true daripada menggunakan textarea.

Semoga bisa membantu Anda.

$("#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
    }
  }
})
Hsinhsin Hung
sumber
1

Ini bekerja untuk saya!

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

          $('form').submit();

    }
});
Mȍhǟmmǟd Șamȋm
sumber
0

menggunakan ng-keyupdirektif dalam angularJS, hanya mengirim pesan dengan menekan Entertombol dan Shift+Enterhanya akan mengambil baris baru.

ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
Abdallah Okasha
sumber