javascript - Làm thế nào để lấy vị trí cột con trỏ (không phải pixel) trong một textarea, tính bằng ký tự, từ đầu?
Làm thế nào để bạn lấy vị trí con trỏ trong một <textarea> bằng JavaScript?
Ví dụ: Đây là| một văn bản
Điều này nên trả về 7.
Bạn sẽ làm thế nào để nó trả về các chuỗi xung quanh con trỏ/vùng chọn?
Ví dụ: 'Đây là', '', ' một văn bản'.
Nếu từ “is ” được tô sáng, thì nó sẽ trả về 'This ', 'is', ' a text'.
Câu trả lời #1
Với Firefox, Safari (và các trình duyệt khác dựa trên Gecko), bạn có thể dễ dàng sử dụng textarea.selectionStart, nhưng với IE thì điều đó không hoạt động, vì vậy bạn sẽ phải làm gì đó như sau:
function getCaret(node) {
if (node.selectionStart) {
return node.selectionStart;
} else if (!document.selection) {
return 0;
}
var c = "\001",
sel = document.selection.createRange(),
dul = sel.duplicate(),
len = 0;
dul.moveToElementText(node);
sel.text = c;
len = dul.text.indexOf(c);
sel.moveStart('character',-1);
sel.text = "";
return len;
}
(hoàn thiện mã ở đây)
Tôi cũng khuyên bạn nên kiểm tra Plugin jQuery FieldSelection, nó cho phép bạn làm điều đó và còn nhiều hơn thế...
Chỉnh sửa: Thực ra tôi đã tái hiện lại đoạn mã trên:
function getCaret(el) {
if (el.selectionStart) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
Kiểm tra một ví dụ ở đây.
Câu trả lời số 2
Cập nhật ngày 5 tháng 9 năm 2010
Nhìn thấy rằng dường như ai cũng được chỉ dẫn đến đây cho vấn đề này, tôi đang thêm câu trả lời của mình cho một câu hỏi tương tự, có chứa cùng đoạn mã như câu trả lời này nhưng với đầy đủ bối cảnh cho những ai quan tâm:
document.selection.createRange của IE không bao gồm các dòng trống đầu hoặc cuối
Việc tính toán các xuống dòng ở cuối là khá khó trong IE, và tôi chưa thấy giải pháp nào thực hiện điều này đúng cách, bao gồm cả các câu trả lời khác cho câu hỏi này. Tuy nhiên, điều này là có thể, bằng cách sử dụng hàm sau, hàm này sẽ trả về cho bạn vị trí bắt đầu và kết thúc của vùng chọn (các vị trí này sẽ giống nhau trong trường hợp con trỏ) bên trong một <textarea> hoặc trường nhập liệu văn bản <input>.
Lưu ý rằng khu vực văn bản phải có tiêu điểm để chức năng này hoạt động đúng trong IE. Nếu không chắc chắn, hãy gọi phương thức focus() của khu vực văn bản trước.
function getInputSelection(el) {
var start = 0, end = 0, normalizedValue, range,
textInputRange, len, endRange;
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = document.selection.createRange();
if (range && range.parentElement() == el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
}