Evento click() funciona apenas uma vez

278 views
Skip to first unread message

Bernardo Trevizan

unread,
Jan 4, 2014, 5:35:55 PM1/4/14
to jque...@googlegroups.com
Olá, estou desenvolvendo um calendário em PHP. Fiz uma função que gera um mês desse calendário e em JS fiz um script para quando a pessoa clicar no botão "Próximo Mês", o mês que estiver aparecendo é removido e então é carregado o mês seguinte. Eu faço isso usando um .remove() e o .append(), em que o parâmetro do .append() é uma página em php e essa página chama a função para gerar o novo mês. Quando eu clico uma vez funciona normal, mas na segunda vez não roda o script. Procurei em várias sites para ver se alguém tinha um problema parecido, porém não achei. Já tentei usar o .on("click"), o .live("click"), mudar o ID de cada botão e nada funcionou

Código HTML que a função gera para aparecer o calendário:

            <div id="calendario">
                <table border="1">
                    <tbody>
                        <tr>
                            <td colspan="7" data-ano="2014" data-mes="01" id="theadCalendario">
                                <a id="prevmes" href="#">Mês Anterior</a>
                                Janeiro 2014
                                <a id="nextmes" href="#">Próximo Mês</a>
                            </td>
                        </tr>
                        <tr>
                            <td id="domingo">D</td>
                            <td id="segunda">S</td>
                            <td id="terca">T</td>
                            <td id="quarta">Q</td>
                            <td id="quinta">Q</td>
                            <td id="sexta">S</td>
                            <td id="sabado">S</td>
                        </tr>
                        <tr>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td>1</td>
                            <td>2</td>
                            <td>3</td>
                            <td><b>4</b></td>
                        </tr>
                        <tr>
                            <td>5</td>
                            <td>6</td>
                            <td>7</td>
                            <td>8</td>
                            <td>9</td>
                            <td>10</td>
                            <td>11</td>
                        </tr>
                        <tr>
                            <td>12</td>
                            <td>13</td>
                            <td>14</td>
                            <td>15</td>
                            <td>16</td>
                            <td>17</td>
                            <td>18</td>
                        </tr>
                        <tr>
                            <td>19</td>
                            <td>20</td>
                            <td>21</td>
                            <td>22</td>
                            <td>23</td>
                            <td>24</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>26</td>
                            <td>27</td>
                            <td>28</td>
                            <td>29</td>
                            <td>30</td>
                            <td>31</td>
                        </tr>
                    </tbody>
                </table>
            </div>

Código da página "calendario.php":

<?php
require_once 'CalendarioBO.php';

$mes = $_GET['mes'];
$ano = $_GET['ano'];

CalendarioBO::GerarMes($mes, $ano);
?>

O script que eu estou utilizando:


 $("#nextmes").click(function(e) {

        e.preventDefault();

        var mes = parseInt($('#theadCalendario').attr('data-mes'));
        var ano = parseInt($('#theadCalendario').attr('data-ano'));

        var nextMes = 0;
        var nextAno = 0;

        if (mes < 12) {
            nextMes = mes + 1;
            nextAno = ano;
        } else if (mes == 12) {
            nextMes = 1;
            nextAno = ano + 1;
        }

        $('#calendario').remove();
        $('#calendario-content').load('Views/perfil/calendario.php?mes=' + nextMes + '&ano=' + nextAno);
       
    })


Atenciosamente,
Bernardo Trevizan

Leocaminha

unread,
Jan 4, 2014, 8:33:09 PM1/4/14
to jque...@googlegroups.com
Da uma olhadinha no evento delegate, passei por algo similar e ele resolveu

Sent from my iPhone
--
--
Grupo de jQuery Brasil.
 
REGRAS: https://docs.google.com/document/d/1VfvTDmeHTSj-L5ouZJjQQ4OkjTCU1Hr2XtPYBNGVHH4/edit
 
USE O JSBIN.COM / JSFIDDLE.NET PARA CÓDIGOS.
 
Email: jque...@googlegroups.com
Biba: jquery-br+...@googlegroups.com
Site: http://groups.google.com/group/jquery-br?hl=pt-BR
 
