Як я програмую форсувати подія зміни на вході?


123

Як я програмую форсувати подія зміни на вході?

Я спробував щось подібне:

var code = ele.getAttribute('onchange');
eval(code);

Але моя кінцева мета - запускати будь-які функції слухача, і це, здається, не працює. Також не відбувається лише оновлення атрибута "value".

Відповіді:


142

Створіть Eventоб’єкт і передайте його dispatchEventметоду елемента:

var element = document.getElementById('just_an_example');
var event = new Event('change');
element.dispatchEvent(event);

Це запустить слухачів подій незалежно від того, були вони зареєстровані за допомогою виклику addEventListenerметоду або встановлення onchangeвластивості елемента.


Якщо ви хочете, щоб подія спливала, вам потрібно передати Eventконструктору другий аргумент :

var event = new Event('change', { bubbles: true });

Інформація про сумісність браузера:



1
Ось як це зробити правильно, рідно. Зараз підтримується у всіх браузерах: caniuse.com/#feat=dispatchevent
Віллем Малдер,

1
Це справжня відповідь на це питання. Ми повинні цього досягти сучасним чином.
Константин Ван

1
Я намагаюся зробити еквівалент на IE11, але це не працює при спробі змінити поле введення reactjs. var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); elem.dispatchEvent(evt);
Бодосько

3
Чому всі кажуть, що це найкраща відповідь? Згідно з пов'язаним документом Event, навіть поточна версія IE досі не підтримує це.
jeff-h

96

У jQuery я в основному використовую:

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

2
тихи мені допомогли! Я встановлював значення прапорця (відмічено чи ні) за допомогою коду, і подія взагалі не запускалася в IE, незалежно від того, що я робив. Я спробував розмити () фокус () та кілька інших речей. після того як я встановив значення, яке я викликав тригером, і я додав подію клацання, щоб також викликати тригер. Це спричиняє численні пожежі, але для мене це не має значення. У IE я додаю прапорці за допомогою коду, і ви повинні натиснути на них двічі до початку події зміни. Дякую за цю пораду.
Дастін Девіс

6
Як оновлення, $ ("# елемент"). Change (); робить те ж саме, що й jquery 1.0.
CookieOfFortune

3
Зауважте, що це НЕ запускає нативну зміну. Він запустить лише всіх слухачів, що перебувають у мережі, які були пов'язані через jQuery!
Віллем Малдер

Будь-яка допомога тут, будь ласка? Жодне з цих рішень, здається, не працює для мене .. stackoverflow.com/questions/51216332/…
Гейб,

61

Тьфу не використовуй eval ні для чого . Ну, є певні речі, але вони надзвичайно рідкісні. Швидше ви зробите це:

document.getElementById("test").onchange()

Тут шукайте додаткові варіанти: http://jehiah.cz/archive/firing-javascript-events-properly


3
eval за об’єктивацію JSON;)
Аарон Пауелл

3
json2.js для об’єктивації JSON! JSON.parse вже доступний у сучасних браузерах
jinglesthula

12
Цей прийом працює лише в тому випадку, якщо обробник змін був доданий, встановивши "onchange". Це не генерує "справжню" подію, яка запускає обробники подій w3c або microsoft. Детальнішу інформацію див. За посиланням.
Стівен Нельсон

6
Я думаю , що ця відповідь є застарілим зараз, відповідь Лиходія в використанні new Event(...)і dispatchEventє правильним рішенням в даний час, здається.
Якуб Холі

4
Ця відповідь застаріла ; наведений вище код не працюватиме, якщо ви використовували Element.addEventListenerдля обробки подій. Щоб досягти цього сучасним способом, див. Відповідь @ Miscreant.
Константин Ван

23

Чомусь ele.onchange () викидає для мене в IE на моїй сторінці експлікацію "метод не знайдений", тому я в кінцевому рахунку використовував цю функцію за посиланням, яке надав Колтен, і викликав fireEvent (ele, 'change'), який працював :

function fireEvent(element,event){
    if (document.createEventObject){
        // dispatch for IE
        var evt = document.createEventObject();
        return element.fireEvent('on'+event,evt)
    }
    else{
        // dispatch for firefox + others
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent(event, true, true ); // event type,bubbling,cancelable
        return !element.dispatchEvent(evt);
    }
}

