确定标记化html输入中的插入符号位置

Determing caret position in tokenized html input?

本文关键字:插入 符号 位置 输入 html      更新时间:2023-09-26

(请不要jquery(

给定一个value/'s+/g分割的html输入,如何找到插入符号所在的当前标记?

例如,如果您的输入值是

abc      ab          monkey

如果你把它拆分,它就会变成

["abc, "ab", "monkey"]

但是,如果您在输入中的插入符号位置在这里。。。

abc      ab        monk^(caret here)ey     

如何确定插入符号当前位于哪个令牌中?

我正在寻找的api应该是类似的东西

var currentToken = getPosition(inputEl.value); // { index: 2, token: "monkey" }

我已经记下了大部分内容,但当我开始用左箭头在输入中回溯时,它会变得一团糟。

http://jsfiddle.net/dlizik/zmbpq5hz/

html

<input id="input" />
<pre id="test"></pre>
cursor at current token: <span id="res"></span>

js

(function($doc) {
    "use strict";    
    var single = /'s/g;
    var spacer = /'s+/g;
    var disp = $doc.getElementById("test");
    var input = $doc.getElementById("input");
    var res = $doc.getElementById("res");
    function keyListen(e) {
        var tokens = this.value.split(spacer);
        var tokenLengths = tokens.map(function(i) { return i.length; });
        var cumulative = tokenLengths.map(function(i, n) {
            return tokenLengths.slice(0, n + 1).reduce(function(a, b) {
                return a + b;
            });
        });
        var cursor = caretPos(this);
        var currToken = tokens[getPos(cursor, cumulative)];
        res.textContent = currToken;
        disp.textContent = JSON.stringify(this.value.split(spacer), null, 2);
    }
    function getPos(curr, arr) {
        for (var i = 0; i < arr.length; i++) {
            if (curr <= arr[i]) return i;
        }
    }
    function caretPos(el) {
        var val = el.value;
        var extra = val.match(single);
        var whitespace = extra == null ? 0 : extra.length;
        var pos = 0;
        if ($doc.selection) {
            el.focus();
            var sel = $doc.selection.createRange();
            sel.moveStart('character', -val.length);
            pos = sel.text.length;
        }
        else if (el.selectionStart || el.selectionStart == '0') pos = el.selectionStart;
        return (pos - whitespace);
    }
    input.addEventListener("keyup", keyListen.bind(input), false);
})(document);

好的,这样你就可以使用正则表达式了。。。现在我想起来并没有那么难。你只需要找到插入符号位置剩下的单词数。这将为您提供当前的令牌索引以及字符串本身。然而,您只需要考虑一个插入符号,它的相邻字符串都是空格。

http://jsfiddle.net/dlizik/zmbpq5hz/1/

这是您想要运行的功能

(function($doc) {
    "use strict";    
    var single = /'s/g;
    var tokenize = /[^'s+]/g;
    var ledge = /['s]*[^'s]+['s]*/g;
    var disp = $doc.getElementById("test");
    var input = $doc.getElementById("input");
    var res = $doc.getElementById("res");
    function keyListen(e) {
        var tokens = this.value.match(tokenize);
        var pos = caretPos(this);
        var adj = this.value.substring(pos - 1, pos + 1);
        var left = this.value.slice(0, pos + 1).match(ledge).length - 1;
        var curr = adj === "  " ? null : tokens[left];
        res.textContent = curr + "";
        disp.textContent = JSON.stringify(this.value.split(spacer), null, 2);
    }
    function caretPos(el) {
        var pos = 0;
        if ($doc.selection) {
            el.focus();
            var sel = $doc.selection.createRange();
            sel.moveStart('character', -el.value.length);
            pos = sel.text.length;
        }
        else if (el.selectionStart || el.selectionStart == '0') pos = el.selectionStart;
        return (pos);
    }
    input.addEventListener("keyup", keyListen.bind(input), false);
})(document);