Функция клавиатуры работает только один раз для первой буквы ввода

1

У меня есть текстовый ввод, где пользователь вводит желаемое имя страницы

<input type='text' id='pageName'  name='PageName' class='form-control pageName'>

Я пытаюсь использовать функцию keyup для запуска Ajax, чтобы проверить, существует ли страница, однако при вводе чего-то вродеindex Ajax отправляет толькоI (первая буква) и больше не работает.

Сценарий:

<script>
  $("#pageName").keyup(function() {
    $.ajax({
      type: "GET",
      async: false,
      url: "CheckPageName.php",
      data: {
        'PageName': jQuery(this).val()
      },
      cache: false,
      success: function(html) {
        $("#NotAllowed").replaceWith(html);
        $('#loader_image').hide();
      }
    });
  });
</script>

Если я добавлюconsole.log(html); Он правильно показывает значения в журнале, но$("#NotAllowed").replaceWith(data); показывает только первую букву или 2 (если я печатаю быстро!)

Что мне не хватает?

  • 2
    async : false может быть здесь виновником, поскольку он блокирует что-либо еще (включая события JS) в браузере, пока выполняется запрос AJAX. Это не обязательно и просто вызывает проблемы. Уберите это и попробуйте еще раз, было бы моим первым предложением.
  • 1
    Где элементы $("#NotAllowed") и $("#loader_image") ? Находится ли <input id="pageName"> внутри элемента #NotAllowed
  • 0
    @SebastianSimon - Нет, за пределами обоих div. Они находятся под входом
  • 0
    @ADyson - Убран async : false но без разницы ...
  • 0
    Вам следует обернуть вашу функцию нажатия клавиш в debounce .
  • 0
    @ Mr.Polywhirl - Может быть, вы могли бы показать мне пример с моим кодом?
  • 1
    Есть какие-либо ошибки / предупреждения в консоли браузера? Что вы видите в сетевом инструменте - всего лишь один экземпляр вызова AJAX, как это видно из вашего описания? Есть ли последующие неудачные или просто ничего? Вы добавили какое-либо ведение журнала консоли, чтобы узнать, сколько раз запускается событие нажатия клавиш? Отладка пока кажется немного тонкой на земле.
  • 0
    Поделитесь, пожалуйста, подробностями - это вообще связано с PHP?
  • 2
    Поскольку я только что скопировал это и могу выполнить, не воспроизводя вашу ошибку, должно быть что-то еще. Вы также можете вставить любой другой код страницы, который может иметь отношение. Какая версия jquery? любые возможные конфликтующие библиотеки, которые вы также включаете?
  • 0
    @ADyson - Ошибок в консоли нет. Я вижу, что в сети он 5 раз извлекает правильный URL-адрес Ajax (для 5 букв), но переменная get - это только первая буква (если это имеет смысл)
  • 1
    Вы уверены? Это странно ... и также невозможно воспроизвести с использованием кода, который вы показали - демонстрация: jsfiddle.net/k3461n7h/1
  • 0
    @ADyson - мы можем перейти в чат?
  • 0
    @ADyson. Если я добавлю console.log(html); в журнале он отображается правильно, но $("#NotAllowed").replaceWith(html); показывает только первую букву (или две, если я печатаю быстро!)
  • 0
    @SebastianSimon, извините, не данные, я изменил, чтобы сказать html
  • 0
    @Designer Тогда что же такое html ? Вы пробовали это регистрировать? Вы читали документацию по replaceWith ?
  • 0
    @SebastianSimon - success: function(html) - возвращает значение из CheckPageName.php ( $PageName=$_GET['PageName']; echo $PageName )
  • 0
    Я предполагаю, что это всего лишь некоторый тестовый код в PHP, потому что он не делает ничего полезного. В любом случае покажите, пожалуйста, HTML этого «запрещенного» элемента.
  • 0
    @ADyson <p class="NotAllowed" id='NotAllowed'></p>
  • 0
    Я исправил это, изменив $("#NotAllowed").replaceWith(html); в $("#NotAllowed").html(html);
  • 0
    Тогда это дубликат: В чем разница между jQuery replaceWith () и html ()?.replaceWith удаляет выбранный элемент.
  • 0
    @Designer lol похоже, что вы поняли это именно в тот момент, когда я это сделал - я писал ответ ниже, когда вы добавляли свой комментарий :-)
Теги:
keyup
CodeFix

2 ответа

1
Лучший ответ

Проблема не имеет ничего общего с вашим вызовом AJAX (хотяasync:false по-прежнему ненужная и плохая практика в целом).

Проблема в том, что делает функция jQuery replaceWith. Согласно документации, он удаляет элементы, которым он соответствует, и заменяет весь элемент содержимым, которое вы передаете функции. Обратите внимание, что он заменяет весь элемент , а не только его внутреннее содержимое!

Таким образом, причина, по которой он работает только один раз, заключается просто в том, что после первого выполнения элемент NotAllowed больше не существует - replaceWith удалил его и заменил его ответом на ваш запрос AJAX!

Если вы хотите обновить содержимое элемента, не удаляя его, в jQuery вы можете использовать.html() или.text() (в зависимости от того, является ли контент HTML или обычным текстом). В таком случае.text() было бы хорошо:

success: function(response) {
    $("#NotAllowed").text(response);
    $('#loader_image').hide();
}

Демо: https://jsfiddle.net/k3461n7h/2/

Поделиться
Источник
-3

Вам следует обернуть вашу функцию нажатия клавиш в debounce . Это сэкономит вам время и сэкономит нагрузку при запросе данных с сервера.

const debounce = (callback, wait) => {
  let timeoutId = null;
  return (...args) => {
    const [ { target } ] = args;
    window.clearTimeout(timeoutId);
    timeoutId = window.setTimeout(() => {
      callback.apply(target, args);
    }, wait);
  };
}

const handleKeyUp = debounce(function() {
  $('#loader-image').show();
  $.ajax({
    type: 'GET',
    async: false,
    url: 'CheckPageName.php',
    data: { 'PageName': $(this).val() },
    cache: false,
    success: function(data, textStatus, jqXHR) {
      $('#not-allowed').html(data);
      $('#loader-image').hide();
    },
    error: function(jqXHR, textStatus, errorThrown) {
      $('#not-allowed').html('<p>Not found...</p>');
      // Hide the mask after 1 second, to mimic waiting for a response
      // Remove this timeout once the response is hooked-up
      setTimeout(function() {
        $('#loader-image').hide();
      }, 1000);
    }
  });
}, 250); // Search only after 250ms once typing has stopped

$('#loader-image').hide();
$('#page-name').on('keyup', handleKeyUp);
#loader-image {
  display: flex;
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  margin: 0;
  padding: 0;
  z-index: 999;
  background: rgba(0, 0, 0, 0.5);
  justify-content: center;
  align-items: center;
  font-weight: bold;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<div class="container">
  <form>
    <div class="mb-3">
      <label for="page-name" class="form-label">Search existing page name</label>
      <input type="text" id="page-name" name="page-name" class="form-control">
      <div id="page-name-help" class="form-text">Check for an existing page.</div>
    </div>
  </form>
  <hr />
  <div id="not-allowed"></div>
</div>
<div id="loader-image">Loading...</div>

Поделиться
Источник

Другие вопросы

CodeFix
Цитата дня

"Завидую тестировщикам: все хотят с ними дружить."

Эндрю Таненбаум