在suneditor-react中按Enter换行时容器自动滚动至顶部问题
解决方案
方案1:自定义Enter键行为并维护滚动位置
suneditor默认的Enter键处理逻辑可能触发DOM变动,导致容器意外滚动。可以手动拦截Enter事件,自定义换行行为并恢复滚动位置:
import { useRef } from 'react'; import SunEditor from 'suneditor-react'; import 'suneditor/dist/css/suneditor.min.css'; const EditorComponent = () => { const editorRef = useRef(null); const scrollContainerRef = useRef(null); const handleKeyDown = (e) => { if (e.key === 'Enter') { e.preventDefault(); // 手动插入换行标签 const editor = editorRef.current?.sunEditor; if (editor) { editor.insertHTML('<br>'); editor.focus(); // 记录当前滚动位置,延迟恢复避免DOM渲染干扰 const scrollTop = scrollContainerRef.current.scrollTop; setTimeout(() => { scrollContainerRef.current.scrollTop = scrollTop; }, 0); } } }; return ( <div ref={scrollContainerRef} style={{ overflowY: 'auto', height: '400px', border: '1px solid #eee' }} > <SunEditor ref={editorRef} onKeyDown={handleKeyDown} setOptions={{ enterKey: 'br', // 强制Enter键插入br,减少段落创建带来的DOM变动 }} /> </div> ); }; export default EditorComponent;
方案2:监听容器滚动,拦截意外滚动
给滚动容器添加滚动监听,判断是否为编辑器触发的异常滚动,恢复之前的滚动位置:
import { useRef, useEffect } from 'react'; import SunEditor from 'suneditor-react'; import 'suneditor/dist/css/suneditor.min.css'; const EditorComponent = () => { const editorRef = useRef(null); const scrollContainerRef = useRef(null); let lastValidScrollTop = 0; useEffect(() => { const container = scrollContainerRef.current; if (!container) return; const handleScroll = () => { const activeElement = document.activeElement; // 判断焦点是否在编辑器内,若是则恢复滚动位置 if (activeElement?.closest('.sun-editor')) { container.scrollTop = lastValidScrollTop; } else { // 正常滚动时记录有效位置 lastValidScrollTop = container.scrollTop; } }; container.addEventListener('scroll', handleScroll); return () => container.removeEventListener('scroll', handleScroll); }, []); return ( <div ref={scrollContainerRef} style={{ overflowY: 'auto', height: '400px', border: '1px solid #eee' }} > <SunEditor ref={editorRef} /> </div> ); }; export default EditorComponent;
方案3:调整编辑器内容区样式,隔离滚动
让编辑器内部自己处理滚动,避免影响外层容器:
/* 全局样式或组件内的CSS模块 */ .sun-editor-editable { max-height: 360px; /* 高度小于外层容器,留出余量 */ overflow-y: auto; }
方案4:动态导入编辑器避免SSR hydration问题
Next.js的SSR可能导致编辑器DOM初始化异常,尝试禁用SSR动态导入:
import dynamic from 'next/dynamic'; const SunEditor = dynamic(() => import('suneditor-react'), { ssr: false, loading: () => <div>加载编辑器中...</div>, }); const EditorComponent = () => { return ( <div style={{ overflowY: 'auto', height: '400px' }}> <SunEditor /> </div> ); }; export default EditorComponent;
内容的提问来源于stack exchange,提问作者Ekhlas Mridha
相关产品推荐
相关产品推荐

