Domanda

Ho riscontrato questo problema oggi, pubblicando nel caso in cui qualcun altro abbia lo stesso problema.

var execBtn = document.createElement('input');
execBtn.setAttribute("type", "button");
execBtn.setAttribute("id", "execBtn");
execBtn.setAttribute("value", "Execute");
execBtn.setAttribute("onclick", "runCommand();");

Risulta che per fare in modo che IE esegua un onclick su un elemento generato dinamicamente, non possiamo usare setAttribute.Dobbiamo invece impostare la proprietà onclick sull'oggetto con una funzione anonima che racchiude il codice che vogliamo eseguire.

execBtn.onclick = function() { runCommand() };

CATTIVE IDEE:

Tu puoi fare

execBtn.setAttribute("onclick", function() { runCommand() });

ma secondo @scunliffe si romperà in IE in modalità non standard.

Non puoi farlo affatto

execBtn.setAttribute("onclick", runCommand() ); 

perché viene eseguito immediatamente e imposta il risultato di runCommand() come valore dell'attributo onClick, né puoi farlo

execBtn.setAttribute("onclick", runCommand);
È stato utile?

Soluzione

per farlo funzionare sia in FF che in IE devi scrivere in entrambi i modi:


    button_element.setAttribute('onclick','doSomething();'); // for FF
    button_element.onclick = function() {doSomething();}; // for IE

grazie a questo post.

AGGIORNAMENTO:Questo per dimostrare che a volte è così È necessario utilizzare setAttribute!Questo metodo funziona se devi prendere l'attributo onclick originale dall'HTML e aggiungerlo all'evento onclick, in modo che non venga sovrascritto:

// get old onclick attribute
var onclick = button_element.getAttribute("onclick");  

// if onclick is not a function, it's not IE7, so use setAttribute
if(typeof(onclick) != "function") { 
    button_element.setAttribute('onclick','doSomething();' + onclick); // for FF,IE8,Chrome

// if onclick is a function, use the IE7 method and call onclick() in the anonymous function
} else {
    button_element.onclick = function() { 
        doSomething();
        onclick();
    }; // for IE7
}

Altri suggerimenti

C'è un GRANDE raccolta di attributi tu non è possibile impostarlo in IE utilizzando .setAttribute() che include ogni gestore di eventi in linea.

Vedi qui per i dettagli:

http://webbugtrack.blogspot.com/2007/08/bug-242-setattribute-doesnt-always-work.html

funziona alla grande!

l'uso di entrambi i modi sembra non essere necessario ora:

execBtn.onclick = function() { runCommand() };

apparentemente funziona in tutti i browser attuali.

testato negli attuali Firefox, IE, Safari, Opera, Chrome su Windows;Firefox ed epifania su Ubuntu;non testato su Mac o sistemi mobili.

  • Brama:Proverei "document.getElementById(ID).type='password';
  • Qualcuno ha verificato l'approccio "AddEventListener" con motori diversi?

Questa è una funzione straordinaria per l'associazione di eventi compatibile con più browser.

Capito da http://js.isite.net.au/snippets/addevent

Con esso puoi semplicemente farlo Events.addEvent(element, event, function); e non preoccuparti!

