Làm cách nào để lấy văn bản của hộp văn bản đầu vào trong onKeyPress?


85

Tôi đang cố lấy văn bản trong một hộp văn bản khi người dùng nhập vào đó ( jsfiddle sân chơi ):

function edValueKeyPress() {
    var edValue = document.getElementById("edValue");
    var s = edValue.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: " + s;

    //var s = $("#edValue").val();
    //$("#lblValue").text(s);    
}
<input id="edValue" type="text" onKeyPress="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>

Mã chạy mà không có lỗi, ngoại trừ giá trị của input texthộp, trong suốt onKeyPressluôn là giá trị trước khi thay đổi:

nhập mô tả hình ảnh ở đây

Câu hỏi : Làm cách nào để lấy nội dung của hộp văn bản trong khi onKeyPress?

Bonus Chatter

Có ba sự kiện liên quan đến "người dùng đang nhập" trong HTML DOM:

  • onKeyDown
  • onKeyPress
  • onKeyUp

Trong Windows , thứ tự của WM_Keythông báo trở nên quan trọng khi người dùng nhấn giữ một phím và phím đó bắt đầu lặp lại:

  • WM_KEYDOWN('a') - người dùng đã đẩy xuống A chìa khóa
  • WM_CHAR('a') - một a ký tự đã được nhận từ người dùng
  • WM_CHAR('a') - một a ký tự đã được nhận từ người dùng
  • WM_CHAR('a') - một a ký tự đã được nhận từ người dùng
  • WM_CHAR('a') - một a ký tự đã được nhận từ người dùng
  • WM_CHAR('a') - một a ký tự đã được nhận từ người dùng
  • WM_KEYUP('a') - người dùng đã phát hành A khóa

Sẽ dẫn đến năm ký tự xuất hiện trong một điều khiển văn bản: aaaaa

Điểm quan trọng là bạn phản hồi WM_CHAR tin nhắn, tin nhắn lặp lại. Nếu không, bạn sẽ bỏ lỡ các sự kiện khi nhấn một phím.

Trong HTML, mọi thứ hơi khác một chút:

  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyUp

Html cung cấp KeyDownKeyPressmọi lần lặp lại phím. VàKeyUp sự kiện chỉ được nâng lên khi người dùng nhả khóa.

Đi xa

  • Tôi có thể trả lời onKeyDownhoặc onKeyPress, nhưng cả hai vẫn được nâng lên trước khi input.valueđược cập nhật
  • Tôi không thể trả lời onKeyUpvì nó không xảy ra khi văn bản trong hộp văn bản thay đổi.

Câu hỏi: Làm cách nào để lấy văn bản của hộp văn bản trong khi onKeyPress?

Đọc thêm


1
Tôi tin rằng bạn cần thêm lần nhấn phím hiện tại vào giá trị trước khi trả lại; giá trị được cập nhật trên keyUp, nhưng dữ liệu có sẵn cho bạn trên keyDown.
Mathletics

Chìa khóa công trình lên cho tôi, bạn không cần phải JQ cho một cái gì đó như thế này, trừ khi bạn muốn thêm sưng lên
Ryan B

nó là đủ chỉ onKeyUp cho nhiệm vụ của bạn
Dmytro

@mit Chỉ xử lý onKeyUpkhông hiển thị các thay đổi trong hộp văn bản khi chúng xảy ra.
Ian Boyd

Nếu bạn muốn giữ bất kỳ phím nào và nhận kết quả trong hộp văn bản, do đó, bạn nên sử dụng cả sự kiện onKeyPress và onKeyDown fiddle của Jonathan M , nhưng nếu bạn muốn nhận kết quả mà không cần giữ phím thì chỉ cần onKeyUp my fiddle là đủ .
dmytro

Câu trả lời:


19

Xử lý các inputsự kiện là một giải pháp phù hợp: nó được hỗ trợ cho textareainputcác yếu tố trong tất cả các trình duyệt hiện đại và nó cháy chính xác khi bạn cần:

function edValueKeyPress() {
    var edValue = document.getElementById("edValue");
    var s = edValue.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: " + s;
}
<input id="edValue" type="text" onInput="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>

Tuy nhiên, tôi sẽ viết lại điều này một chút:

function showCurrentValue(event)
{
    const value = event.target.value;
    document.getElementById("lblValue").innerText = value;
}
<input id="edValue" type="text" onInput="showCurrentValue(event)"><br>
The text box contains: <span id="lblValue"></span>


54

Giữ nó đơn giản. Sử dụng cả hai onKeyPress()onKeyUp():

<input id="edValue" type="text" onKeyPress="edValueKeyPress()" onKeyUp="edValueKeyPress()">

