Skip to Content
LaunchExt | Chrome Extension Dev Platform (Next.js + Plasmo) 🚀 Read more → 
BlogBrowser Extension Development: The Power of blur() + focus() - Refreshing Rich Text Editor State

Browser Extension Development: The Power of blur() + focus() - Refreshing Rich Text Editor State

by esx_ai

While working on Xiaohongshu automation features recently, I stumbled upon a pretty interesting code snippet:

editorEl.blur(); editorEl.focus();

At first glance, it just looks like making the editor lose focus and then regain it. What could such simple code possibly do? Let me share why this seemingly basic trick turns out to be surprisingly useful.

What’s Actually Happening Here

In simple terms, these two lines are forcing the editor to refresh its internal state.

It’s similar to when you’re using an editor manually - sometimes you need to click away and then click back to make the editor realize the content has changed. This code automates that exact behavior.

Why You’d Need This Trick

1. Making the Editor Aware of Content Changes

Xiaohongshu uses the TipTap editor, which is built on ProseMirror under the hood. This library can be a bit “slow” - when you modify content programmatically, it might not notice the changes.

// Directly setting content - editor might not react editor.innerHTML = "new content" // Lose and regain focus - editor wakes up editor.blur() editor.focus()

2. Handling Browser Compatibility Quirks

Different browsers react differently to programmatic content changes. Some are quick to update, others need a nudge. This technique ensures consistent behavior across all browsers, preventing those “it works in Chrome but not Firefox” situations.

3. Activating Editor Features

Some editor functionality depends on focus events to trigger properly:

  • Toolbar button state updates
  • Content change detection
  • Auto-save features

Without focus events, these features might just sit there doing nothing.

How We Use It in Real Projects

In our Xiaohongshu automation workflow, this technique comes in handy here:

async function fillTipTapEditor(content: string) { // First populate the content editor.innerHTML = content // Then force a state refresh editor.blur() editor.focus() // Now the editor knows content has changed }

The benefits we’ve seen:

  • Publish button correctly recognizes there’s content
  • Avoids the “content is there but editor thinks it’s empty” dilemma
  • Ensures all editor features work as expected

When This Technique Shines

From my experience, this approach is particularly useful in these scenarios:

  • Rich text editors: TipTap, ProseMirror, Quill - the complex ones
  • Programmatic content changes: When you’re setting innerHTML or textContent via code
  • Cross-browser compatibility: Making sure behavior is consistent everywhere
  • Automated testing: Simulating real user interaction flows

One Thing to Keep in Mind

While this technique is simple, it’s incredibly practical when dealing with rich text editors. Many of those head-scratching editor issues often boil down to state synchronization problems.

Next time you run into an editor that’s being “slow to respond”, give blur() followed by focus() a try - you might be surprised how often it does the trick.

If you’ve encountered similar editor state issues in your own development work, I’d love to hear about your experiences and solutions!

Last updated on