cferdinandi / reef

A lightweight library for creating reactive, state-based components and UI.

Home Page:https://reefjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Working with Events Questions

mouse0270 opened this issue · comments

Alright, this might be tough to explain, but its a difference in v12 to previous versions. In previous versions, you could pass in listeners that would get attached to the elements. In v12 It appears that our option for events just allows or disallow on attributes during the creation of the template.

Alright not too big of a problem except I seem to run into some issues. In the example, you will notice that it creates two buttons, the first calling a Global function and the second calling a function within the Class. For some reason that breaks, I am not really sure why. In my use case, this doesn't work either way, because the class isn't exposed meaning the items can never tall TASBAR.onClick() as they don't know it exists by the time they are created. At least that's my understanding of it.

So JavaScript doesn't have an on like jquery so I have to use addEventListener. Looking through your documentation I noticed that I could just attach events when reef:render is called, but that comes with its own host of issues. Because it basically will just keep adding the event over and over and over again. In the example you'll notice that the two items onclick events error when they are clicked. Clicking on the dice icon adds another element and this one does not error and properly calls the class function.

Am I doing something wrong, or do I have to attach events via reef:render?

Example: https://codepen.io/mouse0270/pen/vYrNEjM?editors=0011

Hi @mouse0270, so... it's all about scope.

The Class needs to be in the global scope to call it form an on* event on the element. As an alternative to on events, you can use event delegation without having to wait for the render to happen.

If you are going to attach events directly to the rendered elements, I would use reef:start as your event hook if they're not going to be removed from the UI later.

Its a module, it doesn't get defined on the global scope. Which is fine, I was just trying to provide an example of why passing in events used to be a very nice feature.

Also, event delegation is great, and you did a fantastic job writing that article, it might be best to update it. Though it does a great job at explaining how to use event delegation in pure vanilla JS, it leaves out the fact that it won't work on any element that has children in it.

<button class="click-me" id="click-me-1">Click Me</button>
<button class="click-me" id="click-me-2"><span>Click Me</span></button>

<script>
// Listen for click events
document.addEventListener('click', function (event) {
  if (!(event.target.matches('.click-me'))) return;
  
  console.log('An element was brought into focus.');
  console.log(event.target);
});
</script>

In this example, you'll find that the second button never triggers the click event unless you click on the very edge of the button because javascript has registered that the span is the target element.

changing the script to something like

// Listen for click events
document.addEventListener('click', function (event) {
  if (!(event.target.closest('.click-me'))) return;
  const element = event.target.closest('.click-me')
  
  console.log('An element was brought into focus.');
  console.log(element );
});

I know this was off-topic, but it was a really well written article and figured it would be a nice addition to include some of the limitations of event delegations and how to get around them.