我正在寻找纯粹的 javascript 答案,因为这反映了我的项目范围。 jQuery答案不会被标记为正确,但欢迎未来的问题搜索者。旁注:我对第三方图书馆也不感兴趣。
我试图在多行selectionStart
中获取当前行的第一个位置(0)(当前基于textarea
用户选择多于1行的机会),但将其转换为插入符号索引。
我尝试了什么?没什么好看的:
for ( i = 0; i < this.selectionStart; i++ ) {
if (this.value.substr(i,1).match(/\r?\n|\r/)) {
lineStartIndx = i + 1
}
}
当使用大量的行迭代textareas时,这被证明是昂贵的。我个人对此的使用不会在每次keydown执行,但是,我只是以它为例。是否有更好的方法,内置或以其他方式模仿这一结果?
我的完整例子:
var input = document.getElementById("ta");
var output = document.getElementById("output");
let pattern = /\r?\n|\r/;
var lineNum, lineStartIndx;
input.addEventListener("keydown", function(e) {
taHandler(this);
})
input.addEventListener("click", function(e) {
taHandler(this);
})
function taHandler(elem) {
lineNum = getLineNumForSelection(elem);
let caretPos = elem.selectionStart;
lineStartIndx = 0;
for ( i = 0; i < caretPos; i++ ) {
if (elem.value.substr(i,1).match(pattern)) {
lineStartIndx = i + 1
}
}
output.innerHTML = "Selection Start: " + caretPos + " Selection End: " + elem.selectionEnd +
" <br> Line Number: " + lineNum.start +
"<br>Line Start Position: " + lineStartIndx;
}
function getLineNumForSelection(sel) {
return {
'start' : sel.value.substr(0, sel.selectionStart).split(pattern).length,
'end' : sel.value.substr(0,sel.selectionEnd).split(pattern).length
};
}
&#13;
<textarea id="ta" rows="5" cols="50">
Line one
Line two
Line three
Line four
</textarea>
<hr>
<div id="output"></div>
&#13;
答案 0 :(得分:1)
我的代码片段中的方法将内容分成行并使用.length属性而不是循环,因此它看起来更漂亮&#34;但是根据time complexity of javascript's .length可能不会更快,因为规范中没有任何内容可以防止浏览器执行缓慢。
关于代码的两个注意事项,我使用lineStartIndex,而不是没有e的lineStartIndx。由于lineNum是一个数组,我使用lineNumArray或selLineNums或更明显的东西,因为以num结尾的变量通常是整数。
var input = document.getElementById("ta");
var output = document.getElementById("output");
let pattern = /\r?\n|\r/;
var lineNum, lineStartIndx;
input.addEventListener("keydown", function(e) {
taHandler(this);
})
input.addEventListener("click", function(e) {
taHandler(this);
})
function taHandler(elem) {
lineNum = getLineNumForSelection(elem);
let caretPos = elem.selectionStart;
lineStartIndx = 0;
// begin modified code
let lines = elem.value.split(pattern),
lineIndex = 0;
while ( (lineIndex + 1 ) < lineNum.start ) {
lineStartIndx += parseInt( lines[lineIndex].length ) + 1;
lineIndex++;
}
// end modified code
// begin replaced code
for ( i = 0; i < caretPos; i++ ) {
if (elem.value.substr(i,1).match(pattern)) {
lineStartIndx = i + 1
}
}
// end replaced code
output.innerHTML = "Selection Start: " + caretPos + " Selection End: " + elem.selectionEnd +
" <br> Line Number: " + lineNum.start +
"<br>Line Start Position: " + lineStartIndx;
}
function getLineNumForSelection(sel) {
return {
'start' : sel.value.substr(0, sel.selectionStart).split(pattern).length,
'end' : sel.value.substr(0,sel.selectionEnd).split(pattern).length
};
}
&#13;
<textarea id="ta" rows="5" cols="50">
Line one
Line two
Line three
Line four
</textarea>
<hr>
<div id="output"></div>
&#13;