Điều này sẽ giúp bạn nhận được giá trị chuỗi được cập nhật mới nhất (sau khi khóa) và cũng cập nhật nếu người dùng nhấn giữ một phím.

jsfiddle: http://jsfiddle.net/VDd6C/8/


Vì câu trả lời của arnaud576875 phải từ bỏ và dự phòng onKeyUp(đánh bại mục đích sử dụng onKeypress) nên đây là câu trả lời đơn giản nhất, rõ ràng nhất và gần nhất mà bất kỳ ai sẽ thấy. Chỉ người dùng tinh ý nhất mới nhận thấy phản hồi không khớp với những gì họ đã nhập.
Ian Boyd

@Ian, rất vui được giúp đỡ. Ý bạn là gì khi "phản hồi không khớp với những gì họ đã nhập"? Có cần điều chỉnh không?
Jonathan M

tôi nhớ ý tôi bây giờ! Phản hồi mà tôi đang đề cập sẽ là tô màu <input>phần tử là màu đỏ hoặc xanh lá cây hoặc đưa ra một số phản hồi khác cho người dùng rằng những gì họ đã nhập là tốt hay xấu. Mặc dù câu trả lời được chấp nhận của bạn vẫn gặp phải vấn đề là luôn luôn có ký tự "khác biệt " : chỉ người dùng tinh ý nhất mới nhận thấy phản hồi không khớp với những gì họ đã nhập. " Trong thực tế, kể từ khi- một lỗi chỉ xảy ra trong chính-repeat (tức là họ đang giữ phím) ai (ngoài tôi) sẽ chú ý đến vấn đề.
Ian Boyd

19

giá trị của hộp văn bản đầu vào, trong onKeyPress luôn là giá trị trước khi thay đổi

Đây là mục đích: Điều này cho phép người nghe sự kiện hủy việc nhấn phím.

Nếu người nghe sự kiện hủy sự kiện , giá trị không được cập nhật. Nếu sự kiện không bị hủy, giá trị sẽ được cập nhật, nhưng sau khi trình xử lý sự kiện được gọi .

Để nhận giá trị sau khi giá trị trường đã được cập nhật, hãy lên lịch một hàm để chạy trong vòng lặp sự kiện tiếp theo. Cách thông thường để làm điều này là gọi setTimeoutvới thời gian chờ là 0:

$('#field').keyup(function() {
    var $field = $(this);

    // this is the value before the keypress
    var beforeVal = $field.val();

    setTimeout(function() {

        // this is the value after the keypress
        var afterVal = $field.val();
    }, 0);
});

Hãy thử tại đây: http://jsfiddle.net/Q57gY/2/

Chỉnh sửa : Một số trình duyệt (ví dụ: Chrome) không kích hoạt các sự kiện nhấn phím cho phím xóa lùi; đã thay đổi thao tác nhấn phím thành tổ hợp phím trong mã.


Đã về để đăng điều này. Đây là jsFiddle tôi đã làm.
kapa

Bạn nói đúng, Chrome dường như không kích hoạt các sự kiện nhấn phím cho backspace; cập nhật
Arnaud Le Blanc

@Ian, OP có muốn nó cập nhật như một khóa được giữ không? Không quá chắc chắn nếu đây là một yêu cầu. Tuy nhiên, giải pháp này không có chức năng đó.
Jonathan M

Nói rõ hơn: Không kích hoạt các sự kiện nhấn phím cho phím xóa lùi là theo Tiêu chuẩn: "phím tạo ra giá trị ký tự" - đối với các phím khác, hãy sử dụng "keydown" (trước khi thay đổi, có thể hủy bỏ) hoặc "keyup" (sau khi thay đổi)
sebilasse

5

giữ cho nó nhỏ gọn.
Mỗi lần bạn nhấn một phím, chức năng edValueKeyPress()sẽ được gọi.
Bạn cũng đã khai báo và khởi tạo một số biến trong hàm đó - điều này làm chậm quá trình và yêu cầu nhiều CPU và bộ nhớ hơn.
Bạn chỉ có thể sử dụng mã này - bắt nguồn từ sự thay thế đơn giản.

function edValueKeyPress()
{
    document.getElementById("lblValue").innerText =""+document.getElementById("edValue").value;
}

Đó là tất cả những gì bạn muốn và nó nhanh hơn!


3
<asp:TextBox ID="txtMobile" runat="server" CssClass="form-control" style="width:92%;  margin:0px 5px 0px 5px;" onkeypress="javascript:return isNumberKey(event);" MaxLength="12"></asp:TextBox>

<script>
    function isNumberKey(evt) {
        var charCode = (evt.which) ? evt.which : event.keyCode;
        if (charCode > 31 && (charCode < 48 || charCode > 57)) {
            return false;
        }
        return true;
    }
</script>

3

