在contenteditable div中捕获返回键

时间:2018-04-09 23:32:17

标签: javascript html mobile contenteditable

我正在构建一个programmable calculator,它使用一个contenteditable div作为输入您需要评估的表达式的位置。 div侦听用户敲击返回键,然后将其文本内容传递给计算器引擎,清除自身,然后显示表达式的结果。

一切都在桌面浏览器上按预期工作,但在移动浏览器下,当插入符号不在文本末尾时按下返回键时会有一些奇怪的行为。有时点击返回键会插入一个空格或换行符,有时它会在插入符号之前提交并清除所有内容,而在Chrome下它似乎会创建一个新的div元素。我有什么想法吗?

我已经成功测试了在Ubuntu 17.10上运行的Firefox 59.0.2和Chromium 65.0.3325.181以及在Windows 7上运行的Firefox 59.0.2中的代码。我在Firefox 59.0.2和Chrome 65.0.3325.109中测试代码失败了在Android 8.1.0上运行。

window.addEventListener("load", function () {
    "use strict";

    var i = document.getElementById("i");
    var o = document.getElementById("o");

    i.addEventListener("keypress", function (e) {
        if (e.key === "Enter") {
            e.preventDefault();

            o.textContent = i.textContent;
            i.textContent = "";

            return false;
        }
        return true;
    });
});
div {
    font-size: 24px;
    padding: 1em;
    border: 1px solid black;
    min-height: 1em;
    box-sizing: content-box;
    margin: 1em;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=0">
        <title>Test</title>
    </head>

    <body>
        <div id="i" contenteditable="true"></div>
        <div id="o"></div>
    </body>
</html>

Demo of what happens on mobile

修改

经过一些工作,我做了另一种检测输入,复制文本和清除方框的方法。它不再监听击键,而是监视盒子本身的变化。它适用于桌面,但在移动设备上以类似方式失败。它还有一个额外的问题,如果你键入太快,它将崩溃Firefox手机。我在以前的浏览器上测试过代码。

window.addEventListener("load", function () {
    "use strict";

    var i = document.getElementById("i");
    var o = document.getElementById("o");
    var getText;
    var input;

    getText = function (e) {
        var s = [];

        e.childNodes.forEach(function (n) { // get every child
            switch (n.nodeType) {
            case 1: // element, so recurse
                s.push(getText(n));
                break;
            case 3: // text
                s.push(n.nodeValue);
                break;
            }
        });

        return s.join("");
    };

    input = function (e) {
        if (i.childNodes.length > 1  || (i.firstChild && i.firstChild.nodeType != 3)) { // checking for added <br />
            e.preventDefault();

            o.textContent = getText(i);
            while (i.firstChild) { // clear element
                i.removeChild(i.firstChild);
            }

            // add and remove listener to prevent event from firing on clear
            i.removeEventListener("input", input);
            setTimeout(function () {
                i.addEventListener("input", input, true);
            }, 100);

            return false;
        }
        return true;
    };

    i.addEventListener("input", input, true);
});
div {
    font-size: 24px;
    padding: 1em;
    border: 1px solid black;
    min-height: 1em;
    box-sizing: content-box;
    margin: 1em;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=0">
        <title>Test</title>
    </head>

    <body>
        <div id="i" contenteditable="true"></div>
        <div id="o"></div>
    </body>
</html>

编辑2(含解决方法):

经过一番思考后,我意识到我不需要使用一个有意义的div,所以我重新使用它来使用一个正常工作的样式文本输入字段。

window.addEventListener("load", function () {
    "use strict";

    var f = document.getElementById("f");
    var i = document.getElementById("i");
    var o = document.getElementById("o");

    f.addEventListener("submit", function (e) {
        e.preventDefault();

        o.textContent = i.value;
        i.value = "";

        return false;
    });
});
input[type="text"] {
    display: block;
    width: 100%;
    overflow: auto;
    outline: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    box-sizing: content-box;
}

#i, div {
    width: calc(100% - 4em - 2px);
    min-height: 1em;
    font-size: 24px;
    padding: 1em;
    border: 1px solid black;
    min-height: 1em;
    margin: 1em;
    color: black;
    font-family: serif;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=0">
        <title>Test</title>
    </head>

    <body>
        <form id="f" name="f">
            <input id="i" name="i" type="text" >
        </form>
        <div id="o"></div>
    </body>
</html>

0 个答案:

没有答案