您好我正在使用jquery来检测是否已将@符号插入到可信任的div中。检测到此情况时,会向服务器触发ajax请求以检索用户列表。然后用户点击用户名(功能adduser将触发),它将在div中创建一个禁用的textarea。 然后我动态创建一个输入,并将用户的id选为值(通知他)
我遇到的问题是,如果用户使用键盘甚至鼠标从contenteditable div删除textarea(用户名),我怎么知道它是textarea,所以删除输入具有用户ID作为价值?
我的剧本:
function adduser(fname, lname, id, q)
{
var fname = fname;
var lname = lname;
var id = id;
var word = '@' + q;
var iid = 'id' + id;
var old=$("#contentbox").html();
var content=old.replace(word,"");
$("#contentbox").html(content);
var E="<textarea class='textareamention' name="+id+" id="+iid+" disabled >"+fname+"</textarea>";
$("#contentbox").append(E);
$('<input/>').attr({ type: 'text', name: 'mention[]', id: id, value: id}).appendTo('#post');
}
答案 0 :(得分:1)
好的,这里......
未来的方式 - 也许不是唯一的方法 - 是使用Mutation Observers,尤其是Mutation-summary库来观察#contentbox
的变化。 Mutation-summary文档甚至提到了这个特定的用例 - 请参阅What is it useful for?下的最后一个要点。
事件处理的优势在于您无需预测可能导致删除textarea的每种类型的事件。
但有一些警告:
一旦观察到突变,必须有多种方法来处理相应元素的移除。
正如我在上面的评论中所建议的那样,一种方法是循环遍历所有输入并删除其对应的textarea不再存在的任何输入。
但是,我认为有一种更清洁的方式。
首先,在页面上安装Mutation-summary库(<script src="...">
标记,如jQuery)。
然后,修改adduser()
以包含附加到removeRelatedElements
元素的自定义EventListener <textarea>
:
function adduser(fname, lname, id, q) {
$('<textarea class="textareamention" name=' + id + ' id=id' + id + ' disabled>' + fname + '</textarea>')
.on('removeRelatedElements', function() {
$input.remove(); // $input is held in a closure
})
.appendTo($("#contentbox").html($("#contentbox").html().replace('@' + q, '')));
var $input = $('<input/>')
.attr({
'type': 'text',
'name': 'mention[]',
'id': id,
'value': id
})
.appendTo('#post');
}
现在,您应该能够使用Mutation-summary来观察对#contentbox
的更改,并在删除textArea时触发其自定义removeRelatedElements
事件,从而导致相应的<input>
元素也被删除了。
var observer = new MutationSummary({
queries: [
{ element: '#contentbox' } // jQuery-like selector
],
callback: function(summaries) {
summaries[0].removed.forEach(function(removedEl) {
// Here, you should be able to write POJS or jQuery, or a mixture
if(removedEl.tagName.toUpperCase() === 'TEXTAREA') {
$(removedEl).trigger('removeRelatedElements').off('removeRelatedElements'); // remove the corresponding input element and detatch the custom handler to keep things clean
}
});
}
});
无论如何,这是它的要点。您可能需要进行一些调试。
修改强>
好的,由于$("#contentbox").html().replace('@' + q, '')
取代了#contentbox中的DOM层次结构,上述尝试无效。在此过程中,我们的.on('removeRelatedElements', ...)
事件处理程序会不可逆转地闪烁,之后.trigger('removeRelatedElements')
会无声地失败。
我们必须恢复“计划A”。在.textareamention
的每个变异处,您需要查找并删除没有相应文本区域的任何输入。
很有可能认为你可以像以前一样使用summaries[0].removed
,但不是。问题在于summaries[0].removed
包含对replace('@' + q, '')
进程中删除的textareas的引用。因此,所有相应的输入元素将被删除,包括刚添加的那个!净效应是预期的输入永远不会出现。
幸运的是,解决方法很简单。我们可以完全忽略summaries
并使用$("#contentbox textarea.textareamention")
作为每个观察到的突变的起点。如果你不能理解这一点,不要担心 - 这并不明显。我通过反复试验发现了它。
以下是代码:
jQuery(function($) {
var counter = 0; // integer, for associating each <textarea> with its <input>
$('#button').click(function() {
var q = " ";
$('<textarea class="textareamention ' + counter + '" disabled></textarea>') // include `counter` as a className
.text(counter) // for demo purposes
.appendTo($("#contentbox").html($("#contentbox").html().replace('@' + q, '')));
var $input = $('<input/>').attr({
'type': 'text',
'name': 'mention[]',
'value': counter // for demo purposes
})
.data('counter', counter) // bind the current counter value to this <input>
.appendTo('#post');
counter++;
});
var observer = new MutationSummary({
'queries': [
{ element: '.textareamention' }
],
'callback': function(summaries) {
// Remove all inputs for which there is no corresponding textarea.
var $textareas = $("#contentbox textarea.textareamention"); // all textareas
$("#post input").filter(function(index, element) {
return $textareas.filter('.' + $(element).data('counter')).length === 0;
}) // filter to find any input for which there is no corresponding textarea ...
.remove(); // ... and remove it/them.
}
});
});
<强> DEMO 即可。注意:在小提琴中,所有上述代码都出现在javascript框架的 bottom 中。
答案 1 :(得分:0)
尝试在删除textarea时注册回调函数,如下所示:
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
function del(id) {
if (event.keyCode == 8) {
alert(id);
$("#id"+id).remove();
}
}
function adduser(fname, lname, id, q) {
var fname = fname;
var lname = lname;
var id = id;
var word = '@' + q;
var iid = 'id' + id;
var old=$("#contentbox").html();
var content=old.replace(word,"");
$("#contentbox").html(content);
var E="<textarea onkeydown='del("+id+")' class='textareamention' name="+id+" id="+iid+" >"+fname+"</textarea>";
$("#contentbox").append(E);
$('<input/>').attr({ type: 'text', name: 'mention[]', id: id, value: id}).appendTo('#post');
}
</script>
<body>
<div id='contentbox'></div>
<button onclick="adduser(123, 123, 123, 123)">Click me</button>
</body>
</html>