Per esempio:(http://jsfiddle.net/Zxeka/)

function hello() {
    alert('Hello');
}

var button = document.createElement('input');
button.value = "Hello";
button.type = "button";

Events.addEvent(input_0, "click", hello);

document.body.appendChild(button);

Ecco la funzione:

// We create a function which is called immediately,
// returning the actual function object.  This allows us to
// work in a separate scope and only return the functions
// we require.
var Events = (function() {

  // For DOM2-compliant browsers.
  function addEventW3C(el, ev, f) {
    // Since IE only supports bubbling, for
    // compatibility we can't use capturing here.
    return el.addEventListener(ev, f, false);
  }

  function removeEventW3C(el, ev, f) {
    el.removeEventListener(ev, f, false);
  }

  // The function as required by IE.
  function addEventIE(el, ev, f) {
    // This is to work around a bug in IE whereby the
    // current element doesn't get passed as context.
    // We pass it via closure instead and set it as the
    // context using call().
    // This needs to be stored for removeEvent().
    // We also store the original wrapped function as a
    // property, _w.
    ((el._evts = el._evts || [])[el._evts.length]
        = function(e) { return f.call(el, e); })._w = f;

    // We prepend "on" to the event name.
    return el.attachEvent("on" + ev,
        el._evts[el._evts.length - 1]);
  }

  function removeEventIE(el, ev, f) {
    for (var evts = el._evts || [], i = evts.length; i--; )
      if (evts[i]._w === f)
        el.detachEvent("on" + ev, evts.splice(i, 1)[0]);
  }

  // A handler to call all events we've registered
  // on an element for legacy browsers.
  function addEventLegacyHandler(e) {
    var evts = this._evts[e.type];
    for (var i = 0; i < evts.length; ++i)
      if (!evts[i].call(this, e || event))
        return false;
  }

  // For older browsers.  We basically reimplement
  // attachEvent().
  function addEventLegacy(el, ev, f) {
    if (!el._evts)
      el._evts = {};

    if (!el._evts[ev])
      el._evts[ev] = [];

    el._evts[ev].push(f);

    return true;
  }

  function removeEventLegacy(el, ev, f) {
    // Loop through the handlers for this event type
    // and remove them if they match f.
    for (var evts = el._evts[ev] || [], i = evts.length; i--; )
      if (evts[i] === f)
        evts.splice(i, 1);
  }

  // Select the appropriate functions based on what's
  // available on the window object and return them.
  return window.addEventListener
      ? {addEvent: addEventW3C, removeEvent: removeEventW3C}
      : window.attachEvent
          ? {addEvent: addEventIE, removeEvent: removeEventIE}
          : {addEvent: addEventLegacy, removeEvent: removeEventLegacy};
})();

Se non vuoi utilizzare una funzione così grande, dovrebbe funzionare per quasi tutti i browser, incluso IE:

if (el.addEventListener) { 
    el.addEventListener('click', function, false); 
} else if (el.attachEvent) { 
    el.attachEvent('onclick', function); 
} 

In risposta alla domanda di Craig.Dovrai creare un nuovo elemento e copiare gli attributi del vecchio elemento.Questa funzione dovrebbe fare il lavoro:(fonte)

function changeInputType(oldObject, oType) {
  var newObject = document.createElement('input');
  newObject.type = oType;
  if(oldObject.size) newObject.size = oldObject.size;
  if(oldObject.value) newObject.value = oldObject.value;
  if(oldObject.name) newObject.name = oldObject.name;
  if(oldObject.id) newObject.id = oldObject.id;
  if(oldObject.className) newObject.className = oldObject.className;
  oldObject.parentNode.replaceChild(newObject,oldObject);
  return newObject;
}

Oppure potresti utilizzare jQuery ed evitare tutti questi problemi:

var execBtn = $("<input>", {
       type: "button",
       id: "execBtn",
       value: "Execute"
    })
    .click(runCommand);        

jQuery si occuperà anche di tutti i problemi cross-browser.

In realtà, per quanto ne so, i gestori di eventi in linea creati dinamicamente funzionano perfettamente con Internet Explorer 8 se creati con x.setAttribute() comando;devi solo posizionarli correttamente all'interno del tuo codice JavaScript.Mi sono imbattuto nella soluzione al tuo problema (e al mio) Qui.

Quando ho spostato tutte le mie dichiarazioni contenenti x.appendChild() nelle loro posizioni corrette (ovvero, immediatamente dopo l'ultimo comando setAttribute all'interno dei loro gruppi), ho scoperto che OGNI singolo setAttribute funzionava in IE8 come avrebbe dovuto, inclusi tutti gli attributi di input del modulo (inclusi gli attributi "nome" e "tipo", come così come i miei gestori di eventi "onclick").

L'ho trovato piuttosto notevole, dal momento che tutto ciò che ho ottenuto in IE prima di farlo era spazzatura renderizzata sullo schermo e un errore dopo l'altro.Inoltre, ho scoperto che ogni setAttribute funzionava ancora anche con gli altri browser, quindi se ricordi questa semplice pratica di codifica, sarai a posto nella maggior parte dei casi.

Tuttavia, questa soluzione non funzionerà se è necessario modificare al volo degli attributi, poiché non possono essere modificati in IE una volta che il loro elemento HTML è stato aggiunto al DOM;in questo caso, immagino che si dovrebbe eliminare l'elemento dal DOM, quindi ricrearlo e i suoi attributi (nell'ordine corretto, ovviamente!) affinché funzionino correttamente e non generino errori.

