Summernote调用pasteHTML()触发appendChild错误的特定场景排查
Answer
Great question—this boils down to how browser selection and Summernote's internal range handling work together. Here's the breakdown:
Why Clicking Blank Areas Causes the Error
When you click a non-interactive area like page whitespace, the browser's text selection (Selection object) shifts from Summernote's editable <div> to the main document (document node).
Summernote's pasteHTML() relies entirely on the currently active range (its internal WrappedRange abstraction) to know where to insert content. If that range is attached to the document instead of the editor's editable container, Summernote's underlying DOM logic tries to append content directly to the document node.
But DOM rules strictly state that the document node can only have one direct child element (the <html> tag). Trying to append anything else triggers the Only one element on document allowed error you're seeing.
In short: Clicking outside the editor yanks the selection out of the editor's scope, and pasteHTML() tries to insert content in the wrong place.
Fixes to Try
Here are three reliable ways to fix this:
1. Force Editor Focus & Reset Selection Before pasteHTML()
Before calling pasteHTML(), explicitly move the selection back into the editor. This ensures Summernote uses the correct insertion context:
// Get your Summernote editor instance const $editor = $('#your-editor-id'); const editor = $editor.summernote('editor'); // Force focus on the editor editor.focus(); // Create a range that targets the end of the editor's content const range = editor.createRange(); range.selectNodeContents(editor.layoutInfo.editable[0]); range.collapse(false); // Collapse to the end of existing content // Save this range as the active one editor.saveRange(range); // Now paste your HTML editor.pasteHTML(yourOriginalMessageHtml);
2. Validate Selection Context First
Check if the current selection is inside the editor before running pasteHTML(). If not, redirect focus:
const $editor = $('#your-editor-id'); const $editable = $editor.summernote('layoutInfo').editable; const selection = window.getSelection(); // Check if the active selection is outside the editor if (selection.rangeCount > 0) { const activeRange = selection.getRangeAt(0); if (!$editable.has(activeRange.commonAncestorContainer).length) { // Force focus back to the editor $editor.summernote('focus'); } } // Proceed with pasteHTML $editor.summernote('pasteHTML', yourOriginalMessageHtml);
3. Clear Document Selection on External Clicks
Prevent the browser from keeping a selection on the document when clicking outside the editor:
$(document).on('click', function(e) { const $editor = $('#your-editor-id'); // Check if click target is outside the editor if (!$editor.has(e.target).length && !$editor.find(e.target).length) { // Clear any existing document selection window.getSelection().removeAllRanges(); } });
Any of these should prevent the error by ensuring pasteHTML() always operates within the editor's DOM context.
内容的提问来源于stack exchange,提问作者Steven Frank

