val () не викликає зміни () у jQuery


343

Я намагаюся викликати changeподію у текстовому полі, коли змінюю її значення кнопкою, але це не працює. Перевірте цю загадку .

Якщо ви вводите щось у текстових полях і натискаєте десь ще, changeспрацьовує. Однак, якщо натиснути кнопку, значення текстового поля буде змінено, але changeне спрацьовує. Чому?



Назва сама відповіла на моє запитання. Підтверджено у .change () жовтому "Примітка: Змінення значення вхідного елемента за допомогою JavaScript, наприклад, використовуючи .val (), не призведе до запуску події."
Боб Штейн

Хочеться, щоб я швидше натрапив на stackoverflow.com/questions/11873721/… , сподіваюся, що це допоможе.
JeopardyTempest

Відповіді:


454

onchange спрацьовує лише тоді, коли користувач набирає вхід, а потім вхід втрачає фокус.

Ви можете вручну викликати onchangeподію за допомогою після встановлення значення:

$("#mytext").change(); // someObject.onchange(); in standard JS

Можна також запустити подію, використовуючи:

$("#mytext").trigger("change");

18
не соромтеся розширити jquery і додати функцію say valWithChange, яка буде робити те, що ви хочете. Це не може бути дією за замовчуванням стільки разів, коли ви не хочете, щоб подія, викликана автоматизованою зміною значення, лише тоді, коли користувач взаємодіє з елементом
redsquare

8
Я хотів би, щоб ця відповідь була відредагована, щоб звернутись до варіанту прив’язки .change()до .val()методу.
Снексе

19
Причина може бути в тому , що деякі люди називають .val()в .change()тому , що вони роблять вхідні перевірку. Спрацьовування .change()на .val()викличе нескінченний цикл.
Yingted

7
Тільки якби вони змінювали цінність на щось, що не могло б їх власну перевірку, що було б нерозумно.
Ленг

3
Я закінчився зобов’язанням blurздійснити щось подібне:$('#mytext').focus().val('New text').blur();
Уес Джонсон

63

З чудової пропозиції червоного колеса це чудово працює:

$.fn.changeVal = function (v) {
    return this.val(v).trigger("change");
}

$("#my-input").changeVal("Tyrannosaurus Rex");

5
Вам не потрібно загортати this:return this.val(v).trigger("change");
Містер Полівурл

27

Ви можете дуже легко змінити valфункцію, щоб викликати зміни, замінивши її на проксі до вихідної valфункції.

просто додайте цей код десь у вашому документі (після завантаження jQuery)

(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0)
            $(this).change(); // OR with custom event $(this).trigger('value-changed');
        return result;
    };
})(jQuery);

Робочий приклад: тут

(Зауважте, що це завжди спрацює, changeколиval(new_val) викликається, навіть якщо значення насправді не змінилося.)

Якщо ви хочете викликати зміну ТІЛЬКИ, коли значення фактично змінилося, скористайтеся цим:

//This will trigger "change" event when "val(new_val)" called 
//with value different than the current one
(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var prev;
        if(arguments.length>0){
            prev = originalVal.apply(this,[]);
        }
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0 && prev!=originalVal.apply(this,[]))
            $(this).change();  // OR with custom event $(this).trigger('value-changed')
        return result;
    };
})(jQuery);

Живий приклад для цього: http://jsfiddle.net/5fSmx/1/


4
Хм, непотрібне каченя, я думаю :-p. Може бути краще, так як коментували RedSquare , дають таку функцію ім'я , відмінне .val().
бінкі

1
Якщо ви перейменовуєте його, слід змінити існуючий код - таким чином ваш існуючий код буде продовжувати працювати
Yaron U.

4
Але тоді весь код, написаний з правильним визначенням .val()на увазі, раптом почне створювати побічні ефекти :-p.
бінкі

2
Це також призведе до несправності плагінів, що може бути не так легко виправити
SoWhat

1
Щоб уникнути побічних ефектів, я змінив функцію val, як описано вище, але викликаю іншу подію ("val"), яка дозволяє мені зберігати існуючий код, але легко обробляти його, коли мені потрібно: $ (... ) .on ('змінити вал', ...)
улу


14

Ні, можливо, вам не знадобиться його запускати вручну після встановлення значення:

$('#mytext').change();

або:

$('#mytext').trigger('change');

8

Схоже, події не киплять. Спробуйте це:

$("#mybutton").click(function(){
  var oldval=$("#mytext").val();
  $("#mytext").val('Changed by button');
  var newval=$("#mytext").val();
  if (newval != oldval) {
    $("#mytext").trigger('change');
  }
});

Я сподіваюся, що це допомагає.

Я спробував просто звичайне старе, $("#mytext").trigger('change')не зберігаючи старе значення, і .changeпожежі, навіть якщо значення не змінилося. Ось чому я зберег попереднє значення і зателефонував $("#mytext").trigger('change')лише у тому випадку, якщо воно зміниться.


Здивовано, що цього не було більше голосів, оскільки це ефективна реалізація зміни елементів HTML.
vol7ron

4

Станом на feb 2019 .addEventListener()наразі не працює з jQuery .trigger()або .change(), ви можете протестувати його нижче за допомогою Chrome або Firefox.

txt.addEventListener('input', function() {
  console.log('not called?');
})
$('#txt').val('test').trigger('input');
$('#txt').trigger('input');
$('#txt').change();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="txt">

ви повинні використовувати .dispatchEvent()замість цього.

txt.addEventListener('input', function() {
  console.log('it works!');
})
$('#txt').val('yes')
txt.dispatchEvent(new Event('input'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type="text" id="txt">


1

З https://api.jquery.com/change/ :

changeПодія надсилається до елементу , коли змінюється його значення. Ця подія обмежується <input>елементами, <textarea>коробками та <select>елементами. Для полів вибору, прапорців та радіо кнопок подія запускається негайно, коли користувач робить вибір за допомогою миші, але для інших типів події відкладається, поки елемент не втратить фокус.


1

Я знаю, що це стара тема, але для інших, хто шукає, наведені вище рішення, можливо, не такі гарні, як наступні, замість того, щоб перевіряти changeподії, перевіряти inputподії.

$("#myInput").on("input", function() {
    // Print entered value in a div box
    $("#result").text($(this).val());
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.