Element event created after DOM loading

Asked

Viewed 495 times

0

Next: I have a page where requests will be made. On this page, the user chooses the item and can, if desired, add extra items to this item, for example "more cheese". When I insert this "more cheese", I create a row with two extra items in the table. The first contains the description of the extra item and the second a button will delete this item if necessary. Problem: If I enter more than one item, the event is triggered by passing as parameters the last item inserted.

                    id = gera_id(itemExtra[0].replace(' ', '')); // Função para não existir duplicidade de ids
                var table       = document.getElementById(tabela);
                var n_rows      = document.getElementById(tabela).rows.length;
                var row         = table.insertRow(n_rows);
                row.id          = id;
                var cell1       = row.insertCell(0);
                var cell2       = row.insertCell(1);
                cell1.innerHTML = itemExtra[1];

                var deletaExtra = document.createElement("INPUT");
                deletaExtra.setAttribute("type", "button");
            /*
                deletaExtra.onclick = function (){
                    deletaItemExtra(id, tabela);
                }
            */
                var parametros = ""+id + "," + tabela+"";
                deletaExtra.addEventListener("click", function(){
                    deletaItemExtra(id, tabela);
                });

                deletaExtra.setAttribute("value", 'X');
                cell2.appendChild(deletaExtra);

If necessary, follow the link to the full page. http://siclopadm.com.br/sc/9/app/siclop/wbl_vendas/

  • Where the declaration of id ?

  • Right after the creation of Row. Fifth line in the code snippet

1 answer

1

Version with pure Javascript:

First we create this small function that will separate the classes of the element individually if it has multiple classes using the .split(), then using the .indexOf() We advise you to start searching for the class name with the index of -1, which is basically checking for something that is not yet in this group.

Has Class?

function temClasse(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

Then we will control what happens in the event click.
In the first example I posted, I had pointed the click to the document but now corrected pointing it to the element Parent which is best practice because then we are not checking for clicks on the document but on the target element which is what interests us.

When a click occurs on the element Parent, which in this case will be the class .container, we will check with the if whether this click was on the target element (target) with class el-alvo or not, together with this same if we will run the function temClass to search for new elements indexOf() > -1.

Clicked on target element?

var container = document.querySelector('.container');
container.addEventListener('click', function (e) {
    if (temClasse(e.target, 'el-alvo')) {
        alert(e.target.id);
    }
});

Recap this part, whenever a click occurs on .container, => if/if this click was an element child with class .el-alvo together also checks whether there are new elements => does something.

Example:

var container = document.querySelector('.container');

// Código abaixo não interessa. Apenas para criar novos elementos
document.getElementById('add-el').addEventListener('click', function() {
    var el = document.createElement('li');
    var id = Math.floor(Math.random() * 2000);
    el.id = id;
    el.className = 'el-alvo';
    el.innerHTML = id;
    container.appendChild(el);
});

function temClasse(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}
container.addEventListener('click', function (e) {
    if (temClasse(e.target, 'el-alvo')) {
        alert(e.target.id);
    }
});
.container li {
  padding: 5px;
  background-color: #fff;
  color: #000;
}

.container li:nth-child(odd) {
  background-color: #eee;
}
<ul class="container">
    <li id="primeiro" class="el-alvo">primeiro</li>
    <li id="segundo" class="el-alvo">segundo</li>
    <li id="terceiro" class="el-alvo">terceiro</li>
</ul>
<button id="add-el" type="button">
Add li
</button>

More about the split() here: w3schools - split() Method
More about the indexOf() here: w3schools - index() Method

Version jQuery would be something like:

With jQuery it would be something shorter as in this example below:

// Código abaixo não interessa. Apenas para criar novos elementos
document.getElementById('add-el').addEventListener('click', function() {
    var el = document.createElement('li');
    el.className = "el-alvo";
    var id = Math.floor(Math.random() * 2000);
    el.id = id;
    el.innerHTML = id;
    document.querySelector('.container').appendChild(el);
});

// com jQuery
$('.container').on('click', '.el-alvo', function(e) {
    alert(e.target.id);
});
.container li {
  padding: 5px;
  background-color: #fff;
  color: #000;
}

.container li:nth-child(odd) {
  background-color: #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<ul class="container">
    <li id="first" class="el-alvo">first</li>
    <li id="second" class="el-alvo">second</li>
    <li id="third" class="el-alvo">third</li>
</ul>
<button id="add-el" type="button">
Add li
</button>

  • I think the answer lacks explanations, mainly to assign the event to the document and then check the target.

  • Hello @Chun. Thank you so much for your help. It worked right. Now I need to adjust my need. A question: This action will be triggered every time a click is performed, right? It causes some performance problem?

  • @Matheusdelatorrre I improved my answer in the event click pointing only to the target element instead of the whole document, so the iterations will only be made when the specific element is clicked and not the whole document that would be a constant check.

  • thanks for the feedback @Andersoncarloswoss , also made me realize that the event click could be improved =)

  • 1

    Thanks @Chun. now it’s clearer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.