Silverstripe 4 TinyMCE插件:为每条记录独立保存恢复滚动位置
解决方案:为每条记录生成唯一的滚动位置存储键
你的问题根源在于sessionStorage使用了固定键tinymceScrollPosition,导致所有记录的滚动位置都会互相覆盖。要解决这个问题,需要为每个编辑器实例生成关联到具体记录的唯一存储键,结合Silverstripe 4的上下文,可按以下步骤修改:
步骤1:获取当前编辑记录的ID
在Silverstripe的编辑页面中,当前记录的ID可以直接从编辑器所在的表单隐藏字段中获取(Silverstripe默认会在编辑表单里添加ID隐藏字段):
// 在插件init函数内,获取当前记录ID var recordId = ed.getElement().closest('form').querySelector('input[name=ID]').value;
步骤2:生成唯一的存储键
结合编辑器ID(ed.id)和记录ID,生成唯一的存储键,确保不同记录、不同编辑器实例的存储项不会冲突:
var storageKey = `tinymceScrollPosition_${ed.id}_${recordId}`;
步骤3:修改存储与恢复逻辑
把原代码中固定的tinymceScrollPosition替换为上面生成的唯一键,调整保存和恢复的逻辑。
修改后的完整代码
(function() { tinymce.create('tinymce.plugins.scrollposition', { init:function(ed,url){ // 获取当前编辑记录的ID var recordId = ed.getElement().closest('form').querySelector('input[name=ID]').value; // 生成唯一存储键 var storageKey = `tinymceScrollPosition_${ed.id}_${recordId}`; // 初始化时恢复滚动位置 ed.on('init',function(){ console.log('Editor initialized. Attempting to restore scroll position.'); var savedScrollPosition=sessionStorage.getItem(storageKey); if(savedScrollPosition!==null){ var iframeWindow=ed.getWin(); iframeWindow.scrollTo(0,parseInt(savedScrollPosition,10)); } }); // 保存滚动位置的通用函数 function saveScrollPosition(){ var iframeWindow=ed.getWin(); var scrollPosition=iframeWindow.scrollY; sessionStorage.setItem(storageKey,scrollPosition); } ed.on('NodeChange',saveScrollPosition); ed.on('blur',saveScrollPosition); ed.on('PostProcess',saveScrollPosition); ed.on('BeforeUnload',saveScrollPosition); }, getInfo:function(){ return{ longname:'Scroll Position Plugin', author:'', authorurl:'', version:"1.0" }; } }); tinymce.PluginManager.add('scrollposition',tinymce.plugins.scrollposition); })();
关键说明
- 唯一性保障:通过
ed.id(编辑器实例唯一标识)+recordId(Silverstripe记录ID)的组合,彻底避免不同记录间的滚动位置覆盖问题。 - 用户体验优化:移除了原代码中的
sessionStorage.removeItem操作,用户再次编辑同一条记录时,仍能恢复之前的滚动位置;若需仅单次恢复,可重新添加该逻辑。 - 兼容性:代码中使用的
closest和querySelector属于现代浏览器标准API,完全适配Silverstripe 4的目标运行环境。
内容的提问来源于stack exchange,提问作者seppzzz
相关产品推荐
相关产品推荐

