3 回答

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超3個(gè)贊
//獲取選擇域位置,如果未選擇便是光標(biāo)位置
function getSelection(el) {
return (
('selectionStart' in el && function () {
var l = el.selectionEnd - el.selectionStart;
return {
start: el.selectionStart,
end: el.selectionEnd,
length: l,
text: el.value.substr(el.selectionStart, l)
};
}) ||
(document.selection && function () {
el.focus();
var r = document.selection.createRange();
if (r === null) {
return {
start: 0,
end: el.value.length,
length: 0
}
}
var re = el.createTextRange();
var rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return {
start: rc.text.length,
end: rc.text.length + r.text.length,
length: r.text.length,
text: r.text
};
}) ||
function () {
return null;
}
)();
}
//替換選擇
function replaceSelection(el) {
var text = arguments[0] || '';
return (
/* mozilla / dom 3.0 */ ('selectionStart' in el && function () {
el.value = el.value.substr(0, el.selectionStart) + text + el.value.substr(el.selectionEnd, el.value.length);
return this;
}) ||
/* exploder */ (document.selection && function () {
el.focus();
document.selection.createRange().text = text;
return this;
}) ||
/* browser not supported */function () {
el.value += text;
return jQuery(el);
}
)();
}

TA貢獻(xiàn)1906條經(jīng)驗(yàn) 獲得超10個(gè)贊
可以考慮使用 Range,但是由于存在兼容性問(wèn)題,也比較麻煩。
新浪的做法挺簡(jiǎn)單的。
用 css 控制,做一個(gè)和 textarea 一樣樣式的 div,放在一個(gè)不可見(jiàn)的地方。綁定事件保證 div 里面的內(nèi)容和 textarea 一致。
如果輸入的是 @ 或者其他需要關(guān)注的字符,就在 div 里面的 @ 外層用 包裹一下 <span>@</span>
。
這個(gè)時(shí)候,我們就可以用傳統(tǒng)的方法獲取 @ 相對(duì) div 左上角的 xy 座標(biāo)了。根據(jù) xy 座標(biāo),就能確定彈出層相對(duì) textarea 的位置了。

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超5個(gè)贊
以下是在Vue中的例子實(shí)現(xiàn)
// main.js中
import { position, offset } from 'caret-pos';
Vue.prototype.$positon = position
Vue.prototype.$offset = offset
// edior.vue 的 methods 中,然后在 mounted 鉤子中掛一下這個(gè)方法
bindKeys() {
let textarea = document.querySelector('.textarea')
textarea.addEventListener('keyup', (e) => {
console.log('____________', this.$offset(textarea))
})
},
添加回答
舉報(bào)