简体   繁体   中英

Instant Search function is one keystroke behind

I have a type of "translate" program on my website that uses an instant search function. I have a textarea

<textarea name="text" onkeydown="searchq();"></textarea>

which runs the searchq() function

function searchq() {
    var searchTxt = $("textarea[name='text']").val();

    $.post("translate.php", {text: searchTxt}, function(output){
        $("#translated").html(output);
    });
}

which sends each word to the translate.php

if(isset($_POST["text"])){
    $words = explode(' ',$_POST['text']);

    $i = 0;
    foreach($words as $word){
        // performs transformations on the words
        $output = $word . " ";
        echo($output);
        $i++;
    }
}

However, if you try it out on my website http://saaa.me/MattSpeak.html , you can clearly see that if you type in "y", nothing shows up, and only when you type in the next letter or space will the "y" show up. The instant translation process seems to be one character behind. What's causing this? (the Trade Mark signs and "er" word endings are things that I added as part of the "translation")

I have a slight idea of why this isn't working properly but have no clue how to solve it. Help would be greatly appreciated.

The keydown event precedes the character being added (even the keypress event precedes it). If you want to respond to a letter being typed, respond to input or, for older and/or buggy browsers (basically IE9 and earlier ), respond to keypress with a brief setTimeout .

Using input :

 $("textarea").on("input", function() { $("<p>").text($(this).val()).appendTo(document.body); });
 <textarea></textarea> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Using keypress with a setTimeout so the character gets added:

 $("textarea").on("keypress", function() { var $this = $(this); setTimeout(function() { $("<p>").text($this.val()).appendTo(document.body); }, 0); });
 <textarea></textarea> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


I tend to respond to a range of events and use debouncing so I don't respond more than once:

 var lastSearch = null; $("textarea").on("input keyup change", function() { var search = $(this).val(); if (search !== lastSearch) { lastSearch = search; $("<p>").text(search).appendTo(document.body); } });
 <textarea></textarea> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM