我怎么知道用户是否删除了一个可信的div中的元素?

时间:2017-09-26 01:25:08

标签: javascript jquery html dom

您好我正在使用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');
    }

2 个答案:

答案 0 :(得分:1)

好的,这里......

未来的方式 - 也许不是唯一的方法 - 是使用Mutation Observers,尤其是Mutation-summary库来观察#contentbox的变化。 Mutation-summary文档甚至提到了这个特定的用例 - 请参阅What is it useful for?下的最后一个要点。

事件处理的优势在于您无需预测可能导致删除textarea的每种类型的事件。

但有一些警告:

  • Mutation Observers目前仅受主要浏览器支持 - 谷歌Chrome,Firefox,Safari,Opera和IE11。我们被告知,“未来它将在其他浏览器中实施”。
  • Mutation-summary尚未更新约3年。
  • 我实际上并没有真正使用Mutation-summary - 我只阅读了文档。

一旦观察到突变,必须有多种方法来处理相应元素的移除。

正如我在上面的评论中所建议的那样,一种方法是循环遍历所有输入并删除其对应的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>