问题出现的场景是:使用dataTables组件,但是该组件没有自带的编辑功能,所以需要自己处理table在行内编辑的效果。目标效果是:1.当hover到当前tr的时候,该行tr中可以编辑的td中出现一个input框:2.当离开当前tr的时候,该行退出可编辑的状态,恢复到没有hover上去之前的效果。3.当td变成可编辑状态,即出现了一个input输入框的时候,focus到input输入框中,可以输入number;当input框发生blur事件的时候,td恢复到非编辑状态:由于blur和moseleave都会让输入框恢复到非编辑的状态,所以,这里的事件会有冲突。在实际的编码中,在tr上绑定了mouseenter和mouseleave事件;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事件: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事件就会被添加两次。