[JAVASCRIPT] InnerHTML não funciona com addEventListener

256 views
Skip to first unread message

Antonio Jozzolino

unread,
Aug 17, 2007, 7:45:32 AM8/17/07
to ar...@googlegroups.com, arq...@googlegroups.com
A página descarrega várias páginas do servidor e monta cada uma num
div oculto. Na lateral, há botões que acionam esses links, não com
show e hide, mas com innetHTML.

O problema é que os botões tem o comportamento definido pelo load de
eventos. Até aí beleza, bonito, MVC. O problema ocorre quando o
conteúdo tem links também. Fiz uma função, mas os eventos não são
atachados aos links, e eu acho que o culpado é o innerHTML.

Tentei chamar a função de carrega os eventos APÓS o disparo do
innetHTML, mas não funcionou.

Estou considerando mudar a função usando o velho hide e show, assim os
eventos são carregados no load da página.

Só não sei se isso impactará outras coisas. É que peguei este trabalho
em andamento, quer dizer, não sou o autor dessa arquitetura.

Alguma idéia ou sugestão? Sei que está conceitual, mas não dá pra
postar o código...

--
Antonio Jozzolino
-------------------------------------------
SOLUÇÃO GRÁFICA DESIGN
Graphic Design Illustration Web Development
Website : http://www.sgd.com.br
Resume : http://tinyurl.com/dt27l
RSS : http://feeds.feedburner.com/sgd
Orkut : http://tinyurl.com/39eybw
Via6 : http://tinyurl.com/2wyxt6
-------------------------------------------

leandro n. camargo

unread,
Aug 17, 2007, 8:09:18 AM8/17/07
to ar...@googlegroups.com
A questão é:
quais são esses eventos?

O problema maior de envolver event listeners com conteúdo carregado
assincronamente é atrelar os eventos aos novos elementos no DOM.
A solução mais interessante é passar uma função callback e seus
possíveis argumentos a cada carregamento de um conteúdo via http
request. Para isso você teria que implementar nas funções que realizam
os http requests para aceitar mais 2 parêmetros:
- a função callback
- os argumentos dessa função (opcional)

Antonio Jozzolino

unread,
Aug 17, 2007, 8:19:24 AM8/17/07
to ar...@googlegroups.com
Leandro

o evento é onClick numa tag a, que deve retornar false para invalidar o link.

veja só a função que está sendo usada para carregar os eventos:

function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}

Essa aqui não seria melhor?

function addEvent(elm, evType, fn, useCapture)
{
if (elm.addEventListener){
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent){
var r = elm.attachEvent("on"+evType, fn);
return r;
} else {
alert("Handler could not be removed");
}
}


obrigado

--
Antonio Jozzolino
-------------------------------------------
SOLUÇÃO GRÁFICA DESIGN

leandro n. camargo

unread,
Aug 17, 2007, 8:26:59 AM8/17/07
to ar...@googlegroups.com
Use a segunda função...mas de qualquer forma, em que momento você
vincula o evento ao objeto?

On 8/17/07, Antonio Jozzolino <antonio....@gmail.com> wrote:
>

Antonio Jozzolino

unread,
Aug 17, 2007, 8:34:05 AM8/17/07
to ar...@googlegroups.com
Só reparei que estava sendo usada esta primeira função agora, e me
parece que usar o onload não funcionaria para anexar eventos após o
carregamento da página. É isso mesmo?

Numa primeira tentativa, estava usando a função e anexando o evento
onclick no load na pagina. Depois, quando percebi o innerHTML, tentei
usar essa funcao após o innerHTML, pensando que então o DOM seria
reescrito e ele encontraria o objeto. Mas não funcionou.

Ainda não testei com essa outra função, mas acredito e tenho fé que
ela resolverá o problema,. O que você acha?

--
Antonio Jozzolino
-------------------------------------------
SOLUÇÃO GRÁFICA DESIGN

Graphic Design Illustration Web Development


On 8/17/07, leandro n. camargo <leand...@gmail.com> wrote:

leandro n. camargo

unread,
Aug 17, 2007, 9:11:03 AM8/17/07
to ar...@googlegroups.com
Não resolve.
Porque você vai atrelar o evento ao objeto quando a janela é carregada...
Você teria que atribuir novamente a cada "ajax load", a cada conteúdo
novo inserido dentro de uma div. Por isso mencionei a solução da
callback...você teria que cahamar ela a cada sucesso de carregamento
de uma requisição ajax (http request).

