使用dataTables組件製做可編輯table單元格時blur、 mouseleave以及mouseenter事件的衝突

問題出現的場景是:
使用dataTables組件,可是該組件沒有自帶的編輯功能,因此須要本身處理table在行內編輯的效果。html

目標效果是:
1.當hover到當前tr的時候,該行tr中能夠編輯的td中出現一個input框:this

圖片描述

2.當離開當前tr的時候,該行退出可編輯的狀態,恢復到沒有hover上去以前的效果。編碼

圖片描述

3.當td變成可編輯狀態,即出現了一個input輸入框的時候,focus到input輸入框中,能夠輸入number;當input框發生blur事件的時候,td恢復到非編輯狀態:spa

圖片描述

因爲blur和moseleave都會讓輸入框恢復到非編輯的狀態,因此,這裏的事件會有衝突。code

在實際的編碼中,在tr上綁定了mouseenter和mouseleave事件;htm

mouseenter事件的綁定:

function mouseenterEvt (e) {
    var tds = $(this).children('td');
    $.each(tds, function (i, val) {
        var jqob = $(val);
        if (i !== 3) {
            return true;
        }
        // if there is something validate wrong,stay there width no value exchange
        var validateSpanDom = jqob.find('span');
        var value = validateSpanDom ? validateSpanDom.text() : '';
        var validateTxt = validateInputBox(value);
        if(validateTxt) return false;
        // open edit mode
        jqob.addClass("edit-btn-display");
        var txt = jqob.text();
        txt = txt.replace('$', '');
        txt = txt.replace(/,/g, '');
        var put = $("<div class=\"money-budget-validate\"><input type='text' class='edit-input-box'><span></span></div>");
        put.children('.edit-input-box').val(txt);
        jqob.html(put);

    });
}
$("#table_id_example tbody").on("mouseenter", "tr",mouseenterEvt );

mouseleave事件的綁定:

$("#table_id_example tbody").on("mouseleave", "tr", function (e) {
    var row = tableDom.row($(this));
    var tds = $(this).children('td');

    $.each(tds, function (i, val) {
        var jqob = $(val);
        if (jqob.hasClass('edit-btn-display') && jqob.find('.edit-input-box').length > 0) {
            // if there is something validate wrong,stay there width no value exchange
            var validateSpanDom = jqob.find('span');
            var value = validateSpanDom ? validateSpanDom.text() : '';
            var validateTxt = validateInputBox(value);
            if(validateTxt) return false;
            var txt = jqob.find('.edit-input-box').val();
            txt = txt.replace('$', '');
            if(String(txt).indexOf('.') !== -1 ) {
                txt = Number(txt).toFixed(2);
            }
            jqob.html(txt);
            tableDom.cell(jqob).data(txt);
            // close edit mode
            jqob.removeClass("edit-btn-display");
        }
    });

    $("#table_id_example tbody").off("mouseenter", "tr",mouseenterEvt )
    $("#table_id_example tbody").on("mouseenter", "tr",mouseenterEvt )
});

在input輸入框上綁定了blur事件:blog

blur事件的綁定:

$("#table_id_example tbody").on("blur", ".edit-input-box", function (e) {
    var value = $(this).val();
    var validateTxt = validateInputBox(value)
    if (!validateTxt) {
        var td = $(this).parents('td');
        var row = tableDom.row($(td));
        $(this).toggleClass("edit-btn-being-edit");
        var txt = $(this).val();
        txt = txt.replace('$', '');
        if(String(txt).indexOf('.') !== -1 ) {
            txt = Number(txt).toFixed(2);
        }
        td.html(txt);
        tableDom.cell(td).data(txt);//change data of DataTables obj
        var data = row.data();
        //alert('save current monthly-budget value')
        $("#table_id_example tbody").off("mouseenter", "tr",mouseenterEvt )
    }
});

對於事件解綁和從新綁定的解釋:事件

  • 當沒有進行事件的解綁和從新綁定的時候,在input框中輸入結束,點擊input所在的td的時候,會接着觸發mouseenter事件;可是當點擊該input所在的td以外的td的時候,就會發生blur事件和mouseleave事件。
  • 爲了,在點擊當前input所在的td的時候,只發生blur事件,須要在blur事件結束以後,刪除mouseenter事件的綁定。這樣,tr的mouseenter事件被刪除了就不會觸發了。
  • 可是,在當前行blur以後,再進入其餘的行依舊須要可以編輯,又因爲編輯完一行以後,確定是會mouseleave該行的,所以,在tr的mouseleave事件中又將tr的mouseenter事件加回去。
  • 須要注意一點,咱們在使用jq綁定事件的時候,重複的事件是不會被清除的,而是會累加,因此,在mouseleave中從新添加事件以前,須要將以前的先清除。在這裏就是:在mousenter以後根本沒有對input進行編輯就mouseleave了,此時在mouseleave中若不先清除原有的事件,那麼tr上的mouseenter事件就會被添加兩次。
相關文章
相關標籤/搜索