我有一个内容可编辑的div,当您键入@时,列表就会出现。现在,我希望能够在contenteditable div中的当前光标位置单击li元素时插入一些文本。我不知何故需要找到光标位置,并用一些文本替换@。假设我输入“ Javascript is @”以产生“ Javascript is awesome”。
$('.reply').on('keydown', function(e) {
if (e.keyCode == 86) {
$('.list').show();
} else {
$('.list').hide();
}
})
.list {
display: none;
}
.reply {
border: 1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="reply" contentEditable="true"></div>
<ul class="list">
<li>One</li>
<li>Two</li>
<li>three</li>
<li>Four</li>
<li>Five</li>
</ul>
答案 0 :(得分:3)
如果要检测用户是否按 @ 键,除了检查单个keyCode之外,还需要检查 alt 键是否也按下。
$('.reply').on('keydown', function(e) {
if (e.altKey && e.keyCode == 81) {
$('.list').show();
} else {
$('.list').hide();
}
});
要在单击时获取li元素的内容,您需要将click事件侦听器附加到列表,并使用 e.target.firstChild.data 在回调函数中检索文本。 >
现在,事情变得有些棘手了,因为您使用的是内容可编辑的 div 而不是 textarea 。 div不提供内置方法来检索光标的位置,因此我们需要使用 Selection API自行实现。
首先将两个新属性添加到HTML div元素
HTMLDivElement.prototype.selectionStart = 0;
HTMLDivElement.prototype.selectionEnd = 0;
并将多个侦听器附加到div元素,以检查是否有内容写入
['mousedown', 'mouseup', 'keydown', 'keyup'].forEach(function(evt) {
document.getElementsByClassName("reply")[0].addEventListener(evt, update);
});
以防万一-相应地更新新属性
function update(e) {
var caret = window.getSelection().anchorOffset;
e.target.selectionStart = caret;
e.target.selectionEnd = caret + window.getSelection().focusOffset;
}
现在,事情变得简单,只需检索li元素的click事件处理程序内的光标位置,然后减去1并用适当的文本替换内容即可。
这是一个例子:
HTMLDivElement.prototype.selectionStart = 0;
HTMLDivElement.prototype.selectionEnd = 0;
function update(e) {
var caret = window.getSelection().anchorOffset;
e.target.selectionStart = caret;
e.target.selectionEnd = caret + window.getSelection().focusOffset;
}
['mousedown', 'mouseup', 'keydown', 'keyup'].forEach(function(evt) {
document.getElementsByClassName("reply")[0].addEventListener(evt, update);
});
$('.reply').on('keydown', function(e) {
if (e.altKey && e.keyCode == 81) {
$('.list').show();
} else {
$('.list').hide();
}
});
$('.list').on('click', function(e) {
var text = $('.reply').text();
var pos = $('.reply')[0].selectionStart - 1;
text = text.substring(0, pos) + e.target.firstChild.data + text.substring(pos + 1);
$('.reply').text(text);
});
$('.list').hide();
.reply {
border: 1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="reply" contentEditable="true">
</div>
<ul class="list">
<li>One</li>
<li>Two</li>
<li>three</li>
<li>Four</li>
<li>Five</li>
</ul>
答案 1 :(得分:1)
您必须像这样将事件添加到列表中。
$('.list li').bind('click', function(){
var inputValue = $(".reply").text();
var indexOfAt = inputValue.indexOf('@');
if(indexOfAt != -1){
var modifiedText = $(".reply").text().replace('@',$(this).text());
$(".reply").text(modifiedText);
}
$('.list').hide();
});