---
Você está recebendo esta mensagem porque se inscreveu no grupo "jQuery (Brasil)" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para jquery-br+...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.

Bernardo Trevizan

unread,
Jan 4, 2014, 10:01:58 PM1/4/14
to jque...@googlegroups.com
O .delegate() não funcionou também, mas me ajudou a perceber que o script parava por causa do .load() que eu tava usando. Dei uma pesquisada e vi que o .load() realoca os elementos na DOM e por isso o evento não funcionava na segunda vez. Então coloquei o script dentro do arquivo que estava sendo chamado no .load(). Agora, toda vez que carrega um novo mês no calendário, carrega também o script e deu certo. O problema é que essa "manobra" ficou um gambearra e talvez demora um pouco mais para carregar a página, mas já tentei de tudo e isso foi a única coisa que funcionou. Obrigado pela dica, espero retribuir algum dia.

Atenciosamente,
Bernardo Trevizan

Rodrigo Sclosa

unread,
Jan 6, 2014, 6:21:07 AM1/6/14
to jque...@googlegroups.com
Não faltou isso não?

$(document).ready(function() { 
     -> Seu script aqui dentro....
});

[]'s
Rodrigo.

Saulo Brito

unread,
Jan 6, 2014, 11:26:51 AM1/6/14
to jque...@googlegroups.com
Talvez você não esteja usando o .on da forma incorreta.

1- Coloque o script na página PAI, ou seja, fora do da div que é recarregada com .load;

2- Use .on('click', #nextmes ...

3- Veja se funcionou =)

4- Estude a diferença entre .click, .on e o antigo .live;

Valeu
Saulo Brito



Bernardo Trevizan

unread,
Jan 6, 2014, 10:09:43 PM1/6/14
to jque...@googlegroups.com
Rodrigo, eu tenho o script dentro do

$(document).ready(function() {});

Saulo, eu sempre referencio os scripts no <head> do index, então, tecnicamente, já está na página pai e já testei com o .on(). Porém ainda não funciona, estou tentando um método com AJAX agora, vamos ver se vai dar certo.

Douglas Bezerra Possas

unread,
Jan 7, 2014, 6:23:12 AM1/7/14
to jque...@googlegroups.com
Qual a versão do jQuery?!


--
--
Grupo de jQuery Brasil.
 
REGRAS: https://docs.google.com/document/d/1VfvTDmeHTSj-L5ouZJjQQ4OkjTCU1Hr2XtPYBNGVHH4/edit
 
USE O JSBIN.COM / JSFIDDLE.NET PARA CÓDIGOS.
 
Email: jque...@googlegroups.com
Biba: jquery-br+...@googlegroups.com
Site: http://groups.google.com/group/jquery-br?hl=pt-BR
 
---
Você está recebendo esta mensagem porque se inscreveu no grupo "jQuery (Brasil)" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para jquery-br+...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.



--
Douglas Bezerra Possas
Programador PHP
Campo Grande  – MS – Brasil
Cel.: 67 9280 5866

GitHub
https://github.com/douglaspossas/

Márcio Passos

unread,
Jan 7, 2014, 1:24:25 PM1/7/14
to jque...@googlegroups.com
Olá,

Pra mim funcionou assim.. usando ajax/load...


$("#btnAdicionar").on("click", function(e){
e.preventDefault();
$('.wrapper').load("http://citador.marciopassos.com/index.php/citacao/criar div.content").fadeIn('slow');
});




2014/1/7 Douglas Bezerra Possas <dougla...@gmail.com>

Márcio Passos

unread,
Jan 7, 2014, 1:31:05 PM1/7/14
to jque...@googlegroups.com
E pra elementos criados e destruidos via ajax, etc... usando delegate no body funcionou legal pra mim também.

$("body").delegate('#desFavoritar', "click", function(e) {
 // ....
});


2014/1/7 Márcio Passos <marciop...@gmail.com>

Bernardo Trevizan

