์ผ€์ด์Šค ce-0312-chrome-android-focus-blur-input-en-ko ยท ์‹œ๋‚˜๋ฆฌ์˜ค scenario-chrome-android-focus-blur-input

Input events fire on focus/blur without content changes

OS: Android 10+ ๊ธฐ๊ธฐ: Mobile Any ๋ธŒ๋ผ์šฐ์ €: Chrome for Android 90+ ํ‚ค๋ณด๋“œ: Any ์ดˆ์•ˆ
chromeandroidmobilefocusblurinput-eventfalse-positive

Phenomenon

In Chrome on Android, input events may fire when a contenteditable element gains or loses focus, even without any actual content changes. This behavior can lead to unintended side effects in applications that rely on input events to detect content modifications.

Reproduction Steps

  1. Open Chrome browser on an Android device.
  2. Create a contenteditable element.
  3. Add an event listener for input events that logs to console.
  4. Tap on the contenteditable element to focus it.
  5. Observe the console - an input event may fire even though no content was changed.
  6. Tap outside the element to blur it.
  7. Observe the console - an input event may fire again.

Observed Behavior

  1. Input Event on Focus: An input event fires when the element gains focus, even though no content was changed.
  2. Input Event on Blur: An input event may fire when the element loses focus, even though no content was changed.
  3. False Positive Events: These events are false positives - they indicate content changes that didnโ€™t actually occur.
  4. Android-Specific: This issue is specific to Chrome on Android.

Expected Behavior

  • input events should only fire when content actually changes.
  • Focus and blur events should not trigger input events.
  • Applications should be able to rely on input events to detect actual content modifications.

Impact

  • False Positive Events: Input events fire without actual content changes.
  • Unintended Side Effects: Applications may trigger save operations, validation, or other actions unnecessarily.
  • Performance Issues: Unnecessary processing triggered by false input events.
  • User Experience: Applications may behave unexpectedly.

Browser Comparison

  • Chrome Android: This issue occurs.
  • Chrome Desktop: Not affected.
  • Firefox Android: Not affected.
  • Safari iOS: Not affected.

Notes and Possible Workarounds

Filter False Input Events

const editor = document.querySelector('[contenteditable]');
let lastContent = editor.innerHTML;
let isFocusing = false;
let isBlurring = false;

editor.addEventListener('focus', () => {
  isFocusing = true;
  lastContent = editor.innerHTML;
  
  setTimeout(() => {
    isFocusing = false;
  }, 100);
});

editor.addEventListener('blur', () => {
  isBlurring = true;
  
  setTimeout(() => {
    isBlurring = false;
  }, 100);
});

editor.addEventListener('input', (e) => {
  // Ignore input events during focus/blur
  if (isFocusing || isBlurring) {
    return;
  }
  
  // Check if content actually changed
  const currentContent = editor.innerHTML;
  if (currentContent === lastContent) {
    return;
  }
  
  lastContent = currentContent;
  handleContentChange(currentContent);
});

Use MutationObserver Instead

const editor = document.querySelector('[contenteditable]');
let isUserInput = false;

editor.addEventListener('beforeinput', () => {
  isUserInput = true;
});

editor.addEventListener('input', () => {
  isUserInput = false;
});

const observer = new MutationObserver((mutations) => {
  if (isUserInput) {
    handleContentChange(editor.innerHTML);
  }
});

observer.observe(editor, {
  childList: true,
  subtree: true,
  characterData: true
});

References

Playground for this case

Use the reported environment as a reference and record what happens in your environment while interacting with the editable area.

Reported environment
OS: Android 10+
Device: Mobile Any
Browser: Chrome for Android 90+
Keyboard: Any
Your environment
Sample HTML:
Event log
Use this log together with the case description when filing or updating an issue.
0 events
Interact with the editable area to see events here.