在用作聊天输入的 contenteditable div 中使用图像作为表情符号

Using images as emojis in a contenteditable div used as a chat input

提问人:redd 提问时间:8/28/2023 最后编辑:Md. Rakibul Islamredd 更新时间:8/28/2023 访问量:46

问:

我正在开发一个小聊天功能,我正在使用图像作为表情符号。

我所做的是,当单击表情符号时,会创建两个元素,第一个是带有表情符号背景图像的跨度,第二个是另一个以实际表情符号为内容的跨度,第一个跨度是第二个跨度的父级,所以我使用 CSS 将第二个跨度的可见性设置为“隐藏”,以便第一个跨度的背景图像从后面可见。

但问题是当我单击表情符号将其(上述两个 span 元素的组合)发送到消息输入(在本例中为 contenteditable div)时,插入符号被放置在图像表情符号(span 元素组合)之前而不是后面。例如,如果我点击表情符号之前输入的内容是“你好”,在我点击表情符号后,它会变成“你好(光标)(表情符号)”而不是“你好(表情符号)(光标)”,如果我添加另一个表情符号,它会变成“你好(光标)(表情符号)(表情符号)”而不是“你好(表情符号)(表情符号)(光标)”,请问我该如何解决这个问题?

以下是我的代码:

const chatInput = document.querySelector("div#chat-input");
const grinningFace = document.querySelector("span#grinning-face");
const rocket = document.querySelector("span#rocket");

chatInput.addEventListener("keydown", function(event) {
    if(event.key === "Enter"){
        event.preventDefault();
        const message = document.createElement("div");
        message.textContent = chatInput.innerText;
        chatInput.innerHTML = "";
    }
})


grinningFace.addEventListener("mousedown", function(event) {
    event.preventDefault();
});

grinningFace.addEventListener("click", function() {
    const content = grinningFace.querySelector("span")

    const range = document.getSelection().getRangeAt(0);
    const emojiImage = document.createElement("span");
    const emojiImageContent = document.createElement("span");
    emojiImage.classList.add("emoji-image");
    emojiImage.style.backgroundImage = `${getComputedStyle(grinningFace).backgroundImage}`;
    emojiImage.style.backgroundSize = "contain";
    emojiImageContent.textContent = content.textContent;
    emojiImage.appendChild(emojiImageContent);

    range.insertNode(emojiImage);
    // Get the next text node and set the cursor at its start
    const nextTextNode = emojiImage.nextSibling;
    if (nextTextNode && nextTextNode.nodeType === Node.TEXT_NODE) {
        const newRange = document.createRange();
        newRange.setStart(nextTextNode, 0);
        newRange.collapse(true);
        const selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(newRange);
        chatInput.focus();
    }

    
});

rocket.addEventListener("mousedown", function(event) {
    event.preventDefault();
    chatInput.focus();
});
div#chat-msgs {
    height: 70%;
    border: 1px solid #686868a1;
    border-radius: 8px;
}

span#grinning-face {
    background-image: url(./emojis/grinning-face.png);
    background-size: contain;
    display: inline-block;
    height: 80px;
    width: 80px;
}

span#grinning-face > span {
    visibility: hidden;
    height: 100%;
    display: inline-block;
    height: inherit; width: inherit;
}

span#rocket {
    background-image: url(./emojis/rocket.png);
    background-size: contain;
    display: inline-block;
    height: 80px;
    width: 80px;
}

span#rocket > span {
    visibility: hidden;
    height: 100%;
    display: inline-block;
    height: inherit; width: inherit;
}

div#chat-input {
    margin-top: 5px;
    height: 41px;width: calc(100% - 8px);
    line-height: 41px;
    border: 1px solid #686868a1;
    border-radius: 8px;
    padding-left: 8px
}

div#chat-input:empty:before {
    content: attr(placeholder);
}

.emoji-image {
    position: relative;
    top: 4px;
    left: 2px;
    display: inline-block;
    height: 28px;
    width: 28px;
    background-size: contain;
}

.emoji-image > span {
    visibility: hidden;
}
<html>
    <head>
        <title>Demo Chat</title>
        <link rel="stylesheet" href="./index.css">
        <script src="./index.js" defer></script>
    </head>
    <body>
        <div id="chat-msgs">
        </div>
        <div id="emojis">
            <span id="grinning-face"><span>😀</span></span>
            <span id="rocket"><span>🚀</span></span></div>
        <div id="chat-input" contenteditable="true" placeholder="Enter a message"></div>
    </body>
</html>

JavaScript 范围 聊天 选择 表情符号

评论


答: 暂无答案