Không có câu trả lời nào cho đến nay cung cấp một giải pháp hoàn chỉnh. Có một số vấn đề cần giải quyết:

  1. Không phải tất cả các lần nhấn phím đều được chuyển sang keydownkeypress trình xử lý (ví dụ: phím xóa lùi và xóa bị chặn bởi một số trình duyệt).
  2. Sự điều khiển keydown không phải là một ý kiến ​​hay. Có những trường hợp nhấn phím KHÔNG dẫn đến việc nhấn phím!
  3. setTimeout() các giải pháp phong cách bị trì hoãn trong trình duyệt web Google Chrome / Blink cho đến khi người dùng ngừng nhập.
  4. Các sự kiện chuột và chạm có thể được sử dụng để thực hiện các hành động như cắt, sao chép và dán. Những sự kiện đó sẽ không kích hoạt các sự kiện bàn phím.
  5. Trình duyệt, tùy thuộc vào phương thức nhập, có thể không gửi thông báo rằng phần tử đã thay đổi cho đến khi người dùng điều hướng khỏi trường.

Một giải pháp chính xác hơn sẽ xử lý keypress, keyup, input, vàchange các sự kiện.

Thí dụ:

<p><input id="editvalue" type="text"></p>
<p>The text box contains: <span id="labelvalue"></span></p>

<script>
function UpdateDisplay()
{
    var inputelem = document.getElementById("editvalue");
    var s = inputelem.value;

    var labelelem = document.getElementById("labelvalue");
    labelelem.innerText = s;
}

// Initial update.
UpdateDisplay();

// Register event handlers.
var inputelem = document.getElementById("editvalue");
inputelem.addEventListener('keypress', UpdateDisplay);
inputelem.addEventListener('keyup', UpdateDisplay);
inputelem.addEventListener('input', UpdateDisplay);
inputelem.addEventListener('change', UpdateDisplay);
</script>

Vĩ cầm:

http://jsfiddle.net/VDd6C/2175/

Xử lý tất cả bốn sự kiện bắt tất cả các trường hợp cạnh. Khi làm việc với đầu vào từ người dùng, tất cả các loại phương thức nhập phải được xem xét và phải xác minh chức năng trên nhiều trình duyệt và thiết bị chéo. Đoạn mã trên đã được thử nghiệm trong Firefox, Edge và Chrome trên máy tính để bàn cũng như các thiết bị di động mà tôi sở hữu.


Tại sao không chỉ là inputsự kiện?
YakovL

inputkhông phải lúc nào cũng cháy. Không có sự kiện nào bao gồm tất cả các tình huống.
CubicleSoft

sẽ được tốt đẹp của bạn nếu bạn mô tả "không phải lúc nào" một cách chi tiết hơn, như bạn đã chỉ cho keypresstrong câu trả lời
YakovL

1

Tôi thường nối giá trị của trường (tức là trước khi nó được cập nhật) với khóa được liên kết với sự kiện khóa. Phần sau sử dụng JS gần đây nên sẽ cần điều chỉnh để hỗ trợ trong IE cũ hơn.

Ví dụ JS gần đây

document.querySelector('#test').addEventListener('keypress', function(evt) {
    var real_val = this.value + String.fromCharCode(evt.which);
    if (evt.which == 8) real_val = real_val.substr(0, real_val.length - 2);
    alert(real_val);
}, false);

Ví dụ về hỗ trợ cho IEs cũ hơn

//get field
var field = document.getElementById('test');

//bind, somehow
if (window.addEventListener)
    field.addEventListener('keypress', keypress_cb, false);
else
    field.attachEvent('onkeypress', keypress_cb);

//callback
function keypress_cb(evt) {
    evt = evt || window.event;
    var code = evt.which || evt.keyCode,
        real_val = this.value + String.fromCharCode(code);
    if (code == 8) real_val = real_val.substr(0, real_val.length - 2);
}

[EDIT - cách tiếp cận này, theo mặc định, vô hiệu hóa các thao tác nhấn phím đối với những thứ như dấu cách lùi, CTRL + A. Đoạn mã trên phù hợp với cái trước, nhưng sẽ cần mày mò thêm để cho phép cái sau và một vài trường hợp cuối cùng khác. Xem bình luận của Ian Boyd bên dưới.]


1
@ bažmegakapa Hoặc bằng deletephím, hoặc nếu người dùng nhấn một phím không sửa đổi nội dung ( Ctrl+A), hoặc nếu người dùng chọn một số văn bản rồi nhấn ađể thay thế một tập hợp con. Đó là một ý kiến ​​hay, Utkanos, nhưng là một ý tưởng dễ vỡ.
Ian Boyd

