Làm cách nào để tôi phát hiện dịch chuyển + nhập vào và tạo một dòng mới trong Textarea?


145

Hiện tại, nếu người đó nhấn enterbên trong vùng văn bản, biểu mẫu sẽ được gửi.
Tốt, tôi muốn điều đó.

Nhưng khi họ gõ shift+ enter, tôi muốn textarea chuyển sang dòng tiếp theo:\n

Làm cách nào tôi có thể làm điều đó trong JQueryhoặc JavaScript đơn giản nhất có thể?


3
Ồ, làm thế nào tôi ghét hành vi thay đổi như vậy ... ^^ Tại sao bạn sẽ làm điều đó? Nếu bạn viết một chữ cái bằng chữ, bạn có muốn nó lưu văn bản trong một tệp khi nhấn enter hay nó sẽ bắt đầu một dòng mới?
Andreas

18
Tôi đang xây dựng một phòng chat. Đó là cách Skype doe ngồi.
TIMEX

10
Kiểm tra cho e.shiftKey.
Thái

6
Tất cả những gì bạn cần làm là tìm mã ngăn Enter gửi biểu mẫu và kiểm tra thuộc tính của sự kiện shiftKey.
Tim Down

3
Shift ENTER cho một dòng mới trong trường văn bản không phải là hành vi "thay đổi". Nó đã được dự kiến ​​hành vi trong nhiều năm của con lừa, cho tất cả các loại. Tôi đã sử dụng nó hàng thập kỷ trước khi nhập văn bản trong bảng tính.
Thư giãn tại Síp

Câu trả lời:


81

Sử dụng tốt hơn giải pháp đơn giản hơn:

Giải pháp của Tim dưới đây tốt hơn tôi khuyên bạn nên sử dụng: https://stackoverflow.com/a/6015906/4031815


Giải pháp của tôi

Tôi nghĩ bạn có thể làm một cái gì đó như thế này ..

EDIT: Đã thay đổi mã để làm việc không phân biệt tư thế dấu mũ

Phần đầu tiên của mã là để có được vị trí caret.

Tham khảo: Làm thế nào để có được vị trí cột caret (không phải pixel) trong textarea, tính bằng ký tự, từ đầu?

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

Và sau đó thay thế giá trị textarea tương ứng khi Shift+ Entercùng nhau, gửi biểu mẫu nếu Enterđược nhấn một mình.

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

Đây là một bản demo


Điều đó sẽ không hoạt động nếu dấu mũ không ở cuối nội dung của văn bản.
Tim xuống

Ngoài ra, có một lỗi đánh máy (ý bạn là event.keyCode == 13) và tôi nghĩ có lẽ bạn cũng muốn event.preventDefault()hơn là event.stopPropagation().
Tim Down

Tôi đã thay đổi nó. Bây giờ nó sẽ làm việc bất kể vị trí caret. Và bởi event.stopPropagation()tôi có nghĩa là dừng một số mã khác mà anh ta có thể đã viết để gửi biểu mẫu.
Jishnu AP

7
Chức năng vị trí dấu mũ đó là thiếu sót (xem nhận xét và trả lời của tôi về câu hỏi vị trí dấu mũ được liên kết) và bạn không cần vị trí dấu mũ để làm điều này. Xem câu trả lời của tôi ở đây. Re event.stopPropagation(), điều đó sẽ ngăn sự kiện nổi lên hơn nữa trong DOM nhưng sẽ không ngăn nhấn phím thực hiện hành động mặc định của nó là chèn ngắt dòng (mặc dù thực tế trong keyupđề xuất của tôi event.preventDefault()sẽ không làm điều đó).
Tim Down

2
Mặc dù nó hoạt động tốt, nhưng nó không có lỗi nhưng carentnếu tôi thay đổi nó thành dấu mũ thì nó sẽ thêm 2 dòng mới
Aamir Mahmood

162

Giải pháp dễ dàng và thanh lịch:

Đầu tiên, nhấn Enterbên trong một textarea không gửi biểu mẫu trừ khi bạn có tập lệnh để làm cho nó làm điều đó. Đó là hành vi mà người dùng mong đợi và tôi khuyên bạn không nên thay đổi nó. Tuy nhiên, nếu bạn phải làm điều này, cách tiếp cận đơn giản nhất sẽ là tìm tập lệnh đang thực hiện Entergửi biểu mẫu và thay đổi nó. Mã sẽ có cái gì đó như

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

... và bạn có thể thay đổi nó thành

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

Mặt khác, nếu bạn không có quyền truy cập vào mã này vì một số lý do, bạn cần thực hiện các thao tác sau để làm cho nó hoạt động trong tất cả các trình duyệt chính ngay cả khi dấu mũ không ở cuối văn bản:

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

Mã số:

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

Hầu hết các câu trả lời này quá phức tạp này. Tại sao không thử nó theo cách này?

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

Không có sự lộn xộn với vị trí caret hoặc dòng shoving phá vỡ vào JS. Về cơ bản, chức năng sẽ không chạy nếu nhấn phím shift, do đó cho phép phím enter / return thực hiện chức năng bình thường.


Đây chính xác là những gì tôi muốn. Cảm ơn.
Taku Yoshi

18

Tại sao không chỉ

$(".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
Bạn chỉ có thể sử dụng một điều kiện như (event.keyCode == 13 &&! Event.shiftKey). Chỉ là một mẹo: nếu bạn sử dụng knoutoutjs, bạn cần hủy tập trung vào nắm đấm của textarea để cập nhật giá trị: jQuery (this) .blur ();
Justin

4

Sử dụng plugin jQuery hotkey và mã này

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

3

Đây là một giải pháp AngularJS sử dụng ng-keyup nếu bất cứ ai có cùng một vấn đề sử dụng AngularJS.

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

3

Sử dụng ReactJS ES6 ở đây là cách đơn giản nhất

shift+ enterDòng mới ở bất kỳ vị trí nào

enter Bị chặn

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

Tôi tìm thấy chủ đề này đang tìm cách để kiểm soát Shift + bất kỳ phím nào. Tôi đã dán các giải pháp khác để thực hiện chức năng kết hợp này để thực hiện những gì tôi cần. Tôi hy vọng nó sẽ giúp người khác.

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

Trong trường hợp ai đó vẫn đang tự hỏi làm thế nào để làm điều này mà không cần 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();
    }
})

1

Tôi sử dụng div bằng cách thêm nội dung đúng thay vì sử dụng textarea.

Hy vọng có thể giúp bạn.

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

Điều này làm việc cho tôi!

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

          $('form').submit();

    }
});

0

sử dụng ng-keyupchỉ thị trong angularJS, chỉ gửi tin nhắn khi nhấn Enterphím và Shift+Entersẽ chỉ nhận một dòng mới.

ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.