Chris M
Chris M

Reputation: 1

How to add a one click statement to an event delegated function?

I've added an event listener via event bubbling to a parent element. On click, the function duplicates the source and inserts the clone after the source. After the source is cloned, I don't want it to be triggered again. What is the best way to accomplish this?

<script>
// declare handler
function clickHandler(e) {
  if (e.target.matches('.list__item') || 
      e.target.matches('.list__item *')) {
        console.log(e.target.innerHTML);
        
        const child = document.getElementById(e.target.id);
        console.log(child.id)
        
        //Get source element
        const source = child.closest('.list__item');
        console.log(source);

        // Create clone
        var clone = source.cloneNode(true);
        console.log(clone)

        // Update clone ID
        clone.id = 'elem2';
        console.log(clone.id)

        // Inject clone into the DOM
        source.after(clone);     
  }
}

// reference to list
const list = document.querySelector('.list');

// add a single listener to list
list.addEventListener('click', clickHandler);

</script>

I haven't found a solution that addresses functions called via event bubbling.

Upvotes: 0

Views: 26

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371193

It sounds like each list__item has an ID. One approach would be, whenever an element is duplicated, add that ID to a Set, and check that the ID isn't in the Set before duplicating.

Because duplicate IDs in the same document is invalid HTML, consider using something else to indicate the uniqueness of an element - such as a data attribute.

const dupeIdsAdded = new Set();
function clickHandler(e) {
  if (!e.target.matches('.list__item') &&
    !e.target.matches('.list__item *')) {
    return;
  }
  const li = e.target.closest('.list__item');
  const { id } = e.target.dataset;
  if (dupeIdsAdded.has(id)) return;
  dupeIdsAdded.add(id);
  const clone = li.cloneNode(true);
  li.after(clone);
}

document.querySelector('.list').addEventListener('click', clickHandler);
<ul class="list">
  <li class="list__item" data-id="x">one</li>
  <li class="list__item" data-id="y">two</li>
</ul>

Upvotes: 2

Related Questions