contenteditable插入HTML元素后无法自动滚动显示的问题求助
Fix: Auto-scroll to newly inserted elements in contenteditable div
我完全懂你遇到的这个痛点:用带contenteditable="true"的div当输入框时,输入文本浏览器会自动滚动到最新字符,但通过按钮插入图标(HTML元素)后,新图标直接藏在看不见的地方,得再敲个字符才触发滚动。这是因为浏览器对文本输入有内置的滚动处理,但插入DOM元素时,哪怕你设置了选区,它也不会主动触发滚动,得我们手动补这一步。
解决思路:插入元素后手动触发滚动
我们只需要在pasteIcon函数里,设置完选区后,让最后插入的元素滚动到输入框的可见区域就行。这里有两种可靠的方式:
修改后的完整代码
function pasteIcon(html) { var sel, range; if (window.getSelection) { sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); range.deleteContents(); var el = document.createElement("div"); el.innerHTML = html; var frag = document.createDocumentFragment(), node, lastNode; while ((node = el.firstChild)) { lastNode = frag.appendChild(node); } range.insertNode(frag); if (lastNode) { range = range.cloneRange(); range.setStartAfter(lastNode); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); // 关键新增:让最后插入的元素滚动到水平可见区域的末尾 lastNode.scrollIntoView({ inline: "end", behavior: "instant" // 想要平滑滚动可以改成"smooth" }); // 如果上面的方法在个别浏览器不生效,用这个备选方案: // const inputBox = document.querySelector('.contEd'); // inputBox.scrollLeft = inputBox.scrollWidth; } } } else if (document.selection && document.selection.type != "Control") { document.selection.createRange().pasteIcon(html); } } $(document).ready(function() { $('.buttOn').click(function() { $('.contEd').focus(); pasteIcon('<img class="icOn" src="http://www.bmgstuff.com/files/interface/generator_frame/text_blood.png">'); }) });
为什么这样有效?
scrollIntoView方法:这是浏览器原生API,调用lastNode.scrollIntoView({ inline: "end" })会让目标元素滚动到容器的水平可视区域的最右侧,完美匹配你需要的“让最后插入的元素可见”的需求,兼容性也很好。- 备选方案(直接设置scrollLeft):如果某些场景下
scrollIntoView表现不符合预期,直接把输入框的scrollLeft设为它的scrollWidth(内容的总宽度),能强制滚动到最右侧,确保新元素可见。
测试效果
改完之后,每次点击按钮插图标,输入框都会自动滚到新图标位置,和输入文本时的体验完全一致,不用再额外敲字符啦。
内容的提问来源于stack exchange,提问作者Bachir Messaouri
相关产品推荐
相关产品推荐

