“Shift + enter” ı nasıl algılar ve Textarea'da yeni bir satır oluştururum?


145

Şu anda, kişi entermetin alanının içine basarsa , form gönderilir.
Güzel, istiyorum.

Ancak shift+ yazdıklarında enter, metin alanının bir sonraki satıra geçmesini istiyorum:\n

Bunu JQuerymümkün olduğunca basit veya düz JavaScript'te nasıl yapabilirim ?


3
Ah, böyle değişen davranışlardan nasıl nefret ediyorum ... ^^ Neden bunu yapasın ki? Sözcükte bir mektup yazarsanız, enter tuşuna basarken metni bir dosyaya kaydetmesini bekler misiniz yoksa yeni bir satıra mı başlaması gerekir?
Andreas

18
Bir sohbet odası inşa ediyorum. Skype işte böyle oturur.
TIMEX

10
Kontrol edin e.shiftKey.
Tayland

6
Tek yapmanız gereken Enter'ın formu göndermesini engelleyen kodu bulmak ve etkinliğin shiftKeyözelliğini kontrol etmektir .
Tim Down

3
Metin alanındaki yeni bir satır için Shift tuşuna basıldığında "değiştirilmez" davranışı yoktur. Eşek yılları, her türlü şey için davranış beklendi. E-tablolara metin girerken onlarca yıl önce kullandım.
Kıbrıs'ta Dinlenme

Yanıtlar:


81

Daha iyi kullanım daha basit çözüm:

Tim'in aşağıdaki çözümü daha iyidir, bunu kullanmanızı öneririm: https://stackoverflow.com/a/6015906/4031815


Çözümüm

Bence böyle bir şey yapabilirsiniz ..

DÜZENLE : Kod, düzeltme konumu ne olursa olsun çalışacak şekilde değiştirildi

Kodun ilk kısmı, düzeltme konumu elde etmektir.

Ref: Bir metin alanındaki düzeltme sütunu (piksel değil) konumunu karakterlerden başlayarak nasıl alabilirim?

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

Ve sonra Shift+ Enterbirlikte olduğunda textarea değerini uygun şekilde değiştirerek, Entertek başına basıldığında formu gönderin .

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

İşte bir demo


Metin, metin alanının içeriğinin sonunda değilse bu işe yaramaz.
Tim Down

Ayrıca, orada bir yazım hatası (Şunu var event.keyCode == 13) ve ben muhtemelen de istediğini düşünüyorum event.preventDefault()ziyade event.stopPropagation().
Tim Down

Ben değiştirdim. Şimdi, düzeltme konumu ne olursa olsun çalışır. Ve event.stopPropagation()ben, formu göndermek için yazmış olabileceği başka bir kodu durdurmak istedim.
Jishnu AP

7
Bu düzeltme konumu işlevi kusurludur (bağlantılı düzeltme konumu sorusu hakkındaki yorumuma ve cevaba bakın) ve yine de bunu yapmak için düzeltme konumu gerekmez. Cevabımı burada görün. Re event.stopPropagation(), bu olay DOM daha fazla köpürmesini engelleyecek ama keypress bir satır sonu ekleme varsayılan eylemi yapmasını engellemeyecektir (aslında keyupbenim önerim de event.preventDefault()bunu yapmayacağım).
Tim Down

2
Her ne kadar iyi çalıştı, ancak carenttanımlanmamış bir hata verdi , eğer caret için değiştirirseniz 2 yeni satır ekler
Aamir Mahmood

164

Kolay ve Zarif çözüm:

İlk olarak, Enterbunu yapmak için komut dosyanız yoksa, bir metin alanının içine basmak formu göndermez. Kullanıcının beklediği davranış budur ve değiştirilmesini önermem. Ancak, bunu yapmanız gerekiyorsa, en kolay yaklaşım Enterformu gönderen betiği bulmak ve değiştirmek olacaktır. Kod gibi bir şey olacak

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

... ve sadece

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

Öte yandan, herhangi bir nedenden dolayı bu koda erişiminiz yoksa, düzeltme metni metnin sonunda olmasa bile, tüm büyük tarayıcılarda çalışmasını sağlamak için aşağıdakileri yapmanız gerekir:

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

Kod:

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

Bu cevapların çoğu bunu çok karmaşık hale getiriyor. Neden böyle denemiyorsun?

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

Caret pozisyonuyla uğraşmak yok veya shoving hattı JS'ye giriyor. Temel olarak, üst karakter tuşuna basıldığında işlev çalışmaz, bu nedenle enter / return tuşunun normal işlevini yerine getirmesine izin verir.


Bu tam olarak istediğim şeydi. Teşekkürler.
Taku Yoshi

18

Neden sadece

$(".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
Sadece (event.keyCode == 13 &&! Event.shiftKey) gibi bir koşulu kullanabilirsiniz. Sadece bir ipucu: knockoutjs kullanıyorsanız, değeri güncellemek için textarea yumruğunu odaklamalısınız: jQuery (this) .blur ();
Justin

4

Kullanım jQuery kısayol tuşlarını eklentisi ve bu kodu

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

3

AngularJS kullanarak aynı sorunu yaşayan ng-keyup kullanan bir AngularJS çözümü .

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

3

ReactJS ES6'yı kullanmak en kolay yol

shift + enter Herhangi bir pozisyonda Yeni Hat

enter tıkalı

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 + herhangi bir tuşu kontrol etmek için bir yol arayan bu iş parçacığı buldum. İhtiyacım olanı gerçekleştirmek için bu birleşik işlevi yapmak için diğer çözümleri yapıştırdım. Umarım başka birine yardımcı olur.

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

Birisi hala jQuery olmadan bunu nasıl yapacağını merak ediyor.

HTML

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

JavaScript

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

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

Vanilya JS

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

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

1

Div'i textarea kullanmak yerine contenteditable true ekleyerek kullanıyorum.

Umut size yardımcı olabilir.

$("#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

Bu benim için çalışıyor!

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

          $('form').submit();

    }
});

0

ng-keyupaçısalJS içinde yönerge kullanarak , sadece Entertuşa basmak için bir mesaj gönderin ve Shift+Entersadece yeni bir satır alacaktır.

ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.