Function js is executed several times

1

Hello, I'm developing a football betting app which features a table with quotes values of different game modes for each registered game. For each match I have a table with the following code:

<div id="partida_1" class="panel-heading-margin">
<table id="jogo_1" onclick="getTableClick()" class="w3-table-all w3-card-4 myTable" data-id="1" data-horario="05-05-2017 12:00:00" data-jogo="Barcelona X Real Madrid">
    <thead>
        <tr id="infopartida_1" class="w3-dark-grey">
            <th colspan="20">
                <small>Barcelona X Real Madrid</small>
                <span class="pull-right"><small>05-05-2017 12:00:00&nbsp; </small> <button id="removejogo_1" class="btn btn-danger btn-xs pull-right hidden" onclick="removeJogo(1)" ><span class="fa fa-close"></span></button></span>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td data-key="jogo_1_1" data-valorcotacao="1.4" data-nomecotacao="Casa" class="cotacao" style="text-align: center" width="200">Casa <br> <strong>1.4</strong></td>
            <td data-key="jogo_1_2" data-valorcotacao="1.2" data-nomecotacao="Empate" class="cotacao" style="text-align: center" width="200">Empate <br> <strong>1.2</strong></td>
            <td data-key="jogo_1_3" data-valorcotacao="1.1" data-nomecotacao="Fora" class="cotacao" style="text-align: center" width="200">Fora <br> <strong>1.1</strong></td>
        </tr>
        <tr>
            <td data-key="jogo_1_4" data-valorcotacao="2.1" data-nomecotacao="Ambas" class="cotacao" style="text-align: center" width="200">Ambas <br> <strong>2.1</strong></td>
            <td data-key="jogo_1_5" data-valorcotacao="5.4" data-nomecotacao="+2.5GM" class="cotacao" style="text-align: center" width="200">+2.5GM <br> <strong>5.4</strong></td>
            <td data-key="jogo_1_6" data-valorcotacao="2.1" data-nomecotacao="-2.5GM" class="cotacao" style="text-align: center" width="200">-2.5GM <br> <strong>2.1</strong></td>
        </tr>
        <tr>
            <td data-key="jogo_1_7" data-valorcotacao="2.1" data-nomecotacao="1.5GM" class="cotacao" style="text-align: center" width="200">1.5GM <br> <strong>2.1</strong></td>
            <td data-key="jogo_1_8" data-valorcotacao="2.1" data-nomecotacao="Casa ou Empate" class="cotacao" style="text-align: center" width="200">Casa ou Empate <br> <strong>2.1</strong></td>
            <td data-key="jogo_1_9" data-valorcotacao="2.1" data-nomecotacao="Fora ou Empate" class="cotacao" style="text-align: center" width="200">Fora ou Empate<br> <strong>2.1</strong></td>
        </tr>
        <tr>
            <td data-key="jogo_1_10" data-valorcotacao="1.23" data-nomecotacao="C. Marca" class="cotacao" style="text-align: center" width="200">C. Marca <br> <strong>1.23</strong></td>
            <td data-key="jogo_1_11" data-valorcotacao="1.23" data-nomecotacao="F. Marca" class="cotacao" style="text-align: center" width="200">F. Marca <br> <strong>1.23</strong></td>
            <td data-key="jogo_1_12" data-valorcotacao="1.23" data-nomecotacao="Casa ou Fora" class="cotacao" style="text-align: center" width="200">Casa ou Fora <br> <strong>1.23</strong></td>
        </tr>
        <tr>
            <td data-key="jogo_1_13" data-valorcotacao="1.45" data-nomecotacao="C. Vence F. Marca" class="cotacao" style="text-align: center" width="200">C. Venc. F. Marca <br> <strong>1.45</strong></td>
            <td data-key="jogo_1_14" data-valorcotacao="1.45" data-nomecotacao="F. Vence C. Marca" class="cotacao" style="text-align: center" width="200">F. Venc. C. Marca <br> <strong>1.45</strong></td>
            <td data-key="jogo_1_15" data-valorcotacao="1.45" data-nomecotacao="C. Venc. Zero" class="cotacao" style="text-align: center" width="200">C. Venc. Zero <br> <strong>1.45</strong></td>
        </tr>
        <tr>
            <td data-key="jogo_1_16" data-valorcotacao="1.1" data-nomecotacao="F. Venc. Zero" class="cotacao" style="text-align: center" width="200">F. Venc. Zero <br> <strong>1.1</strong></td>
        </tr>
    </tbody>                                       