Однак я створив тестову сторінку, яка підтвердила, що дзвінки повинні працювати onchange ():

<input id="test1" name="test1" value="Hello" onchange="alert(this.value);"/>
<input type="button" onclick="document.getElementById('test1').onchange();" value="Say Hello"/>

Редагувати: причина ele.onchange () не спрацювала через те, що я фактично нічого не заявив про подію onchange. Але fireEvent все ще працює.


2
Мені подобається цей спосіб виявлення браузера (за допомогою виявлення об’єктів) краще, ніж я наводив приклад.
Кріс Макдональд,

Це більше не працює для Firefox 23: "element.dispatchEvent не є функцією"
Олівер

4
Вітаю, товариші Google. Це 2016 рік! Сьогодні ми пишемо код на зразок element.dispatchEvent(new Event('change', true, true))замість того, що є таємничим і здебільшого застарілим createEventта initEventіншим.
ericsoco

3

Це найправильніша відповідь для IE та Chrome:

javascript=>

var element = document.getElementById('xxxx');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);

2

Взяті з дна КВіт

function triggerEvent( elem, type, event ) {
    if ( $.browser.mozilla || $.browser.opera ) {
        event = document.createEvent("MouseEvents");
        event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
            0, 0, 0, 0, 0, false, false, false, false, 0, null);
        elem.dispatchEvent( event );
    } else if ( $.browser.msie ) {
        elem.fireEvent("on"+type);
    }
}

Звичайно, ви можете замінити речі $ .browser на власні методи виявлення браузера, щоб зробити jQuery незалежним.

Щоб скористатися цією функцією:

var event;
triggerEvent(ele, "change", event);

Це в основному запустить справжню подію DOM так, ніби щось насправді змінилося.


1

Якщо ви додаєте всі свої події за допомогою цього фрагмента коду:

//put this somewhere in your JavaScript:
HTMLElement.prototype.addEvent = function(event, callback){
  if(!this.events)this.events = {};
  if(!this.events[event]){
    this.events[event] = [];
    var element = this;
    this['on'+event] = function(e){
      var events = element.events[event];
      for(var i=0;i<events.length;i++){
        events[i](e||event);
      }
    }
  }
  this.events[event].push(callback);
}
//use like this:
element.addEvent('change', function(e){...});

тоді ви можете просто використовувати, element.on<EVENTNAME>()де <EVENTNAME>називається назва вашої події, і зателефонуватимуть усі події<EVENTNAME>



-4

якщо ви використовуєте jQuery, у вас буде:

$('#elementId').change(function() { alert('Do Stuff'); });

або MS AJAX:

$addHandler($get('elementId'), 'change', function(){ alert('Do Stuff'); });

Або в сирому HTML елементі:

<input type="text" onchange="alert('Do Stuff');" id="myElement" />

Після перечитання питання, я думаю, я пропускаю прочитати, що потрібно було зробити. Я ніколи не знаходив способу оновити елемент DOM таким чином, щоб змусити змінити подію, що найкраще робити - це використовувати окремий метод обробника подій, як-от:

$addHandler($get('elementId'), 'change', elementChanged);
function elementChanged(){
  alert('Do Stuff!');
}
function editElement(){
  var el = $get('elementId');
  el.value = 'something new';
  elementChanged();
}

Оскільки ви вже пишете метод JavaScript, який змінить, лише 1 додаткову лінію для дзвінка.

Або, якщо ви будете з допомогою платформи Microsoft AJAX ви можете отримати доступ до всіх обробникам подій з допомогою:

$get('elementId')._events

Це дозволить зробити кілька роздумів у стилі рефлексії, щоб знайти потрібний обробник подій для запуску.


1
Я вважаю, що він хоче запустити фактичну подію, а не виконувати функцію, коли подія звільнена ... я думаю . lol
Колтен

-5

За допомогою JQuery ви можете зробити наступне:

// for the element which uses ID
$("#id").trigger("change");

// for the element which uses class name
$(".class_name").trigger("change");

undefined не є функцією.
Христо Венев
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.