Rafael Mendes H. Perez

unread,
Aug 17, 2007, 10:55:46 AM8/17/07
to ar...@googlegroups.com
Uma solução possível é adicionar um listener no container onde você joga
o innerHTML. Neste listener você pegará do objeto Event a propriedade
target (no W3C) ou srcElement (no IE), que retornará o elemento onde o
evento se originou -- que é diferente do elemento onde o evento foi
capturado. Em seguida, você procura o id deste evento num objeto que
contém um mapeamento id -> função. Se for encontrada uma entrada, você
chama a respectiva função, caso contrário, ignora a chamada.

Vale lembrar que se algum destes links possuir sub-elementos (imgs, span
etc), você precisará fazer um loop que começa comparando o elemento e
vai subindo na hierarquia (através da propriedade parentNode) até chegar
no container.

Não sei se fui claro, qualquer coisa é só falar que escrevo um exemplo.

[]s
Rafael

Antonio Jozzolino

unread,
Aug 17, 2007, 11:08:39 AM8/17/07
to ar...@googlegroups.com
Rafael

Não sei se consegui entender, acho que você vai ter que "desenhar",
eheheh. Confesso também que não sei o que é função callback... :-(
Seria uma função recursiva?


Se eu entendi, seria colocar no inner, algo assim:

main.innerHTML = content.innerHTML+'<script>
addEvent(this, 'load', makeThirdLinks, true);</script>';

???

Anyway

Resolvi o negócio com uma solução POG maluca:

function makeThirdLinks(){
var fls = document.getElementById('filhas');
if (fls != undefined){
var flsList = fls.getElementsByTagName('UL');
for (var i=0; i < flsList.length; i++){
if (flsList[i].className == 'third-nav'){
nd = flsList[i].childNodes;
for (var j=0; j < nd.length; j++){
if(nd[j].nodeName == "LI"){
var link = nd[j].firstChild;
link.setAttribute('onclick', 'return teste()');
}
}
}
}
}
}

function teste(){
alert(2);
return false;
}

addEvent(window, 'click', makeThirdLinks, true);

Para essa ultima chamada, tentei, mas nao funcionou:

addEvent(window, 'change', makeThirdLinks, true);


ou seja, aqui eu não consegui fazer:

link.onclick = function{};

mas isso funcionou:

link.setAttribute('onclick', 'return teste()');

O que é uma inversao doida no MVC. É um codigo MVC gerando um não MVC.

--
Antonio Jozzolino
-------------------------------------------
SOLUÇÃO GRÁFICA DESIGN
Graphic Design Illustration Web Development
Website : http://www.sgd.com.br
Resume : http://tinyurl.com/dt27l
RSS : http://feeds.feedburner.com/sgd
Orkut : http://tinyurl.com/39eybw
Via6 : http://tinyurl.com/2wyxt6
-------------------------------------------

Rafael Mendes H. Perez

unread,
Aug 17, 2007, 12:09:22 PM8/17/07
to ar...@googlegroups.com
Callback nada mais é que uma função que é executada quando um
determinado processo é completado, como o handler de um onload, por
exemplo. Então o exemplo dado poderia ser chamado de callback sim.

Aproveitando a nomenclatura que você usou no seu exemplo, a solução que
propus anteriormente seria basicamente a seguinte.

main.addEventListener('click',cmdDispatcher); // a função cmdDispatcher
vai pegar todos os cliques dentro do div main
var Users={
'delete': function (el) {

},
'add': function(el) {

}
}

var evtMap={
'delUser': Users.delete,
'addUser': Users.add
....
}

function cmdDispatcher(ev){
var ev=ev || window.event,
el= ev.target || ev.srcElement;

if (evtMap(el.id)) // se o id do item clicado estiver no evtMap, ele
executa a respectiva função. Se não, não faz nada
evtMap[el.id](el);
}


Claro que ao invés de comparar o id, você pode comparar a classe ou
mesmo a tagName. Ou pode fazer um mini-parser de CSS e popular a evtMap
com propriedades tipo "a.delUserLink".

[]s
Rafael

Reply all
Reply to author
Forward
0 new messages