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ść”.

Soldarnal
źródło

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:

Niegodziwiec
źródło
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");
Danita
źródło
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

Kolten
źródło
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.

Soldarnal
źródło
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);
Peter Lo
źródło
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.

Chris MacDonald
źródł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>

Wntiv Senyh
źródło
-2

Do wyzwalania dowolnego zdarzenia w JavaScript.

 document.getElementById("yourid").addEventListener("change", function({
    //your code here
})
Hareesh Seela
źródło
2
to nasłuchiwanie zdarzeń, a nie ich wyzwalanie.
niepoprawna nazwa użytkownika
-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.

Aaron Powell
źródło
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");
STALOWY ITBOY
źródło
undefined nie jest funkcją.
Hristo Venev,