Scrivi la funzione in linea e l'interprete è abbastanza intelligente da sapere che stai scrivendo una funzione.Fallo in questo modo e presuppone che sia solo una stringa (che tecnicamente lo è).

function CheckBrowser(){
    if(navigator.userAgent.match(/Android/i)!=null||
        navigator.userAgent.match(/BlackBerry/i)!=null||
        navigator.userAgent.match(/iPhone|iPad|iPod/i)!=null||
        navigator.userAgent.match(/Nokia/i)!=null||
        navigator.userAgent.match(/Opera M/i)!=null||
        navigator.userAgent.match(/Chrome/i)!=null)
        {
            return 'OTHER';
    }else{
            return 'IE';
    }
}


function AddButt(i){
    var new_butt = document.createElement('input');
    new_butt.setAttribute('type','button');
    new_butt.setAttribute('value','Delete Item');
    new_butt.setAttribute('id', 'answer_del_'+i);
    if(CheckBrowser()=='IE'){
        new_butt.setAttribute("onclick", function() { DelElemAnswer(i) });
    }else{
        new_butt.setAttribute('onclick','javascript:DelElemAnswer('+i+');');
    }
}

Hai provato:

    execBtn.setAttribute("onclick", function() { runCommand() });

In alcuni casi gli esempi elencati qui non hanno funzionato per me in Internet Explorer.

Dato che devi impostare la proprietà con un metodo come questo (senza parentesi)

HtmlElement.onclick = myMethod;

non funzionerà se devi passare un nome oggetto o anche parametri.Per Internet Explorer dovresti creare un nuovo oggetto in runtime:

HtmlElement.onclick = new Function('myMethod(' + someParameter + ')');

Funziona anche su altri browser.

Non rilevante per il problema onclick, ma correlato anche a:

Per gli attributi html il cui nome entra in conflitto con parole riservate javascript, viene scelto un nome alternativo, ad es. <div class=''>, Ma div.className, O <label for='...'>, Ma label.htmlFor.

Nei browser ragionevoli, ciò non influisce setAttribute.Quindi in gecko e webkit chiameresti div.setAttribute('class', 'foo'), ma in IE devi invece utilizzare il nome della proprietà javascript, quindi div.setAttribute('className', 'foo').

Hai considerato un ascoltatore di eventi anziché impostare l'attributo?Tra le altre cose, ti consente di passare parametri, il che è stato un problema che ho riscontrato durante il tentativo di farlo.Devi ancora farlo due volte per IE e Mozilla:

function makeEvent(element, callback, param, event) {
    function local() {
        return callback(param);
    }

    if (element.addEventListener) {
        //Mozilla
        element.addEventListener(event,local,false);
    } else if (element.attachEvent) {
        //IE
        element.attachEvent("on"+event,local);
    }
}

makeEvent(execBtn, alert, "hey buddy, what's up?", "click");

Lascia che l'evento sia un nome come "clic" o "passaggio del mouse".

L'ho fatto per aggirare il problema e andare avanti, nel mio caso non sto usando un elemento 'input', invece uso un'immagine, quando ho provato a impostare l'attributo "onclick" per questa immagine ho riscontrato lo stesso problema, quindi Ho provato a racchiudere l'immagine con un elemento "a" e a creare il punto di riferimento per la funzione in questo modo.

var rowIndex = 1;
var linkDeleter = document.createElement('a');
linkDeleter.setAttribute('href', "javascript:function(" + rowIndex + ");");

var imgDeleter = document.createElement('img');
imgDeleter.setAttribute('alt', "Delete");
imgDeleter.setAttribute('src', "Imagenes/DeleteHS.png");
imgDeleter.setAttribute('border', "0");

linkDeleter.appendChild(imgDeleter);

Prova questo exectBtn.onclick = function () {eval ('runCommand ()')};

Per me funziona.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top