好的,这就去......
一个的方法——也许不是唯一的方法——是使用 Mutation Observers,尤其是 Mutation-summary,库——来观察你的 #contentbox 的变化。 Mutation-summary 文档甚至提到了这个特殊的用例 - 请参阅What is it useful for? 下的最后一个要点。
与事件处理相比,优势在于您无需预测可能导致删除文本区域的每种类型的事件。
虽然有一些警告:
- 目前只有主流浏览器支持 Mutation Observers - Google Chrome、Firefox、Safari、Opera 和 IE11。有人告诉我们,“未来它将在其他浏览器中实现”。
- Mutation-summary 已经有 3 年没有更新了。
- 我实际上并没有在愤怒中使用 Mutation-summary - 我只阅读了文档。
一旦观察到突变,必须有多种方法来处理相应元素的删除。
正如我在上面的 cmets 中所建议的那样,一种方法是遍历所有输入并删除其中任何相应的 textarea 不再存在的输入。
但是,我认为有一种更清洁的方法。
首先,在页面上安装Mutation-summary 库(<script src="..."> 标记,如 jQuery)。
然后,修改 adduser() 以包含一个自定义事件侦听器 removeRelatedElements,附加到您的 <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, '') 过程中删除的文本区域的引用。结果 所有 对应的输入元素被删除,包括刚刚添加的元素!净效应是预期的输入永远不会出现。
幸运的是,解决方法很简单。我们可以完全忽略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框架的底部。