Jak programowo wymusić zdarzenie onchange na wejściu?


123

Jak programowo wymusić zdarzenie onchange na wejściu?

Próbowałem czegoś takiego:

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

Ale moim ostatecznym celem jest uruchomienie funkcji słuchacza, a to nie działa. Nie wystarczy też zaktualizować atrybut „wartość”.

Odpowiedzi:


143

Utwórz Eventobiekt i przekaż go do dispatchEventmetody elementu:

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

Spowoduje to wyzwolenie detektorów zdarzeń niezależnie od tego, czy zostały zarejestrowane przez wywołanie addEventListenermetody, czy ustawienie onchangewłaściwości elementu.


Jeśli chcesz, aby zdarzenie było bąbelkowe, musisz przekazać konstruktorowi drugi argument Event:

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

Informacje o kompatybilności przeglądarki:


2
Tak, MDN Tworzenie i wyzwalanie zdarzeń jest dobrym źródłem informacji!
Jakub Holý

1
Oto jak to zrobić poprawnie, natywnie. Obsługiwane teraz we wszystkich przeglądarkach: caniuse.com/#feat=dispatchevent
Willem Mulder

1
To jest prawdziwa odpowiedź na to pytanie. Musimy to osiągnąć w nowoczesny sposób.
Константин Ван

1
Próbuję zrobić odpowiednik w IE11, ale nie działa, gdy próbuję zmienić pole wejściowe reaguje. var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); elem.dispatchEvent(evt);
Bodosko

3
Dlaczego wszyscy mówią, że to najlepsza odpowiedź? Zgodnie z połączonym dokumentem Event, nawet aktualna wersja IE nadal tego nie obsługuje.
jeff-h

96

W jQuery najczęściej używam:

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

2
tihs mi pomogło! Ustawiałem wartość pola wyboru (zaznaczone lub nie) za pomocą kodu i zdarzenie w ogóle nie było uruchamiane w IE, niezależnie od tego, co zrobiłem. Próbowałem blur () focus () i kilka innych rzeczy. po ustawieniu wartości nazwałem wyzwalaczem i dodałem zdarzenie kliknięcia również do wywołania wyzwalacza. Powoduje wiele pożarów, ale nie ma to dla mnie znaczenia. W IE dodaję checkboxy za pomocą kodu i musisz na nie dwukrotnie kliknąć, zanim uruchomi się zdarzenie zmiany. Dzięki za tę wskazówkę.
Dustin Davis

6
W ramach aktualizacji $ ("# element"). Change (); robi to samo od wersji jquery 1.0.
CookieOfFortune

3
Zwróć uwagę, że to NIE wyzwala natywnej wymiany. Uruchomi się tylko na wszystkich słuchaczach onchange, którzy zostali powiązani przez jQuery!
Willem Mulder,

Jakaś pomoc tutaj, proszę? Żadne z tych rozwiązań nie wydaje się działać dla mnie .. stackoverflow.com/questions/51216332/
Gabe

61

ugh nie używaj eval do niczego . Cóż, są pewne rzeczy, ale są one niezwykle rzadkie. Raczej zrobiłbyś to:

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

Poszukaj więcej opcji: http://jehiah.cz/archive/firing-javascript-events-properly


3
eval za uprzedmiotowienie JSON;)
Aaron Powell

3
json2.js do uprzedmiotowienia JSON! JSON.parse jest już dostępne w nowoczesnych przeglądarkach
jinglesthula

12
Ta technika działa tylko wtedy, gdy program obsługi zmian został dołączony przez ustawienie „onchange”. Nie generuje „prawdziwego” zdarzenia, które wyzwala programy obsługi zdarzeń w3c lub Microsoft. Zobacz łącze, aby uzyskać więcej informacji.
Stephen Nelson

6
Myślę, że ta odpowiedź jest teraz przestarzała, odpowiedź Miscreant za pomocą new Event(...)i dispatchEventwydaje się, że jest obecnie właściwym rozwiązaniem.
Jakub Holý

4
Ta odpowiedź jest przestarzała ; powyższy kod nie zadziała, jeśli Element.addEventListenerobsługiwałeś zdarzenia. Aby osiągnąć to w nowoczesny sposób, zobacz odpowiedź @ Miscreant.
Константин Ван

23

Z jakiegoś powodu ele.onchange () rzuca dla mnie w IE na mojej stronie wyjątek "nie znaleziono metody", więc skończyło się na tym, że użyłem tej funkcji z linku podanego przez Kolten i wywołałem fireEvent (ele, 'zmiana'), co zadziałało :

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);
    }
}

Stworzyłem jednak stronę testową, która potwierdziła, że ​​połączenie powinno działać:

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

Edycja: Powodem, dla którego ele.onchange () nie działało, było to, że tak naprawdę nie zadeklarowałem niczego dla zdarzenia onchange. Ale fireEvent nadal działa.


2
Ta metoda wykrywania przeglądarki (poprzez wykrywanie obiektów) podoba mi się bardziej niż podany przeze mnie przykład.
Chris MacDonald,

To już nie działa w przeglądarce Firefox 23: „element.dispatchEvent nie jest funkcją”
Oliver

4
Witajcie, koledzy Googlersi. Jest rok 2016! W dzisiejszych czasach piszemy kod jak element.dispatchEvent(new Event('change', true, true))zamiast tego wszystkiego tajemniczego i przeważnie przestarzałego createEventi tak initEventdalej.
ericsoco

3

To jest najbardziej poprawna odpowiedź dla IE i Chrome:

javascript=>

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

2

Zaczerpnięte z dołu QUnit

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);
    }
}

Możesz oczywiście zamienić zawartość $ .browser na własne metody wykrywania przeglądarki, aby uczynić ją niezależną od jQuery.

Aby skorzystać z tej funkcji:

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

Zasadniczo spowoduje to uruchomienie prawdziwego zdarzenia DOM, tak jakby coś się faktycznie zmieniło.


1

Jeśli dodasz wszystkie swoje wydarzenia z tym fragmentem kodu:

//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){...});

wtedy możesz po prostu użyć element.on<EVENTNAME>()gdzie <EVENTNAME>jest nazwą twojego wydarzenia, a to wywoła wszystkie wydarzenia z<EVENTNAME>



-4

jeśli używasz jQuery, powinieneś:

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

lub MS AJAX:

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

Lub w surowym kodzie HTML elementu:

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

Po ponownym przeczytaniu pytania myślę, że przegapiłem - przeczytałem, co było do zrobienia. Nigdy nie znalazłem sposobu, aby zaktualizować element DOM w sposób, który wymusi zdarzenie zmiany, najlepiej jest mieć oddzielną metodę obsługi zdarzeń, taką jak ta:

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

Ponieważ już piszesz metodę JavaScript, która dokona zmiany, wywołanie jest tylko 1 dodatkową linią.

Lub, jeśli za pomocą programu Microsoft AJAX można uzyskać dostęp do wszystkich programów obsługi zdarzeń poprzez:

$get('elementId')._events

Pozwoliłoby ci to na wykonanie pewnych działań w stylu refleksji, aby znaleźć odpowiednią obsługę zdarzeń do uruchomienia.


1
Myślę, że chce odpalić rzeczywiste zdarzenie, a nie uruchamiać funkcję, gdy zdarzenie jest uruchamiane ... tak myślę . lol
Kolten

-5

Za pomocą JQuery możesz wykonać następujące czynności:

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

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

undefined nie jest funkcją.
Hristo Venev,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.