style eliminar attribute atributo agregar javascript internet-explorer

javascript - eliminar - ¿Por qué una propiedad onclick establecida con setAttribute no funciona en IE?



setattribute jquery (14)

Se topó con este problema hoy, publicando en caso de que alguien más tenga el mismo problema.

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

Resulta que IE ejecuta un onclick en un elemento generado dinámicamente, no podemos usar setAttribute. En su lugar, debemos establecer la propiedad onclick en el objeto con una función anónima que envuelva el código que queremos ejecutar.

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

MALAS IDEAS:

Tu puedes hacer

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

pero se romperá en IE en modo no estándar de acuerdo con @scunliffe.

No puedes hacer esto en absoluto

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

porque se ejecuta inmediatamente y establece el resultado de que runCommand () sea el valor del atributo onClick, y no se puede hacer

execBtn.setAttribute("onclick", runCommand);


¡Funciona genial!

usar ambas formas parece ser innecesario ahora:

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

aparentemente funciona en todos los navegadores actuales.

probado en Firefox actual, IE, Safari, Opera, Chrome en Windows; Firefox y Epiphany en Ubuntu; no probado en Mac o sistemas móviles.

  • Craig: probaría con "document.getElementById (ID) .type = ''contraseña'';
  • ¿Alguien ha revisado el enfoque "AddEventListener" con diferentes motores?

¿Has considerado un oyente de eventos en lugar de establecer el atributo? Entre otras cosas, te permite pasar parámetros, que fue un problema que tuve al intentar hacer esto. Todavía tienes que hacerlo dos veces para IE y 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");

Solo deja que el evento sea un nombre como "clic" o "mouseover".


En algunos casos, los ejemplos enumerados aquí no funcionaron para mí en Internet Explorer.

Dado que debe establecer la propiedad con un método como este (sin corchetes)

HtmlElement.onclick = myMethod;

no funcionará si tiene que pasar un nombre de objeto o incluso parámetros. Para Internet Explorer debe crear un nuevo objeto en tiempo de ejecución:

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

Funciona también en otros navegadores.


En realidad, hasta donde yo sé, los controladores de eventos en línea creados dinámicamente SI funcionan perfectamente en Internet Explorer 8 cuando se crean con el x.setAttribute() ; solo tiene que ubicarlos correctamente dentro de su código JavaScript. Me encontré con la solución a su problema (y el mío) here .

Cuando moví todas mis declaraciones que contenían x.appendChild() a sus posiciones correctas (es decir, inmediatamente después del último comando setAttribute dentro de sus grupos), encontré que CADA setAttribute solo funcionaba en IE8 como se suponía que lo hiciera, incluyendo todas las entradas de formularios atributos (incluidos los atributos "nombre" y "tipo", así como mis controladores de eventos "onclick").

Esto me pareció bastante notable, ya que todo lo que obtuve en IE antes de hacerlo fue basura en la pantalla y un error tras otro. Además, descubrí que cada setAttribute todavía funcionaba en los otros navegadores, por lo que si solo recuerdas esta simple práctica de codificación, serás bueno en la mayoría de los casos.

Sin embargo, esta solución no funcionará si tiene que cambiar los atributos sobre la marcha, ya que no se pueden cambiar en IE una vez que su elemento HTML se haya agregado al DOM; en este caso, me imagino que uno debería eliminar el elemento del DOM, y luego volver a crearlo y sus atributos (¡en el orden correcto, por supuesto!) para que funcionen correctamente y no arrojar ningún error.


Escriba la función en línea, y el intérprete es lo suficientemente inteligente como para saber que está escribiendo una función. Hazlo así, y asume que es solo una cadena (que técnicamente es).


Esta es una función increíble para vincular eventos compatibles con varios navegadores.

Lo obtuve de http://js.isite.net.au/snippets/addevent

Con él puedes hacer Events.addEvent(element, event, function); ¡y sin preocupaciones!

Por ejemplo: ( 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);

Aquí está la función:

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

Si no desea utilizar una función tan grande, esto debería funcionar para casi todos los navegadores, incluido IE:

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

En respuesta a la pregunta de Craig. Tendrá que crear un nuevo elemento y copiar los atributos del antiguo elemento. Esta función debería hacer el trabajo: ( source )

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


Has probado:

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



Hice esto para evitarlo y seguir adelante, en mi caso no estoy usando un elemento de ''entrada'', en su lugar uso una imagen, cuando intenté configurar el atributo "onclick" para esta imagen, experimenté el mismo problema, por lo que Intenté envolver la imagen con un elemento "a" y hacer el punto de referencia para la función de esta manera.

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


No relevante para el problema onclick, pero también relacionado:

Para los atributos html cuyo nombre colisiona con las palabras reservadas de JavaScript, se elige un nombre alternativo, por ej. <div class=''''> , pero div.className , o <label for=''...''> , pero label.htmlFor .

En navegadores razonables, esto no afecta a setAttribute . Entonces en gecko y webkit llamarías a div.setAttribute(''class'', ''foo'') , pero en IE tienes que usar el nombre de la propiedad de javascript en su lugar, así que div.setAttribute(''className'', ''foo'') .


O podría usar jQuery y evitar todos esos problemas:

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

jQuery también se ocupará de todos los problemas del navegador.


Para hacer que esto funcione tanto en FF como en IE, debes escribir de las dos maneras:

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

gracias a esta publicación

ACTUALIZACIÓN : ¡Esto es para demostrar que a veces es necesario usar setAttribute! Este método funciona si necesita tomar el atributo onclick original del HTML y agregarlo al evento onclick, para que no quede anulado:

// 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 }


Pruebe este execBtn.onclick = function () {eval (''runCommand ()'')};

Para mi funciona


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