简体   繁体   中英

Can ResizeObserver be used to prevent Onclcik event on element

I am trying to figure out a way to detect that a TextArea is resized so i can prevent it's onClick event from being fired. Reason being that, when resizing the TextArea it also fires the onClick event. However, the onClick event handler has some logic i need to skip if it's a resize.

I tried using the ResizeObserver API to detect the resize event. However, can't seem to locate the 'event' so i can do a preventDefault on it to skip the onClick event.

Not sure if ResizeObserver can be used this way. Anyone has had this type of requirement met using REsizeObserver or any other approach?

Unfortunately there is no resize event on elements except for on the window, but I would say that this is a solid usecase to use the ResizeObserver API.

Down here I've made an attempt to build something that uses the API and creates a custom event whenever a resize has been made. Because the observer will continuously trigger on every resized pixel, I've added a debounce function in the callback. This will fire the event after 200ms of inactivity.

Then it will fire an event with the data from the resize observer which your field can listen to.

I'm not saying that you should do it like this, but it demonstrates how you could make your own resize event using this API.

 const field = document.querySelector('.field'); field.addEventListener('click', event => { event.preventDefault(); }); field.addEventListener('textarearesize', event => { console.log('Resize triggered'); const { contentRect } = event.detail; const { width, height } = contentRect; field.value = `width: ${Math.floor(width)}, height: ${Math.floor(height)}`; }); const onResizeCallback = (() => { let initial = true; let timeout; return entries => { if (initial) { initial = false; return; } clearTimeout(timeout) timeout = setTimeout(() => { for (const entry of entries) { const event = new CustomEvent('textarearesize', { detail: entry }); entry.target.dispatchEvent(event); } }, 200); } })() const observer = new ResizeObserver(onResizeCallback); observer.observe(field);
 <textarea class="field" name="description">Hello, I'm a textarea</textarea>

Alternative you could check if the field has a changed in either height or width whenever you release the mouse. This does not require a ResizeObserver and is less complex to create and has more predictable behavior than the example above.

 const field = document.querySelector('.field'); const watchField = field => { let width = field.offsetWidth; let height = field.offsetHeight; const areDimensionsChanged = (newWidth, newHeight) => width !== newWidth || height !== newHeight; field.addEventListener('mouseup', event => { const { target } = event; const { offsetWidth, offsetHeight } = target; if (areDimensionsChanged(offsetWidth, offsetHeight)) { width = offsetWidth; height = offsetHeight; const event = new CustomEvent('textarearesize'); target.dispatchEvent(event); } }); } field.addEventListener('textarearesize', event => { console.log('Resize triggered'); }); watchField(field);
 <textarea class="field" name="description">Hello, I'm a textarea</textarea>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM