Слушатель событий Focus не срабатывает при нередактируемом вводе

Я пытаюсь заставить прослушиватель событий фокуса срабатывать, когда пользователь пытается ввести P.O. Вставьте в поле адреса. Я не могу редактировать ввод для простого решения для нажатия клавиш. Что мне не хватает в моем коде, что я не получаю предупреждение?

http://jsfiddle.net/ZQQS9/7/

<input type="text" size="25" maxlength="75" name="ShipAddress1" id="v65-onepage-shipaddr1" value="" style="" onkeydown="">

<script type="text/javascript">  
    document.addEventListener("focus", function killPObox(id) {
        var idValue = document.getElementById('v65-onepage-shipaddr1').value;   
        if (id == 'v65-onepage-shipaddr1') {
            function runVal() {
               if (idValue.substr(0,4).toUpperCase() === "PO B" || idValue.substr(0,5) === "P.O. ") {
                    alert("USA Light cannot ship to P.O. Boxes. Please enter a street address.");
                    }
                }
                    setInterval(runVal(),1);
            }
        }, true
    );
</script>

person Todd Williams    schedule 23.04.2015    source источник
comment
id — это не строка, это объект Event. Вы можете попробовать event.target.id   -  person Halcyon    schedule 24.04.2015
comment
Почему вы добавляете прослушиватель событий в документ вместо элемента ввода?   -  person Barmar    schedule 24.04.2015
comment
Следует также отметить, что вы используете setInterval неправильно. Вы должны передать ему обратный вызов, например setInterval(runVal, 1) (обратите внимание на отсутствие скобок). Прямо сейчас вы передаете ему вывод runVal(), который ничего не значит. Функция запустится один раз и больше никогда.   -  person Halcyon    schedule 24.04.2015
comment
@Barmar, я не могу редактировать ввод. Это код заблокированной корзины Volusion.   -  person Todd Williams    schedule 24.04.2015


Ответы (1)


Я перечислил некоторые проблемы (в дополнение к решению внизу):

1) Как упомянул Halcyon, аргумент id в вашей функции killPObox(id) назначается событию, поэтому вы можете получить нужные вам значения, сначала получив target события, которое будет вашим <input>.

2) Как упоминал Бармар, прослушиватель событий добавляется в документ, а не в сам элемент ввода.

3) Как упомянул Halcyon, setInterval() принимает функцию, а не оцененный результат функции.

4) setInterval() не является хорошим решением, потому что это приведет к тому, что ваша проверка будет выполняться слишком много раз. Особенно, когда пользователь получает предупреждение, пользователь будет постоянно получать предупреждение. Мы можем исправить это, воспользовавшись более подходящим прослушивателем событий, таким как input.

5) Событие focus — не лучшее событие для прослушивания. Мы можем исправить это, используя событие input для прослушивания изменений значений. вашего <input>.

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

document.getElementById('v65-onepage-shipaddr1')
  .addEventListener('input', function killPObox(e) {
    var targetValue = e.target.value;
    if (targetValue.substr(0, 4).toUpperCase() === "PO B" || targetValue.substr(0, 5) === "P.O. ") {
      alert("USA Light cannot ship to P.O. Boxes. Please enter a street address.");
    }
  }, true);
<input type="text" size="25" maxlength="75" name="ShipAddress1" id="v65-onepage-shipaddr1">

person boombox    schedule 23.04.2015
comment
Кажется, это работает! Странно то, что это не работает в JSfiddle, но работает здесь, в редакторе stackoverflow. Есть идеи, почему? (Я бы проголосовал за ответ, но моя репутация слишком низкая) - person Todd Williams; 24.04.2015
comment
Моя скрипка была настроена на отсутствие переноса в ‹head› вместо onLoad в левом меню. Теперь это работает! Спасибо! Не могли бы вы проголосовать за мой вопрос, чтобы я мог проголосовать за таких авторов, как вы? - person Todd Williams; 24.04.2015
comment
Вам не нужно тестировать e.target.id, так как вы только добавляете прослушиватель к этому идентификатору. Просто используйте this, чтобы получить цель. - person Barmar; 24.04.2015
comment
Это очень верно! Я сделаю модификацию. - person boombox; 24.04.2015