我使用一个contenteditable div作为输入字段来键入一些文本,并通过该文本中的按钮(小html图片)插入图标.
只要文本比可满足的领域更窄,它就没问题了.
一旦文本比字段长(因此它部分隐藏):
当我输入一个文本字符时,一切都很好,按下键后会自动显示最后一个字符,这样你就可以随时看到你输入的内容了.
但是当我通过按钮输入一个图标时,图标就可以了,但它是隐藏的,因为字段内容不会移动以使新输入的图标可见,直到我输入另一个文本字符.
对此的任何解决方案,以便输入的最后一个元素(文本或html)始终对用户可见?
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); } } } 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">'); }) });
[contenteditable="true"] { display: inline; white-space: nowrap; overflow: hidden !important; text-overflow: inherit; -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; } [contenteditable="true"] br { display: none; } .contAiner { display: flex; } .buttOn { width: 24px; height: 24px; border: none; background: #666; color: white; } .contEd { height: 22px; text-align: center; width: 100px; line-height: 23px; color: black; font-size: 10.5px; font-family: arial; border: 1px solid black; } .icOn { width: 9px; height: 13px; top: 1px; position: relative; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="contAiner"> <input class="buttOn" type="button" value="B"> <div class="contEd" contenteditable="true" spellcheck="false" autocomplete="off"></div> </div>
这是jsFiddle
这是original thread我从中获取了“pasteIcon”功能.
PS:我试图触发一个键码39(右箭头),就在pasteIcon函数之后,为了模拟一个按键,但它只是不起作用.
解决方法
您只需将编辑器滚动到插入的图标即可.移动选择后,请注意两行代码.希望它按预期工作:)
更新:
为了涵盖所有情况,我们需要检查插入的图像是否在编辑器边界内或外.
首先,让我们在编辑器元素中添加id,以便更容易找到它.然后我们可以利用函数getBoundingClientRect在屏幕上返回一个实际元素的矩形.最后,我们比较矩形,如果图像矩形不在编辑器内(imgRect.left< editorRect.left || imgRect.right> editorRect.right),那么我们滚动.
更新2:
在调查最新评论中描述的问题时,我发现在经过一定长度的编辑内容后,jQuery函数’offset’会返回不准确的结果.最有可能的原因是,编辑器的leftOffset在这种情况下不会自动更新.
最后,我将所需的滚动位置计算更改为图像DOM元素的offsetLeft减去编辑元素的offsetLeft减1(边框大小),现在它可以正常使用任何内容长度.
function pasteIcon(html) { var sel,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); var editorRect = $(contEdit)[0].getBoundingClientRect(); var imgRect = $(lastNode)[0].getBoundingClientRect(); if (imgRect.left < editorRect.left || imgRect.right > editorRect.right) { var actualLeft = $(lastNode)[0].offsetLeft - editorRect.left - 1; $(".contEd").scrollLeft(actualLeft); } } } } 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">'); }) });
[contenteditable="true"] { display: inline; white-space: nowrap; overflow: hidden !important; text-overflow: inherit; -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; } [contenteditable="true"] br { display: none; } .contAiner { display: flex; } .buttOn { width: 24px; height: 24px; border: none; background: #666; color: white; } .contEd { height: 22px; text-align: center; width: 100px; line-height: 23px; color: black; font-size: 10.5px; font-family: arial; border: 1px solid black; } .icOn { width: 9px; height: 13px; top: 1px; position: relative; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="contAiner"> <input class="buttOn" type="button" value="B"> <div id="contEdit" class="contEd" contenteditable="true" spellcheck="false" autocomplete="off"></div> </div>