unread,
Jan 8, 2014, 11:08:16 AM1/8/14
to jque...@googlegroups.com
Douglas, a versão é 1.10.3... Márcio, eu estava usando o .load(), o problema é que eu tenho uma função que gera o mês com os botões de passar para o próximo mês e voltar um mês. Esses botões são gerados na função então os elementos estão sendo carregados depois da DOM e apesar de eu estar usando o .delegate() por causa disso, eles continuam sem funcionar. Eu acho que o jeito vai ser fazer os botões separados da função do calendário.

Douglas Bezerra Possas

unread,
Jan 8, 2014, 11:46:17 AM1/8/14
to jque...@googlegroups.com
Use o .on, algo como 
$(function(){
 $('body').on('#id_elemento').click(function(){
  console.log('clicou');
 });
});


--
--
Grupo de jQuery Brasil.
 
REGRAS: https://docs.google.com/document/d/1VfvTDmeHTSj-L5ouZJjQQ4OkjTCU1Hr2XtPYBNGVHH4/edit
 
USE O JSBIN.COM / JSFIDDLE.NET PARA CÓDIGOS.
 
Email: jque...@googlegroups.com
Biba: jquery-br+...@googlegroups.com
Site: http://groups.google.com/group/jquery-br?hl=pt-BR
 
---
Você está recebendo esta mensagem porque se inscreveu no grupo "jQuery (Brasil)" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para jquery-br+...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.

Eduardo Kraus

unread,
Jan 8, 2014, 3:08:31 PM1/8/14
to jquery-br
Este é o primeiro dos erros que as pessoas cometem quando começam com o jQuery.

Quando você chama o "$("#nextmes").click(function(e) " ele adiciona uma escuta no elemento #nextmes. Porém quando um clique acontece você altera todo o conteúdo do #calendario por um novo HTML e o #nextmes passou a ser um outro elemento que não mais o DOM anterior.

Então, sempre que um elemento for substituido, a referencia a ele é alterada, visto que o ID é o mesmo, mais o ID do DOM não é mais o mesmo.....

Então, para resolver é muiiiiito simples....

$("#nextmes").click( clickNextMes );

function clickNextMes(event) {
    event.preventDefault();

    var mes = parseInt($('#theadCalendario').attr('data-mes'));
    var ano = parseInt($('#theadCalendario').attr('data-ano'));

    var nextMes = 0;
    var nextAno = 0;

    if (mes < 12) {
        nextMes = mes + 1;
        nextAno = ano;
    } else if (mes == 12) {
        nextMes = 1;
        nextAno = ano + 1;
    }

    $('#calendario').remove();
    $('#calendario-content').load('Views/perfil/calendario.php?mes=' + nextMes + '&ano=' + nextAno);

    $("#nextmes").click( clickNextMes );
})

O que eu fiz, foi re-adicionar a escuta ao #nextmes quando o DOM é alterado.

Um abraço para você Obama



Douglas Bezerra Possas

unread,
Jan 8, 2014, 3:35:42 PM1/8/14
to jque...@googlegroups.com
@Eduardo, eu não faria da maneira que você falou, mas sim usando on/delegate/live etc... Só tem que lembrar que precisa setar eles com um elemento pai que não irá mudar em nenhum momento.

Wagner Silva

unread,
Jan 8, 2014, 4:40:35 PM1/8/14
to jque...@googlegroups.com
Eu acho que ele deveria manipular a div calendário com o $('#calendario').on('click','#nextmes',function(){ //codificar });

Bernardo Trevizan

unread,
Jan 9, 2014, 5:08:37 PM1/9/14
to jque...@googlegroups.com
Deu certo, usei o delegate... O que estava faltando era eu colocar um elemento que não mudava nunca, ou seja, o body. Por exempo: $('body').delegate('#id', 'click');... Muito obrigado pela ajuda pessoal!

Eduardo Kraus

unread,
Jan 9, 2014, 9:55:21 PM1/9/14
to jquery-br
Vivendo e aprendendo. Obrigado pela dica.

Um abraço para você Obama



Márcio Passos

unread,
Jan 10, 2014, 12:06:39 PM1/10/14
to jque...@googlegroups.com
isso ai =)



2014/1/9 Eduardo Kraus <eduard...@gmail.com>
Reply all
Reply to author
Forward
0 new messages