简体   繁体   English

如何知道用户是否删除了 contenteditable div 中的元素?

[英]How can I know if an user deleted an element in a contenteditable div?

I am using jQuery to detect if an @ symbol has been inserted into a contenteditable div.我正在使用 jQuery 来检测 @ 符号是否已插入内容可编辑的 div 中。 When this is detected an ajax request is fired to the server to retrieve a list of users.当检测到此情况时,会向服务器发出 ajax 请求以检索用户列表。 A user would then click on the username (the function adduser will fire) and it will create a disabled textarea in the div.然后用户将单击用户名(函数 adduser 将触发),它将在 div 中创建一个禁用的文本区域。 Then I create an input dynamically with the id of the user selected as value (to notify them)然后我动态创建一个输入,将用户的 id 选为值(通知他们)

The problem I have is that if the users delete a textarea (a username) with the keyboard or even the mouse from the contenteditable div, How do I know which textarea it is and so remove too the input which has the user id as value?我遇到的问题是,如果用户使用键盘甚至鼠标从 contenteditable div 中删除文本区域(用户名),我怎么知道它是哪个文本区域,因此也删除了以用户 ID 作为值的输入?

My script:我的脚本:

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');
    }

OK, here goes ...好的,这就...

A way ahead - maybe not the only one - is to use Mutation Observers, more particularly the Mutation-summary , library - to watch your #contentbox for changes.一种前进方式 - 也许不是唯一的 - 是使用 Mutation Observers,尤其是Mutation-summary库 - 来观察你的#contentbox的变化。 The Mutation-summary documentation even mentions this particular usage case - see last bullet point under What is it useful for? Mutation-summary 文档甚至提到了这个特殊的使用案例 - 请参阅它有什么用处下的最后一个要点 . .

The advantage over event handling is that you don't need to predict every type of event that might cause deletion of a textarea.与事件处理相比的优势在于您不需要预测可能导致文本区域删除的每种类型的事件。

A few warnings though :不过有几个警告:

  • Mutation Observers are currently supported only by the major browsers - Google Chrome, Firefox, Safari, Opera and IE11. Mutation Observers 目前仅受主要浏览器支持 - Google Chrome、Firefox、Safari、Opera 和 IE11。 "In the future it will be implemented in other browsers", we are told. “将来它将在其他浏览器中实现”,我们被告知。
  • Mutation-summary hasn't been updated for some 3 years. Mutation-summary 已经有大约 3 年没有更新了。
  • I have not actually used Mutation-summary in anger - I've only read the documentation.我实际上并没有在愤怒中使用 Mutation-summary - 我只阅读了文档。

Once a mutation is observed, there must be a number of ways to handle removal of a corresponding element.一旦观察到突变,必须有多种方法来处理相应元素的移除。

One way, as I suggested in the comments above, would be to loop through all the inputs and remove any of them for which its corresponding textarea no longer exists.正如我在上面的评论中所建议的那样,一种方法是遍历所有输入并删除其相应的 textarea 不再存在的任何输入。

However, I think there's a cleaner way.但是,我认为有一种更清洁的方法。

First, install the Mutation-summary , library on the page (a <script src="..."> tag, like jQuery).首先,在页面上安装Mutation-summary库(一个<script src="...">标签,如 jQuery)。

Then, modify adduser() to include a custom EventListener, removeRelatedElements , attached to your <textarea> elements :然后,修改adduser()以包含附加到您的<textarea>元素的自定义事件侦听器removeRelatedElements

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');
}

Now, you should be able to use Mutation-summary to observe changes to #contentbox and, when a textArea is removed, trigger its custom removeRelatedElements event, causing the corresponding <input> element also to be removed.现在,您应该能够使用 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
            }
        });
    }
});

That's the gist of it anyway.无论如何,这就是它的要点。 You may well need to do some debugging.您可能需要进行一些调试。

EDIT:编辑:

OK, the above attempt doesn't work due to $("#contentbox").html().replace('@' + q, '') , which replaces the DOM hierarchy within #contentbox.好的,由于$("#contentbox").html().replace('@' + q, '')替换了 #contentbox 中的 DOM 层次结构,上述尝试不起作用。 In the process, our .on('removeRelatedElements', ...) event handlers get irrevocably blitzed and thereafter .trigger('removeRelatedElements') fails silently.在此过程中,我们的.on('removeRelatedElements', ...)事件处理程序不可撤销地快速启动,此后.trigger('removeRelatedElements')静默失败。

We have to revert to "plan A".我们必须回到“A计划”。 At each mutation of .textareamention , you need to find and remove any input for which there is no corresponding textarea..textareamention每次.textareamention ,您需要查找并删除任何没有对应 textarea 的输入。

It's tempting to think you can simply work with summaries[0].removed as before, but no.很容易认为您可以像以前一样简单地使用summaries[0].removed ,但summaries[0].removed并非如此。 The problem there is that summaries[0].removed includes references to the textareas that were removed during the replace('@' + q, '') process.问题在于summaries[0].removed包含对在replace('@' + q, '')过程中删除的 textareas 的引用。 Consequently all corresponding input elements get removed, including the one that was just added!因此,所有相应的输入元素都会被删除,包括刚刚添加的元素! The nett effect is that the expected input never appears.净效应是预期的输入永远不会出现。

Fortunately, the workaround is simple.幸运的是,解决方法很简单。 We can completely ignore summaries and work with $("#contentbox textarea.textareamention") as a start point at each observed mutation.我们可以完全忽略summaries并使用$("#contentbox textarea.textareamention")作为每个观察到的突变的起点。 Don't worry if you can't grasp this point - it's not obvious.如果您无法掌握这一点,请不要担心 - 这并不明显。 I discovered it by trial and error.我通过反复试验发现了它。

Here's the code :这是代码:

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 .演示 Note: in the fiddle, all the above code appears at the bottom of the javascript frame.注意:在小提琴中,以上所有代码都出现在 javascript 框架的底部

Try to register a callback function while deleting the textarea, like this:尝试在删除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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在可编辑的 div 中获取已删除的元素? - How to get a deleted element in a contenteditable div? 如果知道元素ID,如何在contenteditable div中选择(获取范围或选择对象)元素? - How do I select (get range or selection object) an element in a contenteditable div if I know the element ID? 我怎么知道div元素的宽度 - how i can know the width of div element 如何通过 contenteditable div 输入保留附加到列表的元素的换行符(格式)? - How can I keep the line breaks (formatting) of an element appended to a list via a contenteditable div input? 如何在另一个元素内将contenteditable div的内容呈现为HTML? - How can I render the content of a contenteditable div as HTML inside another element? 检查 contenteditable div 中的元素(文本)是否已被删除 - Check if an element(text) has been deleted in a contenteditable div Javascript:如何知道用户在contenteditable div中向哪个范围添加了文本? - Javascript: How to know which span did user add text to in contenteditable div? Contenteditable DIV - 如何确定光标是否位于内容的开头或结尾 - Contenteditable DIV - how can I determine if the cursor is at the start or end of the content 如何检测 contenteditable div 中的 HTML 更改? - How can I detect a HTML change inside a contenteditable div? jQuery:如何为contenteditable div创建颜色选择器? - Jquery: How can I create color picker for contenteditable div?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM