英文:
How to change the value of input without the position of cursor going to the end?
问题
The newest question: can you give another more robust or succinct solution that can exactly accomplish the same goal as I described?
这是我的代码,存在一些问题。我想要将每五个字母分开,用空格隔开。
如果在输入的末尾输入或删除,它会表现得很好,但是如果在输入的末尾之外输入或删除,光标会自动移到末尾。
例如,文本框现在有ABCDE FGHJK
。如果我删除A
,光标会在删除A
后移到末尾。
如何修复这个代码以防止这种情况发生?(它应该只包括原始的JavaScript代码,但不包括CSS、HTML代码或Jquery。)
我尝试过重新定位cursorPosition
,但它不起作用...
如果可能的话,我希望代码尽可能简洁。
请记住,目标是尽可能地使输入更方便。
一些示例(|
代表光标):
原始输入 | 操作 | 操作前的结果 | 操作后的结果 | 光标位置相同 |
---|---|---|---|---|
`ABCD | E FGHJ` | 输入 X |
`ABCDX | E FGHJ` |
`ABCD | E FGHJK` | 输入 X |
`ABCDX | E FGHJK` |
`ABCDE | FGHJK` | 输入 X |
`ABCDEX | FGHJK` |
`ABCDE | FGHJK` | 输入 X |
`ABCDE X | FGHJK` |
`ABCD | E FGHJK L` | 退格 | `ABC | E FGHJK L` |
`ABCD | E FGHJK` | 退格 | `ABC | E FGHJK` |
`ABCDE F | GHJK` | 退格 | `ABCDE | GHJK` |
`ABCDE | FGHJK` | 退格 | `ABCDE | FGHJK` |
`ABCDE | FGHJK` | 退格 | `ABCD | FGHJK` |
`ABC | DE FGHJK` | 输入空格 | `ABC | DE FGHJK` |
更新:
这是我的修复:
let Input = document.createElement("input");
Input.setAttribute("type", "text");
Input.style.width = "100%";
Input.style.height = "30px";
Input.style.fontSize = "20px";
Input.addEventListener("input", () => {
const cursorPosition = Input.selectionStart;
const imValue = Input.value;
Input.value = Input.value.replace(/\s*/g,"").replace(/(.{5})/g, '$1 ').trim();
const lenDiff = Input.value.length - imValue.length;
if(cursorPosition == imValue.length) {
Input.setSelectionRange(Input.value.length, Input.value.length);
return ;
}
if(imValue[cursorPosition] === " " && Input.value[cursorPosition - 1] === " ") {
Input.setSelectionRange(cursorPosition + 1, cursorPosition + 1);
return ;
}
if(imValue[cursorPosition - 1] === " ") {
Input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);
return ;
}
Input.setSelectionRange(cursorPosition, cursorPosition);
});
document.body.appendChild(Input);
但是这个修复也有一个问题:它无法处理多字母字符串的复制和粘贴(只能处理单字母输入)。
更新:
问题通过在beforeinput
事件监听器中拆分字符串而得以解决。
let Input = document.createElement("input");
Input.setAttribute("type", "text");
Input.style.width = "100%";
Input.style.height = "30px";
Input.style.fontSize = "20px";
Input.addEventListener("beforeinput", e => {
if(e.data) {
e.preventDefault();
const data = e.data.replace(/\s*/g,"");
for(let i = 0; i < data.length; i++) {
let cursorPosition = Input.selectionStart;
Input.value = Input.value.slice(0, cursorPosition) + data[i] + Input.value.slice(cursorPosition);
Input.setSelectionRange(cursorPosition + 1, cursorPosition + 1);
Input.dispatchEvent(new Event("input"));
}
}
});
Input.addEventListener("input", () => {
const cursorPosition = Input.selectionStart;
const imValue = Input.value;
Input.value = Input.value.replace(/\s*/g,"").replace(/(.{5})/g, '$1 ').trim();
const lenDiff = Input.value.length - imValue.length;
if(cursorPosition == imValue.length) {
Input.setSelectionRange(Input.value.length, Input.value.length);
return ;
}
if(imValue[cursorPosition] === " " && Input.value[cursorPosition - 1] === " ") {
Input.setSelectionRange(cursorPosition + 1, cursorPosition + 1);
return ;
}
if(imValue[cursorPosition - 1] === " ") {
Input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);
return ;
}
Input.setSelectionRange(cursorPosition, cursorPosition);
});
document.body.appendChild(Input);
英文:
The newest question: can you give another more robust or succinct solution that can exactly accomplish the same goal as I described?
This is the code of mine that has some problems.
I want to split every five letters with a space.
It does well if you enter or delete at the end of the input BUT when you enter or delete NOT at the end of the input, the cursor would automatically go to the end.
For instance, the textbox now have ABCDE FGHJK
. If I delete the A
, the cursor would go the end after deleting the A
.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let Input = document.createElement("input");
Input.setAttribute("type", "text");
Input.style.width = "100%";
Input.style.height = "30px";
Input.style.fontSize = "20px";
// The code AFTER this need modification and improvement
Input.addEventListener("input", () => {
Input.value = Input.value.replace(/\s*/g,"");
Input.value = Input.value.replace(/(.{5})/g, '$1 ');
Input.value = Input.value.trim();
});
// The code BEFORE this need modification and improvement
document.body.appendChild(Input);
<!-- end snippet -->
How to fix the code to prevent it? (It should ONLY include original Javascript code but NOT CSS, HTML code or Jquery.)
I've tried to relocate the cursorPosition
but it doesn't work...
I would appreciate that if the code is as succinct as possible.
Remember the goal is to make the input as convenient as possible.
Some examples here (|
is the cursor):
Original Input | Operation | Result Before Operation | Result After Operation | cursorPosSame |
---|---|---|---|---|
`ABCD | E FGHJ` | Enter X |
`ABCDX | E FGHJ` |
`ABCD | E FGHJK` | Enter X |
`ABCDX | E FGHJK` |
`ABCDE | FGHJK` | Enter X |
`ABCDEX | FGHJK` |
`ABCDE | FGHJK` | Enter X |
`ABCDE X | FGHJK` |
`ABCD | E FGHJK L` | Backspace | `ABC | E FGHJK L` |
`ABCD | E FGHJK` | Backspace | `ABC | E FGHJK` |
`ABCDE F | GHJK` | Backspace | `ABCDE | GHJK` |
`ABCDE | FGHJK` | Backspace | `ABCDE | FGHJK` |
`ABCDE | FGHJK` | Backspace | `ABCD | FGHJK` |
`ABC | DE FGHJK` | Enter Space |
`ABC | DE FGHJK` |
Update:
Here is my fix:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let Input = document.createElement("input");
Input.setAttribute("type", "text");
Input.style.width = "100%";
Input.style.height = "30px";
Input.style.fontSize = "20px";
Input.addEventListener("input", () => {
const cursorPosition = Input.selectionStart;
const imValue = Input.value;
Input.value = Input.value.replace(/\s*/g,"").replace(/(.{5})/g, '$1 ').trim();
const lenDiff = Input.value.length - imValue.length;
if(cursorPosition == imValue.length) {
Input.setSelectionRange(Input.value.length, Input.value.length);
return ;
}
if(imValue[cursorPosition] === " " && Input.value[cursorPosition - 1] === " ") {
Input.setSelectionRange(cursorPosition + 1, cursorPosition + 1);
return ;
}
if(imValue[cursorPosition - 1] === " ") {
Input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);
return ;
}
Input.setSelectionRange(cursorPosition, cursorPosition);
});
document.body.appendChild(Input);
<!-- end snippet -->
But this fix also has a problem: it cannot deal with copy and paste of multi-letter string (can only deal with single-letter input).
Update:
The problem is solved by splitting the string in the eventlistener beforeinput
.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let Input = document.createElement("input");
Input.setAttribute("type", "text");
Input.style.width = "100%";
Input.style.height = "30px";
Input.style.fontSize = "20px";
Input.addEventListener("beforeinput", e => {
if(e.data) {
e.preventDefault();
const data = e.data.replace(/\s*/g,"");
for(let i = 0; i < data.length; i++) {
let cursorPosition = Input.selectionStart;
Input.value = Input.value.slice(0, cursorPosition) + data[i] + Input.value.slice(cursorPosition);
Input.setSelectionRange(cursorPosition + 1, cursorPosition + 1);
Input.dispatchEvent(new Event("input"));
}
}
});
Input.addEventListener("input", () => {
const cursorPosition = Input.selectionStart;
const imValue = Input.value;
Input.value = Input.value.replace(/\s*/g,"").replace(/(.{5})/g, '$1 ').trim();
const lenDiff = Input.value.length - imValue.length;
if(cursorPosition == imValue.length) {
Input.setSelectionRange(Input.value.length, Input.value.length);
return ;
}
if(imValue[cursorPosition] === " " && Input.value[cursorPosition - 1] === " ") {
Input.setSelectionRange(cursorPosition + 1, cursorPosition + 1);
return ;
}
if(imValue[cursorPosition - 1] === " ") {
Input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);
return ;
}
Input.setSelectionRange(cursorPosition, cursorPosition);
});
document.body.appendChild(Input);
<!-- end snippet -->
答案1
得分: 1
以下是您的代码部分的翻译:
let Input = document.createElement("input");
Input.setAttribute("type", "text");
Input.style.width = "100%";
Input.style.height = "30px";
Input.style.fontSize = "20px";
function formatValue(value) {
return value.replace(/\s*/g, "").replace(/(.{5})/g, "$1 ").trim();
}
Input.addEventListener("input", function(e) {
const cursorPosition = Input.selectionStart;
const oldValue = Input.value
Input.value = formatValue(Input.value);
const newPosition = oldValue.length < Input.value.length ? cursorPosition + 1 : cursorPosition
Input.setSelectionRange(newPosition, newPosition);
});
Input.addEventListener("keydown", function(e) {
let cursorPosition = Input.selectionStart;
let value = Input.value;
if (e.key === 'Backspace') {
e.preventDefault();
if (cursorPosition === 0) return
const offset = Input.value[cursorPosition - 1] === ' ' ? 2 : 1;
value = value.slice(0, cursorPosition - offset) + value.slice(cursorPosition);
Input.value = formatValue(value);
Input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);
} else if (e.key === 'Delete') {
e.preventDefault();
if (cursorPosition >= value.length) return
const offset = Input.value[cursorPosition] === ' ' ? 2 : 1
value = value.slice(0, cursorPosition) + value.slice(cursorPosition + offset);
Input.value = formatValue(value);
Input.setSelectionRange(cursorPosition, cursorPosition);
}
});
document.body.appendChild(Input);
这是您提供的代码的中文翻译部分。
英文:
Modified your code a bit to restore cursor position:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let Input = document.createElement("input");
Input.setAttribute("type", "text");
Input.style.width = "100%";
Input.style.height = "30px";
Input.style.fontSize = "20px";
function formatValue(value) {
return value.replace(/\s*/g, "").replace(/(.{5})/g, "$1 ").trim();
}
Input.addEventListener("input", function(e) {
const cursorPosition = Input.selectionStart;
const oldValue = Input.value
Input.value = formatValue(Input.value);
const newPosition = oldValue.length < Input.value.length ? cursorPosition + 1 : cursorPosition
Input.setSelectionRange(newPosition, newPosition);
});
Input.addEventListener("keydown", function(e) {
let cursorPosition = Input.selectionStart;
let value = Input.value;
if (e.key === 'Backspace') {
e.preventDefault();
if (cursorPosition === 0) return
const offset = Input.value[cursorPosition - 1] === ' ' ? 2 : 1;
value = value.slice(0, cursorPosition - offset) + value.slice(cursorPosition);
Input.value = formatValue(value);
Input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);
} else if (e.key === 'Delete') {
e.preventDefault();
if (cursorPosition >= value.length) return
const offset = Input.value[cursorPosition] === ' ' ? 2 : 1
value = value.slice(0, cursorPosition) + value.slice(cursorPosition + offset);
Input.value = formatValue(value);
Input.setSelectionRange(cursorPosition, cursorPosition);
}
});
document.body.appendChild(Input);
<!-- end snippet -->
答案2
得分: 1
以下是您要翻译的代码部分:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
document.addEventListener("DOMContentLoaded", function() {
const input = document.createElement("input");
input.setAttribute("type", "text");
input.style.width = "100%";
input.style.height = "30px";
input.style.fontSize = "20px";
let previousValue = "";
let previousCursorPosition = 0;
input.addEventListener("input", function(e) {
const cursorPosition = input.selectionStart;
const value = input.value.replace(/\s*/g, "").replace(/(.{5})/g, "$1 ").trim();
input.value = value;
input.setSelectionRange(cursorPosition, cursorPosition);
previousValue = value;
previousCursorPosition = cursorPosition;
});
input.addEventListener("keydown", function(e) {
const cursorPosition = input.selectionStart;
// Handle the scenario when Backspace key is pressed
if (e.key === "Backspace" && cursorPosition > 0 && input.value[cursorPosition - 1] === " " &&
input.value[cursorPosition] !== " ") {
e.preventDefault();
const valueBeforeCursor = input.value.slice(0, cursorPosition - 2);
const valueAfterCursor = input.value.slice(cursorPosition - 1);
input.value = valueBeforeCursor + valueAfterCursor;
input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);
previousValue = input.value.replace(/\s*/g, "").replace(/(.{5})/g, "$1 ").trim();
previousCursorPosition = cursorPosition - 1;
}
});
input.addEventListener("keydown", function(e) {
if (e.keyCode === 32 && input.selectionStart !== input.selectionEnd) {
// Space bar pressed with text selected, remove spaces from the selection
const start = input.selectionStart;
const end = input.selectionEnd;
const value = input.value.substring(start, end).replace(/\s/g, "");
input.value = input.value.substring(0, start) + value + input.value.substring(end);
input.setSelectionRange(start, start + value.length);
e.preventDefault();
} else if (e.keyCode === 32 && input.selectionStart === input.selectionEnd) {
// Space bar pressed with no text selected, don't add space
e.preventDefault();
}
});
document.body.appendChild(input);
});
<!-- end snippet -->
请注意,这段代码主要是关于在文本输入框中进行文本处理和格式化的JavaScript代码。
英文:
You may try this:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
document.addEventListener("DOMContentLoaded", function() {
const input = document.createElement("input");
input.setAttribute("type", "text");
input.style.width = "100%";
input.style.height = "30px";
input.style.fontSize = "20px";
let previousValue = "";
let previousCursorPosition = 0;
input.addEventListener("input", function(e) {
const cursorPosition = input.selectionStart;
const value = input.value.replace(/\s*/g, "").replace(/(.{5})/g, "$1 ").trim();
input.value = value;
input.setSelectionRange(cursorPosition, cursorPosition);
previousValue = value;
previousCursorPosition = cursorPosition;
});
input.addEventListener("keydown", function(e) {
const cursorPosition = input.selectionStart;
// Handle the scenario when Backspace key is pressed
if (e.key === "Backspace" && cursorPosition > 0 && input.value[cursorPosition - 1] === " " && input.value[cursorPosition] !== " ") {
e.preventDefault();
const valueBeforeCursor = input.value.slice(0, cursorPosition - 2);
const valueAfterCursor = input.value.slice(cursorPosition - 1);
input.value = valueBeforeCursor + valueAfterCursor;
input.setSelectionRange(cursorPosition - 1, cursorPosition - 1);
previousValue = input.value.replace(/\s*/g, "").replace(/(.{5})/g, "$1 ").trim();
previousCursorPosition = cursorPosition - 1;
}
});
input.addEventListener("keydown", function(e) {
if (e.keyCode === 32 && input.selectionStart !== input.selectionEnd) {
// Space bar pressed with text selected, remove spaces from the selection
const start = input.selectionStart;
const end = input.selectionEnd;
const value = input.value.substring(start, end).replace(/\s/g, "");
input.value = input.value.substring(0, start) + value + input.value.substring(end);
input.setSelectionRange(start, start + value.length);
e.preventDefault();
} else if (e.keyCode === 32 && input.selectionStart === input.selectionEnd) {
// Space bar pressed with no text selected, don't add space
e.preventDefault();
}
});
document.body.appendChild(input);
});
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论