frameable / el

Minimal JavaScript application framework / WebComponents base class
MIT License
249 stars 10 forks source link

event fire bug #8

Closed image72 closed 9 months ago

image72 commented 9 months ago

input onchange event fire only on press enter, and inner debounce callback never execute.

handleChange(ev) {
  console.log(ev.target.value);
  debounce(() => {
    console.log(ev.target.value);
  }, 100)
}
render(html) {
  return html`<input onchange=${(ev) => this.handleChange(ev)} />`
}

const debounce = (func, delay, { leading } = {}) => {
  let timerId;
  return (...args) => {
    if (!timerId && leading) {
      func(...args);
    }
    clearTimeout(timerId);
    timerId = setTimeout(() => func(...args), delay);
  };
};
TobiasNickel commented 9 months ago

there are a few issues. some with your example. good is that all that you want to achieve is possible with 'el'.

  <script>
    const debounce = (func, delay, { leading } = {}) => {
      let timerId;
      return (...args) => {
        if (!timerId && leading) {
          func(...args);
        }
        clearTimeout(timerId);
        timerId = setTimeout(() => func(...args), delay);
      };
    };

    class MyElement extends El {
      handleChange=debounce((ev) => {
        console.log(ev);
      },2000);
      render(html) {
        return html`<input onkeyup=${this.handleChange} />`
      }
    }
    customElements.define('my-element',MyElement);
  </script>
</head>
<body>
  <h1>the input:</h1>
  <my-element></my-element>
</body>
  1. the way debounce was used was not right. you created new debouced functions, but those have never been executed. I changed it to so that the class method is directly debounced. I was thinking if I use debounce in the render method, but it might also create to many versions. maybe the place I used is also not perfect, but the libraries mount life cycle method need to be used.
  2. on the timing of 'onchange' this library can not change anything. I think you want to use onkeyup. if fires on every keystroken when writing and the input has already the new value.
  3. I found one more issue, that the event.tarted or srcTarget can not be used. they are ether null or the web component. I believe the solution is to use ref feature as described in the readme. Here I am not sure if this library should update the currentTarget of the event, but anyway,... you have a way to work with it.

I hope this helps, good luck 😃

image72 commented 9 months ago

there are a few issues. some with your example. good is that all that you want to achieve is possible with 'el'.

  <script>
    const debounce = (func, delay, { leading } = {}) => {
      let timerId;
      return (...args) => {
        if (!timerId && leading) {
          func(...args);
        }
        clearTimeout(timerId);
        timerId = setTimeout(() => func(...args), delay);
      };
    };

    class MyElement extends El {
      handleChange=debounce((ev) => {
        console.log(ev);
      },2000);
      render(html) {
        return html`<input onkeyup=${this.handleChange} />`
      }
    }
    customElements.define('my-element',MyElement);
  </script>
</head>
<body>
  <h1>the input:</h1>
  <my-element></my-element>
</body>
  1. the way debounce was used was not right. you created new debouced functions, but those have never been executed. I changed it to so that the class method is directly debounced. I was thinking if I use debounce in the render method, but it might also create to many versions. maybe the place I used is also not perfect, but the libraries mount life cycle method need to be used.
  2. on the timing of 'onchange' this library can not change anything. I think you want to use onkeyup. if fires on every keystroken when writing and the input has already the new value.
  3. I found one more issue, that the event.tarted or srcTarget can not be used. they are ether null or the web component. I believe the solution is to use ref feature as described in the readme. Here I am not sure if this library should update the currentTarget of the event, but anyway,... you have a way to work with it.

I hope this helps, good luck 😃

thanks for your reply, I will try it later.