Pergunta

corri para este problema hoje, postagem no caso de alguém tem o mesmo problema.

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

Acontece que para obter IE para executar um onclick em um elemento gerado dinamicamente, não podemos usar setAttribute. Em vez disso, precisamos definir a propriedade onclick no objeto com uma função anônima envolvendo o código que deseja executar.

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

idéias ruins:

Você pode fazer

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

mas ele vai quebrar no IE no modo não-padrão de acordo com @scunliffe.

Você não pode fazer isso em todos

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

porque ele é executado imediatamente, e define o resultado de RunCommand () para ser o valor do atributo onClick, nem você pode fazer

execBtn.setAttribute("onclick", runCommand);
Foi útil?

Solução

para fazer este trabalho em ambos os FF e IE você deve escrever duas maneiras:


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

este pós .

Atualizar : Esta é demonstrar que às vezes ele é necessário o uso de setAttribute! Este método funciona se você precisa tomar o atributo onclick original a partir do HTML e adicioná-lo ao evento onclick, de modo que ele não fica substituído:

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

Outras dicas

Há um GRANDE coleção de atributos que você não podem ser configuradas no IE usando .setAttribute () que inclui cada manipulador de eventos em linha.

Veja aqui para mais detalhes:

http: //webbugtrack.blogspot. com / 2007/08 / bug-242-setAttribute-doesnt-sempre-work.html

funciona muito bem!

usando os dois lados parecem ser desnecessários agora:

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

aparentemente funciona em todos os navegadores atuais.

testada no atual Firefox, IE, Safari, Opera, Chrome no Windows; Raposa de fogo e Epiphany no Ubuntu; não testado em sistemas móveis Mac ou.

  • Craig: Eu tentaria "document.getElementById (ID) .type = 'password';
  • Alguém já verificou a abordagem "addEventListener" com motores diferentes?

Esta é uma função surpreendente para cross-browser compatível evento obrigatório.

Got-lo do http://js.isite.net.au/snippets/addevent

Com ele você pode apenas fazer Events.addEvent(element, event, function); e ser preocupação! Livre

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

Aqui está a função:

// 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 você não quiser usar uma grande função tal, isso deve funcionar para quase todos os navegadores, incluindo o IE:

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

Em resposta à pergunta de Craig. Você vai ter que fazer um novo elemento e copiar os atributos do elemento de idade. Esta função deve fazer o trabalho: ( 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;
}

Ou você poderia usar jQuery e evitar todos esses problemas:

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

jQuery vai cuidar de todas as questões cross-browser também.

Na verdade, tanto quanto eu sei, criados dinamicamente manipuladores de eventos em linha fazer o trabalho perfeitamente dentro do Internet Explorer 8, quando criado com o comando x.setAttribute(); você só tem que posicioná-los corretamente dentro de seu código JavaScript. Me deparei com a solução para o seu problema (e meu) aqui .

Quando me mudei todas as minhas declarações contendo x.appendChild() às suas posições corretas (ou seja, imediatamente após o último comando setAttribute dentro de seus grupos), descobri que cada setAttribute trabalhou no IE8 como era suposto, incluindo todos os atributos de entrada de formulário (incluindo "nome" e atributos "tipo", bem como as minhas "onclick" manipuladores de eventos).

Eu encontrei este bastante notável, já que tudo o que tenho no IE antes que eu fiz isso foi lixo prestados em toda a tela, e um erro após o outro. Além disso, descobri que cada setAttribute ainda funcionava dentro dos outros navegadores também, então se você só lembrar desta codificação para a prática simples, você vai ser bom para ir na maioria dos casos.

No entanto, esta solução não vai funcionar se você tem que mudar todos os atributos em tempo real, uma vez que não pode ser alterado no IE, uma vez seu elemento HTML foi anexado ao DOM; neste caso, eu iria imaginar que um teria que eliminar o elemento do DOM, em seguida, recriá-lo e seus atributos (na ordem correta, é claro!) para que eles funcionem corretamente, e não lançar quaisquer erros.

Escreva a função inline, e o intérprete é bastante inteligente para saber que você está escrevendo uma função. Fazê-lo como este, e ele assume que é apenas uma string (que tecnicamente é).

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

Você tentou:

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

Em alguns casos, os exemplos listados aqui não funcionou para mim no Internet Explorer.

Uma vez que você tem que definir a propriedade com um método como este (sem colchetes)

HtmlElement.onclick = myMethod;

não vai funcionar se você tem que passar por um nome objeto ou até mesmo parâmetros. Para o Internet Explorer, você deve criar um novo objeto em tempo de execução:

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

também funciona em outros navegadores.

Não é relevante para a questão onclick, mas também relacionados:

Para html atributos cuja colidem nome com palavras javascript reservados, um nome alternativo escolhido, por exemplo. <div class=''>, mas div.className, ou <label for='...'>, mas label.htmlFor.

Em navegadores razoáveis, isso não afeta setAttribute. Assim, em gecko e WebKit você chamaria div.setAttribute('class', 'foo'), mas no IE você tem que usar o nome da propriedade javascript vez, então div.setAttribute('className', 'foo').

Você considerou um ouvinte de evento em vez de definir o atributo? Entre outras coisas, ele permite que você passar parâmetros, que foi uma Corri problema em quando se tenta fazer isso. Você ainda tem que fazê-lo duas vezes para 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");

Apenas deixe evento ser um nome como "clique" ou "mouseover".

Eu fiz isso para contorná-la e seguir em frente, no meu caso eu não estou usando um elemento 'input', em vez disso, usar uma imagem, quando eu tentei definindo o atributo "onclick" para esta imagem que eu experimentei a mesma problema, então eu tentei envolvendo a imagem com um elemento "a" e fazendo o ponto de referência para a função como esta.

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

Tente este execBtn.onclick = função () {Eval ( 'RunCommand ()')};

Para mim ele funciona.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top