ฉันจะตรวจจับ“ shift + enter” และสร้างบรรทัดใหม่ใน Textarea ได้อย่างไร


145

ปัจจุบันถ้าบุคคลกดenterภายในพื้นที่ข้อความแบบฟอร์มจะส่ง
ดีฉันต้องการมัน

แต่เมื่อพวกเขาพิมพ์shift+ enterฉันต้องการให้ textarea ย้ายไปที่บรรทัดถัดไป:\n

ฉันจะทำเช่นนั้นในJQueryหรือธรรมดา JavaScript ง่ายที่สุด?


3
โอ้ฉันเกลียดพฤติกรรมที่เปลี่ยนแปลงเช่นนี้ได้อย่างไร ... ^^ ทำไมคุณถึงทำอย่างนั้น? หากคุณเขียนจดหมายเป็นคำคุณคาดหวังให้บันทึกข้อความไว้ในไฟล์เมื่อกดปุ่ม Enter หรือควรเริ่มบรรทัดใหม่?
Andreas

18
ฉันกำลังสร้างห้องแชท นั่นเป็นวิธีที่ Skype doe นั่ง
TIMEX

10
e.shiftKeyตรวจสอบ
ภาษาไทย

6
สิ่งที่คุณต้องทำคือค้นหารหัสที่ป้องกันไม่ให้ Enter ส่งแบบฟอร์มและตรวจสอบshiftKeyคุณสมบัติของกิจกรรม
Tim Down

3
Shift ENTER สำหรับบรรทัดใหม่ในฟิลด์ข้อความไม่ใช่พฤติกรรม "เปลี่ยน" มันเป็นพฤติกรรมที่คาดหวังมานานหลายปีของลาสำหรับทุกสิ่ง ฉันใช้มันเมื่อหลายสิบปีก่อนเมื่อป้อนข้อความในสเปรดชีต
ผ่อนคลายในไซปรัส

คำตอบ:


81

ใช้โซลูชันที่ง่ายกว่าดีกว่า:

ทางออกของทิมด้านล่างดีกว่าฉันแนะนำให้ใช้: https://stackoverflow.com/a/6015906/4031815


ทางออกของฉัน

ฉันคิดว่าคุณสามารถทำสิ่งนี้ได้ ..

แก้ไข:เปลี่ยนรหัสเพื่อทำงานโดยไม่คำนึงถึงตำแหน่งคาเร็ต

ส่วนแรกของรหัสคือการได้รับตำแหน่งลูกศร

Ref: วิธีการรับตำแหน่งเครื่องหมายรูปหมวก (ไม่ใช่พิกเซล) ใน textarea เป็นตัวอักษรตั้งแต่ต้น?

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

จากนั้นแทนที่ค่า textarea เมื่อShift+ Enterร่วมกันส่งแบบฟอร์มหาก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
ฟังก์ชันตำแหน่งคาเร็ตนั้นมีข้อบกพร่อง (ดูความคิดเห็นและคำตอบของคำถามตำแหน่งคาเร็ตที่เชื่อมโยง) และคุณไม่ต้องการตำแหน่งคาเร็ตเพื่อทำสิ่งนี้ ดูคำตอบของฉันที่นี่ ตอบevent.stopPropagation()ว่าจะป้องกันไม่ให้เหตุการณ์เดือดปุด ๆ ต่อไปใน DOM แต่จะไม่ป้องกันการกดแป้นจากการกระทำเริ่มต้นของการแทรกตัวแบ่งบรรทัด (แม้ว่าจริงๆแล้วในkeyupคำแนะนำของฉันevent.preventDefault()จะไม่ทำเช่นนั้น)
Tim Down

2
แม้ว่ามันจะทำงานได้ดี แต่มันก็มีข้อผิดพลาดที่carentไม่ได้กำหนดไว้หากฉันเปลี่ยนเป็นคาเร็ทจะเพิ่ม 2 บรรทัดใหม่
Aamir Mahmood

164

โซลูชันที่ง่ายและสง่างาม:

ขั้นแรกให้กดEnterภายใน textarea ไม่ได้ส่งแบบฟอร์มเว้นแต่ว่าคุณมีสคริปต์ที่จะทำมัน นั่นเป็นพฤติกรรมที่ผู้ใช้คาดหวังและฉันไม่แนะนำให้เปลี่ยน อย่างไรก็ตามหากคุณต้องทำเช่นนี้วิธีที่ง่ายที่สุดคือการค้นหาสคริปต์ที่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 เพื่อทำหน้าที่ตามปกติ


นี่คือสิ่งที่ฉันต้องการ ขอบคุณ
Taku Yoshi

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) เพียงแค่ปลาย: ถ้าคุณใช้ knockoutjs คุณต้องปลดโฟกัส textarea fist เพื่ออัปเดตค่า: jQuery (this) .blur ();
Justin


3

นี่คือโซลูชัน AngularJS โดยใช้ng-keyupหากใครมีปัญหาเดียวกันกับการใช้ AngularJS

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

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>

จาวาสคริ

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

ฉันใช้ div โดยการเพิ่ม contenteditable true แทนที่จะใช้ textarea

หวังว่าจะช่วยคุณได้

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


0

ใช้ng-keyupdirective ใน angularJS เพียงส่งข้อความเมื่อกดปุ่มEnterและShift+Enterจะขึ้นบรรทัดใหม่

ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.