-
Notifications
You must be signed in to change notification settings - Fork 959
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ensure that events are always sent on blur, but this time correctly #3097
Ensure that events are always sent on blur, but this time correctly #3097
Conversation
Relates to: phoenixframework#3033 Relates to: phoenixframework#2318 Fixes: phoenixframework#3076 The old "fix" from phoenixframework#3033 had a fatal flaw because it would call an old callback on blur. This new commit adjusts the behavior to properly use the correct callback by hooking into the cycle logic and ignoring the throttle in case of blur, leaving the rest of the logic nearly untouched. This requires us to clear the throttle timeout though, because otherwise we would call the callback again after a blur, or multiple times when new events happen after blur but before the next throttle timeout triggers. The debounce/throttle code is not that easy to understand, but this time I'm more confident that the solution is actually correct. (famous last words)
When throttling events, the last event was discarded, but this is not what I would expect from a throttled event. Throttling an input should ensure that it is only emitted at most every `delay` milliseconds, but it should always emit the last event after the delay has passed. This change ensures that the last event is always emitted when throttling. This of course means that events that are emitted shortly after the last throttled event will still be emmitted immeditately, basically starting a new throttle window.
So, I actually added another change that ensures that the last event is always emitted, even when throttling. Currently we discard the event when the throttle timeout expires which causes weird behavior when using inputs like a slider, because the slider position does not reflect the value on the server as the last event is never emitted. When blurring the input after the last throttle expired we also would not send the event, because the trigger function was already reset. Let me know if this makes sense. |
❤️❤️❤️🐥🔥 |
Relates to: phoenixframework#3097 So, in phoenixframework#3097 I changed the throttle behavior to also dispatch an event after the throttle time has passed to make sure that the last event is dispatched. However, this caused the event to be dispatched twice in the case that there was only one event in the first place. This fixes that, although the throttle code is still a bit of a mess and should probably be refactored completely at some point.
Relates to: phoenixframework#3097 Relates to: phoenixframework#3033 Relates to: phoenixframework#2318 Relates to: phoenixframework#3076 This reverts the changes made in phoenixframework#3097 and phoenixframework#3033. It adds one small change to the original behavior to clear the throttle timeout on blur. For cases where the user wants to get the latest value on blur when throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the way to go: ``` <input name="tick_frequency" type="range" min="100" max="1000" value={@tick_frequency} phx-throttle="2000" phx-change="change-tick-frequency" phx-blur={JS.dispatch("change")} /> ```
Relates to: phoenixframework#3097 Relates to: phoenixframework#3033 Relates to: phoenixframework#2318 Relates to: phoenixframework#3076 This reverts the changes made in phoenixframework#3097 and phoenixframework#3033. It adds one small change to the original behavior to clear the throttle timeout on blur. For cases where the user wants to get the latest value on blur when throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the way to go: ``` <input name="tick_frequency" type="range" min="100" max="1000" value={@tick_frequency} phx-throttle="2000" phx-change="change-tick-frequency" phx-blur={JS.dispatch("change")} /> ```
Relates to: phoenixframework#3097 Relates to: phoenixframework#3033 Relates to: phoenixframework#2318 Relates to: phoenixframework#3076 This reverts the changes made in phoenixframework#3097 and phoenixframework#3033. It adds one small change to the original behavior to clear the throttle timeout on blur. For cases where the user wants to get the latest value on blur when throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the way to go: ``` <input name="tick_frequency" type="range" min="100" max="1000" value={@tick_frequency} phx-throttle="2000" phx-change="change-tick-frequency" phx-blur={JS.dispatch("change")} /> ```
Relates to: phoenixframework#3097 Relates to: phoenixframework#3033 Relates to: phoenixframework#2318 Relates to: phoenixframework#3076 This reverts the changes made in phoenixframework#3097 and phoenixframework#3033. It adds one small change to the original behavior to clear the throttle timeout on blur. For cases where the user wants to get the latest value on blur when throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the way to go: ``` <input name="tick_frequency" type="range" min="100" max="1000" value={@tick_frequency} phx-throttle="2000" phx-change="change-tick-frequency" phx-blur={JS.dispatch("change")} /> ```
Relates to: #3097 Relates to: #3033 Relates to: #2318 Relates to: #3076 This reverts the changes made in #3097 and #3033. It adds one small change to the original behavior to clear the throttle timeout on blur. For cases where the user wants to get the latest value on blur when throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the way to go: ``` <input name="tick_frequency" type="range" min="100" max="1000" value={@tick_frequency} phx-throttle="2000" phx-change="change-tick-frequency" phx-blur={JS.dispatch("change")} /> ```
Relates to: #3033
Relates to: #2318
Fixes: #3076
The old "fix" from #3033 had a fatal flaw because it would call an old callback on blur.
This new commit adjusts the behavior to properly use the correct callback by hooking into the cycle logic and ignoring the throttle in case of blur, leaving the rest of the logic nearly untouched. This requires us to clear the throttle timeout though, because otherwise we would call the callback again after a blur, or multiple times when new events happen after blur but before the next throttle timeout triggers.
The debounce/throttle code is not that easy to understand, but this time I'm more confident that the solution is actually correct. (famous last words)