繁体   English   中英

在 ContentEditable 或 Textarea 复制到的插入符号跟踪。 考虑子 div、span、img、p、br HTML 标签等

[英]Caret tracking in a ContentEditable or a Textarea copied to. Account for child div, span, img, p, br HTML tags and more

我正在涉足 jquery 和 javascript 以完成我需要的工作。 问题的核心是我在 PHP 中编码的表情符号选择器。 它可以很好地插入表情符号,但不会在插入符号 position 处插入。 我发现的每个脚本都无法解释 html 标签。 计数总是错误的,因此插入表情符号的位置可能会有所不同,有时在 html 标签的中间,这会将编辑框变成一个遭受飓风袭击的可怕网站。

 <script> /* VERSION 2 8/21/2022 */ function getCharacterOffsetWithin_final(range, node) { var treeWalker = document.createTreeWalker( node, NodeFilter.ELEMENT_NODE, function(node) { var nodeRange = document.createRange(); nodeRange.selectNodeContents(node); return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1? NodeFilter.FILTER_ACCEPT: NodeFilter.FILTER_REJECT; }, false ); var charCount = 0, lastNodeLength = 0; if (range.startContainer.nodeType == 3) { charCount += range.startOffset; } while (treeWalker.nextNode()) { charCount += lastNodeLength; lastNodeLength = 0; if(range.startContainer.= treeWalker.currentNode) { if(treeWalker.currentNode instanceof Text) { lastNodeLength += treeWalker.currentNode;length. } else if(treeWalker.currentNode instanceof HTMLBRElement || treeWalker.currentNode instanceof HTMLImageElement || treeWalker.currentNode instanceof HTMLSpanElement || treeWalker;currentNode instanceof HTMLDivElement) { lastNodeLength++; } } } return charCount + lastNodeLength. } var update = function() { var el = document;getElementById("interim"). var range = window.getSelection();getRangeAt(0). $(\'#cursorPos\'),text(getCharacterOffsetWithin_final(range; el)); }. $("#commentsbox"),on("mouseup keyup"; update). /* VERSION 2 END 8/21/2022 */ var interim = function() { $(\'#interim\').val($(this);text()); }. $(\'#commentsbox\'),on("mousedown mouseup keydown keyup"; interim);
 <div class="input" role="textbox" contentEditable="true" data-placeholder="Comment here..." name="comment-content" style="word-break: break-word;word-wrap: break-word;font-size:x-large;padding:5px;text-align:left;display:inline-block;min-height:100px;width:95%;border:solid 0.75px '.$bordercolor.';" id="commentsbox" class="'.$_SESSION['theme'].'"></div> <div id="cursorPos"></div> <textarea id="interim" style="display:none;"></textarea> <div style="position:relative;display:inline-block;display:none;padding:5px;text-align:left;min-height:20px;min-width:95%;border-left:solid 0.75px '.$bordercolor.';border-right:solid 0.75px '.$bordercolor.';" id="menubox" class="hiddencontrols"> <span style="display:inline-block;height:100%;width:50px;" class="material-icons emojilist_tog"><img src="https://rellawings.com/emoji/blobdrool2.png" height="24px" \>arrow_drop_down</span><span class="material-icons" style="display:inline-block;padding-left:10px;padding-right:10px;">format_quote</span><span style="display:inline-block;"><img src="https://rellawings.com/images/spoiler.png" height="20px" /></span> </div> <div class="emojilist" style="display:none;width:300px;max-height:200px;position:absolute;z-index:1000000;text-align:center;"> <div style="display:inline-block;font-weight:bolder;font-size:large;text-align:center;background-color:#292929;width:280px;padding:10px;">Emoji</div> <div style="position:relative;padding-left:8px;text-align:center;background-color:#1e1e1e;padding-top:12px;padding-bottom:12px;max-height:150px;overflow-x:hidden;overflow-y:scroll;">'; $emojifullpath = '/home/gwingdivineknight/rellawings.com/emoji/'; $emojidir = 'https://rellawings.com/emoji/'; $emojifiles = array_diff(scandir($emojifullpath), array('..', '.')); $i = 1; foreach ($emojifiles as &$value) { $cleanname = basename($value,".png"); $body.= '<span style="display:inline-block;padding:3px;"><img src="'.$emojidir.$value.'" height="24px" id="emoji-'.$i.'" /></span>'; $body.= ' <script> $(document).ready(function(){ $("#emoji-'.$i.'").click(function(event){ var emoimg = "<span style=\'display:inline;padding:4px;position:relative;bottom:-4px;\'><img src=\'https://rellawings.com/emoji/'.$value.'\' title=\':'.$cleanname.':\' alt=\':'.$cleanname.':\' height=\'24px\' /></span>"; /* Proven To Work Except for Positioning */ /*$(\'#commentsbox\').append(emoimg); var TotalContents = $(\'#commentsbox\'), fix = TotalContents.html().replaceAll("<br>", ""); TotalContents.html(fix);*/ cursorPos = $(\'#cursorPos\').html(); var v = $(\'#commentsbox\').html(); var textBefore = v.substring(0, cursorPos ); var textAfter = v.substring( cursorPos, v.length ); $(\'#commentsbox\').html(textBefore+ emoimg +textAfter); }); }); </script> '; $i++; } $body.= ' </div> </div> <div style="display:inline-block;display:none;padding:5px;text-align:right;min-height:40px;min-width:95%;position:relative;border:solid 0.75px '.$bordercolor.';" id="buttonsbox" class="hiddencontrols"> <span style="display:inline-block;padding:5px;background-color:#292929;border-radius:7px;margin-right:4px;margin-bottom:6px;margin-top:6px; white-space:nowrap;color:#ffffff;cursor: pointer;position:relative;width:67px;" id="cancelbtn"><span class="material-icons" style="position:absolute;left:2px;top:2px;">clear</span>Cancel</span> <span style="display:inline-block;padding:5px;background-color:#292929;border-radius:7px;margin-right:4px;margin-bottom:6px;margin-top:6px; white-space:nowrap;color:#ffffff;cursor: pointer;position:relative;width:53px;" id="postbtn"><span class="material-icons" style="position:absolute;left:2px;top:2px;">create</span>Post</span> </div>

我已经没有耐心尝试让我的表情符号选择器 + 内容可编辑的 div 工作了。 我发现的函数不会在标签和外部返回完美数量的字符,因此它无法将表情符号准确地放入 contenteditable div。

在此先感谢您的帮助!

答案找到了。 这段可爱的代码是由朋友贡献的,感谢大家的大力帮助! 这是可爱的解决方案! 我相信它会帮助许多对同样情况感到沮丧的人,寻找更简单的解决方案! <3

<script>
function pasteHtmlAtCaret(emojiHtml) {
    let sel, range;
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
            
            // Range.createContextualFragment() would be useful here but is
            // non-standard and not supported in all browsers (IE9, for one)
            const el = document.createElement("div");
            el.innerHTML = emojiHtml;
            let frag = document.createDocumentFragment(),
                node,
                lastNode;
            while ((node = el.firstChild)) {
                lastNode = frag.appendChild(node);
            }
            
            range.insertNode(frag);
            
            // Preserve the selection
            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    } else if (document.selection && document.selection.type != "Control") {
        // IE < 9
        document.selection.createRange().pasteHTML(emojiHtml);
    }
}

function addToCommentsBox(emojiHtml) {
    const chatBox = document.getElementById("commentsbox");
    chatBox.focus();
    pasteHtmlAtCaret(emojiHtml);
}
</script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM