You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 13:23:18