Psychopy在线实验Javascript版:输入字符限制引发光标异常Bug
问题根因
你这段代码的问题出在每帧被动截断文本但没管光标位置,还有个小问题是判断用了textbox_text.length,但修改的是textbox.text,变量没对齐。当文本超50字符被截断后,浏览器默认把光标怼回输入框开头,后面再输入就直接覆盖前面的内容;加上每帧循环的处理和用户输入不同步,就出现顺序混乱的情况了。
修复方案
别用每帧检查的方式,直接监听输入框的input事件,在用户输入的时候就限制长度,同时把光标位置固定好,避免浏览器瞎搞:
修改后的代码片段
var max_char_limit; function showImageRoutineEachFrame() { return async function () { //--- Loop for each frame of Routine 'showImage' --- t = showImageClock.getTime(); frameN = frameN + 1;// number of completed frames (so 0 is the first frame) // update/draw components on each frame // *object1* updates if (t >= 0.0 && object1.status === PsychoJS.Status.NOT_STARTED) { object1.tStart = t; object1.frameNStart = frameN; object1.setAutoDraw(true); } // *textPrompt* updates if (t >= 0.0 && textPrompt.status === PsychoJS.Status.NOT_STARTED) { textPrompt.tStart = t; textPrompt.frameNStart = frameN; textPrompt.setAutoDraw(true); } // *textbox* updates - 新增输入限制逻辑 if (t >= 0.0 && textbox.status === PsychoJS.Status.NOT_STARTED) { textbox.tStart = t; textbox.frameNStart = frameN; textbox.setAutoDraw(true); // 获取文本框的真实DOM元素 const inputBox = textbox._pdomElement; const maxLen = 50; // 监听输入事件,实时处理长度限制 inputBox.addEventListener('input', function(e) { if (e.target.value.length > maxLen) { // 截断到50字符 e.target.value = e.target.value.slice(0, maxLen); // 把光标固定在末尾,避免跳转到开头 e.target.setSelectionRange(maxLen, maxLen); } }); // 增加原生maxlength属性,从浏览器层面直接限制输入,双重保险 inputBox.maxLength = maxLen; } // 移除原来那段每帧检查长度的代码 // *continue_image8* updates if ((textbox.text.length > 0) && continue_image8.status === PsychoJS.Status.NOT_STARTED) { continue_image8.tStart = t; continue_image8.frameNStart = frameN; continue_image8.setAutoDraw(true); } } }
关键改进说明
- 抛弃每帧循环检查:直接监听用户输入事件,和输入动作同步,避免异步逻辑导致的冲突
- 强制固定光标位置:截断文本后用
setSelectionRange把光标锁定在末尾,解决浏览器默认跳开头的问题 - 原生属性双保险:给DOM元素设置
maxLength,让浏览器直接限制输入长度,减少额外代码压力 - 统一变量引用:直接操作DOM元素的
value,避免原代码中textbox_text和textbox.text的不一致问题
改完之后,效果就和本地Python版一致了:达到50字符后无法继续输入(退格正常),光标不会乱跳,也不会出现覆盖内容的情况。
内容的提问来源于stack exchange,提问作者cookielovessasa
相关产品推荐
相关产品推荐