1
Đã đồng ý. Tôi sẽ để nó lên vì có một số dặm trong đó, nhưng, như bạn nói, bạn phải tích lũy các khoản phụ cấp cho những cảnh báo này.
Mitya

1

dễ dàng...

Trong trình xử lý sự kiện keyPress của bạn, hãy viết

void ValidateKeyPressHandler(object sender, KeyPressEventArgs e)
{
    var tb = sender as TextBox;
    var startPos = tb.SelectionStart;
    var selLen= tb.SelectionLength;

    var afterEditValue = tb.Text.Remove(startPos, selLen)
                .Insert(startPos, e.KeyChar.ToString()); 
    //  ... more here
}

Điều gì xảy ra nếu e.KeyCharBackspacechìa khóa? Hay Deletechìa khóa? Hay Ctrl+A?
Ian Boyd

Đây có phải là JavaScript không? void? object? phương pháp viết hoa đầu tiên?
YakovL

1

Vì vậy, có những lợi thế và bất lợi cho mỗi sự kiện. Các sự kiện onkeypressonkeydownkhông truy xuất giá trị mới nhất và onkeypresskhông kích hoạt đối với các ký tự không in được trong một số trình duyệt. Cáconkeyup kiện không phát hiện khi một phím được giữ cho nhiều ký tự.

Đây là một chút hacky, nhưng làm một cái gì đó như

function edValueKeyDown(input) {
    var s = input.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: "+s;

    //var s = $("#edValue").val();
    //$("#lblValue").text(s);    
}
<input id="edValue" type="text" onkeydown="setTimeout(edValueKeyDown, 0, this)" />

dường như xử lý tốt nhất của tất cả các thế giới.


1

Bằng cách sử dụng event.key, chúng ta có thể nhận các giá trị trước khi nhập vào Hộp văn bản nhập HTML. Đây là mã.

function checkText()
{
  console.log("Value Entered which was prevented was - " + event.key);
  
  //Following will prevent displaying value on textbox
  //You need to use your validation functions here and return value true or false.
  return false;
}
<input type="text" placeholder="Enter Value" onkeypress="return checkText()" />


Đây sụp đổ khi văn bản được thay đổi thông qua một cái gì đó là không một phím nhấn (cắt, dán, xóa chọn, vv)
Ian Boyd

@IanBoyd vâng đồng ý. Để giữ cho ví dụ đơn giản, tôi đã triển khai chỉ xác thực khi nhấn phím.
vibs2006

0

Cố gắng nối mã charCode sự kiện với giá trị bạn nhận được. Đây là một mẫu mã của tôi:

<input type="text" name="price" onkeypress="return (cnum(event,this))" maxlength="10">
<p id="demo"></p>

js:

function cnum(event, str) {
    var a = event.charCode;
    var ab = str.value + String.fromCharCode(a);
    document.getElementById('demo').innerHTML = ab;
}

Giá trị trong absẽ nhận giá trị mới nhất trong trường đầu vào.


Xin lỗi, tôi nhận thấy một bài đăng khác với cách tiếp cận tốt hơn trong trang này sau khi tôi đăng bài này. Tôi đã không thấy điều đó trước khi đăng. Nhưng tôi nghĩ rằng khái niệm của tôi dễ hiểu hơn.
Rama Krishna,

Đó sụp đổ khá nhanh khi quan trọng là xóa , xóa lùi , Ctrl + X hoặc tổ hợp phím Ctrl + V , hoặc khi chuột chọn tất cả các văn bản và tôi bấm Space
Ian Boyd

Tôi chỉ viết ý tưởng của tôi. bạn có thể thực hiện nó theo yêu cầu của bạn bằng cách sử dụng mã khóa hoặc các phương pháp khác. Đây chỉ là ý tưởng của tôi.
Rama Krishna,

1
Ý tưởng không phải là câu trả lời. Các câu trả lời trên SO phải là các giải pháp ngắn gọn trả lời dứt điểm câu hỏi của OP để mọi người đều có lợi. Điều này rõ ràng không đáp ứng tiêu chí đó.
CubicleSoft

0

Có một cách tốt hơn để làm điều này. Sử dụng Phương pháp concat. Thí dụ

khai báo một biến toàn cục. điều này hoạt động tốt trên góc 10, chỉ cần chuyển nó sang Vanilla JavaScript. Thí dụ:

HTML

<input id="edValue" type="text" onKeyPress="edValueKeyPress($event)"><br>
<span id="lblValue">The text box contains: </span>

emptyString = ''

edValueKeyPress ($event){
   this.emptyString = this.emptyString.concat($event.key);
   console.log(this.emptyString);
}

Và khi quan trọng là Delete, Ctrl+ X, Ctrl+ V, Backspace? Hoặc nếu họ đã chọn một số văn bản, và sau đó nhấn A?
Ian Boyd
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.