</table>

And I have the following function to receive the clicks from the table:

function getTableClick(){
$('.myTable tbody tr td').click(function () {
    //Valores passados pelo click na tabela
    var jogoId = $(this).closest('table').data('id');
    var cotacao = $(this).data('nomecotacao');
    var partida = $(this).closest('table').data('jogo');
    var valorCotacao = $(this).data('valorcotacao');

    $(this).addClass('selected-cell');
    $(this).parents('tbody').find('td').not(this).removeClass('selected-cell');
    $('#removejogo_' + jogoId).removeClass('hidden');
    $('#parcialApostas').removeClass('hidden');
    $('#infopartida_' + jogoId).removeClass('w3-dark-grey');
    $('#infopartida_' + jogoId).addClass('w3-green');            

    //Teste
    alert(cotacao + ': ' + valorCotacao);

    //Inclui o jogo clicado na tabela.
    /*$('#modalBody').append(
        '<tr id="tr_133" data-jogo="'+ partida +'" data-key="'+ cotacao +'" > \
            <td> \
                <p>'+ partida +'<span class="pull-right">R$'+ valorCotacao +'</span></p> \
            </td> \
        </tr>'
    );*/
});}

When the table is rendered I click on it for the first time the function is not executed, only on the second click. Also when I click again on a cell the function is executed twice, if I click again it executes three times and so on. If anyone can help me to find the error I would greatly benefit.

    
asked by anonymous 08.01.2017 / 16:12

1 answer

0

When you have HTML in <table id="jogo_1" onclick="getTableClick(this, event);" this will make the function run when there is a click on the table element or one of its descendants.

Example:

function minhaFuncao(table, evento) {
  console.log(table, evento.target);
}
table th,
table td {
  padding: 0.8em;
  border: 1px solid;
}

table th {
  background-color: #6699FF;
  font-weight: bold;
}

table th:hover,
table td:hover {
  background-color: #ddf;
  cursor: pointer;
}
<table onclick="minhaFuncao(this, event);">
  <tr>
    <th>#</th>
    <th>Coluna A</th>
    <th>Coluna B</th>
    <th>Coluna C</th>
  </tr>
  <tr>
    <td>1</td>
    <td>A 1</td>
    <td>B 1</td>
    <td>C 1</td>
  </tr>
  <tr>
    <td>2</td>
    <td>A 2</td>
    <td>B 2</td>
    <td>C 2</td>
  </tr>
</table>

Problem:

The problem you have is that every time there is a click on the table the function runs again

$('.myTable tbody tr td').click(function () {

and join multiple, multi-event headphones. You do not really need this line, because event.target already gives you what you want.

Solution:

By passing this to this function you get a pointer to the table element itself, and passing event you can read the event and remove the .target that is the element within the table that actually received the click .

I suggest you change to this:

function minhaFuncao(table, evento) {
    var td = evento.target;
    if (td.tagName.toLowerCase() != 'td') return;
    //Valores passados pelo click na tabela
    var jogoId = $(table).data('id');
    var cotacao = $(this).data('nomecotacao');
    var partida = $(table).data('jogo');
    var valorCotacao = $(this).data('valorcotacao');

    $(this).addClass('selected-cell');
    $(this).parents('tbody').find('td').not(this).removeClass('selected-cell');
    $('#removejogo_' + jogoId).removeClass('hidden');
    $('#parcialApostas').removeClass('hidden');
    $('#infopartida_' + jogoId).removeClass('w3-dark-grey');
    $('#infopartida_' + jogoId).addClass('w3-green');

    //Teste
    alert(cotacao + ': ' + valorCotacao);

    //Inclui o jogo clicado na tabela.
    /*$('#modalBody').append(
        '<tr id="tr_133" data-jogo="'+ partida +'" data-key="'+ cotacao +'" > \
            <td> \
                <p>'+ partida +'<span class="pull-right">R$'+ valorCotacao +'</span></p> \
            </td> \
        </tr>'
    );*/
}

or put $('.myTable tbody tr td').click(function () { out of function, sometime after the DOM has loaded.

    
08.01.2017 / 16:58