2016-08-18 328 views
0

我會說我相當體面的JavaScript和jQuery,足以讓工作做得很好。 但是我對js缺乏深刻的理解。創建一個JavaScript對象

我創建了一些突出顯示錶格元素的函數。 Ctrl +單擊切換選擇 SHIFT +單擊+拖動突出選擇

我的問題不屬於我的實現是否是最好的方法或沒有,但...

我如何抽象此功能,因此我可以將此功能添加到任何表格。就像我添加更多高亮功能等,並將其放入其自己的.js文件中一樣。我如何將它附加到任何html表格?

對不起,如果這已經回答了,但我想不出要搜索什麼。

謝謝。

****最新編碼**** 此代碼位於其自己的.js文件中,並附加到我的表格中。 所有當前的功能都在那裏。我唯一厭倦的就是.off()函數。在我的情況下,我正在重新裝載新表......當我輸入這個時,我意識到我應該從表中清空tr而不是始終重新創建一個新表,然後我可以擺脫.off()調用。

$.fn.addEvents = function(obj) 
{ 
console.log("Adding events to table"); 
var properties = $.extend(true, 
    { 
    shifting: false, 
    ctrling: false, 
    mousing: false, 
    mouseenter: 0, 
    mouseleave: 0, 
    mousestartindex: 0, 
    mouseenterindex: 0, 
    mouseleaveindex: 0, 
    trajectory: null, 
    tmptrajectory: null 
    }, obj || {}); 

$(document) 
.off('mouseup') 
.on('mouseup', function(e) 
    { 
    properties.mousing = false; 
    properties.trajectory = null; 
    }) 
.off("keyup") 
.on("keyup", function(e) 
    { 
    if(e.which == 16) 
     { 
     properties.shifting = false; 
     } 
    if(e.which == 17) 
     { 
     properties.ctrling = false; 
     } 
    }) 
.off("keydown") 
.on("keydown", function(e) 
    { 
    if(e.which == 16) 
     { 
     properties.shifting = true; 
     } 
    if(e.which == 17) 
     { 
     properties.ctrling = true; 
     } 
    if($(this).find('tr.selected').length > 0) 
     { 
     switch(e.which) 
      { 
      //case 37: // left 
       //break; 

      case 38: // up 
       var index = $(this).find('tr.selected').index(); 
       if(index > 0) 
        { 
        $(this).find('tr').removeClass('selected'); 
        $(this).find('tr td').removeClass('selected'); 
        $(this).find('tr:eq(' + index + ')').addClass('selected'); 
        $(this).find('tr:eq(' + index + ') td').addClass('selected'); 
        } 
       break; 

      //case 39: // right 
       //break; 

      case 40: // down 
       var index = $(this).find('tr.selected').index(); 
       if(index < $(this).find('tr').length - 2) 
        { 
        $(this).find('tr').removeClass('selected'); 
        $(this).find('tr td').removeClass('selected'); 
        $(this).find('tr:eq(' + (index+2) + ')').addClass('selected'); 
        $(this).find('tr:eq(' + (index+2) + ') td').addClass('selected'); 
        } 
       break; 

      case 117: // f6 
       var index = $(this).find('tr.selected').index(); 
       if(index > 0) 
        { 
        .... 
        } 
       break; 

      case 118: // f7 
       var index = $(this).find('tr.selected').index(); 
       if(index < $(this).find('tr').length - 1) 
        { 
        .... 
        } 
       break; 

      default: return; // exit this handler for other keys 
      } 
     e.preventDefault(); // prevent the default action (scroll/move caret) 
     } 
    return; 
    }); 

return $(this) 
.off('click') 
.off('contextmenu') 
.on('click', function() 
    { 
    if(!properties.ctrling && !properties.shifting) 
     { 
     $('#datatablebody tr, #datatablebody tr td').removeClass('selected'); 
     $(this).addClass('selected'); 
     $(this).find('td').addClass('selected'); 
     } 
    else if(properties.ctrling && $(this).hasClass('selected')) 
     { 
     $(this).removeClass('selected'); 
     $(this).find('td').removeClass('selected'); 
     } 
    else if(properties.ctrling && !$(this).hasClass('selected')) 
     { 
     $(this).addClass('selected'); 
     $(this).find('td').addClass('selected'); 
     } 
    }) 
.on('contextmenu', function(ev) 
    { 
    ev.preventDefault(); 
    $('#datatablebody tr, #datatablebody tr td').removeClass('selected'); 
    $(this).addClass('selected'); 
    $(this).find('td').addClass('selected'); 
    showContextMenuTR($(this).closest('tr').attr('id'), ev.clientX, ev.clientY); 
    return false; 
    }) 
.off('mousedown') 
.on('mousedown', function(e) 
    { 
    properties.mousing = true; 
    properties.mousestartindex = $(this).index(); 
    if(properties.shifting && properties.mousing) 
     { 
     multiselectrow($(this)); 
     } 
    }) 
.off('mouseenter') 
.on('mouseenter', function(e) 
    { 
    properties.mouseenter = e.clientY; 
    properties.mouseenterindex = $(this).index(); 

    if(properties.tmptrajectory === properties.trajectory) 
     { 
     if(properties.shifting && properties.mousing) 
      { 
      multiselectrow($(this)); 
      } 
     } 
    }) 
.off('mouseleave') 
.on('mouseleave', function(e) 
    { 
    properties.mouseleave = e.clientY; 

    if(properties.shifting && properties.mousing) 
     { 
     properties.tmptrajectory = properties.mouseenter - properties.mouseleave < 0?1:-1; 
     } 

    if(properties.trajectory != null && properties.tmptrajectory !== properties.trajectory && $(this).index() !== properties.mousestartindex) 
     { 
     if(properties.shifting && properties.mousing) 
      { 
      multiselectrow($(this)); 
      } 
     } 

    if(properties.shifting && properties.mousing) 
     { 
     if(properties.trajectory == null) 
      { 
      properties.trajectory = properties.tmptrajectory; 
      } 
     else if(properties.tmptrajectory !== properties.trajectory && $(this).index() === properties.mousestartindex) 
      { 
      properties.trajectory = properties.tmptrajectory; 
      } 
     } 
    }) 
.off('mouseup') 
.on('mouseup', function(e) 
    { 
    properties.mousing = false; 
    properties.trajectory = null; 
    if(properties.shifting && properties.mousing) 
     { 
     multiselectrow($(this)); 
     } 
    }); 
} 

function multiselectrow(obj) 
{ 
if($(obj).hasClass('selected')) 
    { 
    $(obj).removeClass('selected'); 
    $(obj).find('td').removeClass('selected'); 
    } 
else 
    { 
    $(obj).addClass('selected'); 
    $(obj).find('td').addClass('selected'); 
    } 
} 
+2

切換出'#datatablebody'對於某些元件(一個或多個)用戶提供。然後,將您的選擇器更改爲'$(userSelectedTable).find('tr')'等。 –

+2

@MikeC說的很多。我會採用傳遞'$ table'參數的方法,然後在整個代碼中使用它,而不是表ID。或者看看創建一個jQuery插件,然後將其稱爲(例如)$(「#datatablebody」)。addTableFunctionality()'。 [你可以在這裏閱讀這個方法。](https://learn.jquery。com/plugins/basic-plugin-creation /) – Archer

回答

2

你可以用這一切的功能,因爲你必須從@JAG與個人選擇

$.fn.addEvents = function(obj) { 
    var properties = $.extend(true, { 
     shifting: false, 
     ctrling: false, 
     mousing: false, 
     mouseenter: 0, 
     mouseleave: 0, 
     trajectory: null 
    }, obj || {}); 

    return $(this) 
     .off('click') 
     .off('contextmenu') 
     .on('click', function() { 
      ..... 
     }) 
     .on('mouseleave', function(e) { 

      //rename your local variables with `properties.` prefix 
      properties.mouseleave = e.clientY; 

      if (properties.shifting && properties.mousing) { 
       tmptrajectory = properties.mouseenter - properties.mouseleave < 0 ? 1 : -1; 
      } 

      if ($(this).hasClass('selected') && properties.shifting && properties.mousing && properties.trajectory != null && properties.trajectory != tmptrajectory) { 
       $(this).removeClass('selected'); 
       $(this).find('td').removeClass('selected'); 
      } 
      .... 
     }); 
} 

使用

$('#datatablebody tr').addEvents({ shifting: false, ctrling: true }); //custom settings 

$('#someother tr').addEvents(); //default settings 
+0

這看起來正是我所說的。我將不得不閱讀「擴展」方法。謝謝! –

+0

移位和ctrling是在「keyup」和「keydown」處理程序中進行切換的布爾值。我認爲這些也可以包裹進去。 –

+0

是的,您可以包裝與該選擇相關的所有事件。 – Jag

1

您可以添加該功能的類和類添加到您要影響的表... 在這裏,我創建類.myTableBeh和與該類所有的表將有你編程的行爲。

var shifting = false; 
    var ctrling = false; 
    var mousing = false; 
    var mouseenter = 0; 
    var mouseleave = 0; 
    var trajectory = null; 

    $('.myTableBeh tr') 
    .off('click') 
    .off('contextmenu') 
    .on('click', function() 
     { 
     if(!ctrling) 
      { 
      $('.myTableBeh tr, .myTableBeh tr td').removeClass('selected'); 
      $(this).addClass('selected'); 
      $(this).find('td').addClass('selected'); 
      } 
     else if(ctrling && $(this).hasClass('selected')) 
      { 
      $(this).removeClass('selected'); 
      $(this).find('td').removeClass('selected'); 
      } 
     else if(ctrling && !$(this).hasClass('selected')) 
      { 
      $(this).addClass('selected'); 
      $(this).find('td').addClass('selected'); 
      } 
     }) 
    .on('contextmenu', function(ev) 
     { 
     ev.preventDefault(); 
     $('.myTableBeh tr, .myTableBeh tr td').removeClass('selected'); 
     $(this).addClass('selected'); 
     $(this).find('td').addClass('selected'); 
     showContextMenuTR($(this).closest('tr').attr('id'), ev.clientX, ev.clientY); 
     return false; 
     }) 
    .off('mousedown') 
    .on('mousedown', function(e) 
     { 
     mousing = true; 
     multiselectrow($(this)); 
     }) 
    .off('mouseenter') 
    .on('mouseenter', function(e) 
     { 
     mouseenter = e.clientY; 
     multiselectrow($(this)); 
     }) 
    .off('mouseleave') 
    .on('mouseleave', function(e) 
     { 
     mouseleave = e.clientY; 

     if(shifting && mousing) 
      { 
      tmptrajectory = mouseenter - mouseleave < 0?1:-1; 
      } 

     if($(this).hasClass('selected') && shifting && mousing && trajectory != null && trajectory != tmptrajectory) 
      { 
      $(this).removeClass('selected'); 
      $(this).find('td').removeClass('selected'); 
      } 

     if(shifting && mousing && trajectory == null) 
      { 
      trajectory = tmptrajectory; 
      } 
     }) 
    .off('mouseup') 
    .on('mouseup', function(e) 
     { 
     mousing = false; 
     trajectory = null; 
     multiselectrow($(this)); 
     }); 
0

多虧了答案一些局部變量我能爲任何處理突出顯示的HTML表創建一個很好的附加。

查看小提琴的工作版本,請使用它,如果你覺得它對你的網站有幫助或有用。

你甚至可以實現按鍵在表格中上下移動tr位置。我刪除了我的實現,因爲它專用於我正在開發的項目。

我做到了這一點,所以你必須將鼠標懸停在桌子上才能與其交互,並且鼠標離開以便不重點。

https://jsfiddle.net/kwj74kg0/2/

//Add the events simply by running this 
$('#dtable tr').addEvents(0); 


/** 
* This add on can be applied and customized to any html tr set i.e. $('#tableid tr').addEvents() 
* It will add highlighting capability to the table. 
* 
* Single click highlight tr 
* Click -> Shift + click highlight/toggle range 
* Shift+MouseDown+Drag highlight/toggle range 
* Ctrl+Click toggle item 
* 
* 
* @author Michaela Ervin 
* 
* @param tabindex 
* 
* Help from JAG on http://stackoverflow.com/questions/39022116/create-a-javascript-object 
*/ 
$.fn.addEvents = function(tabindex) 
{ 
console.log("Adding events to table"); 
var properties = $.extend(true, 
    { 
    shifting: false, 
    ctrling: false, 
    mousing: false, 
    mouseenter: 0, 
    mouseleave: 0, 
    mousestartindex: 0, 
    mouseenterindex: null, 
    mouseleaveindex: null, 
    trajectory: null, 
    tmptrajectory: null 
    }, {}); 

/** 
* Add events to closest table. 
*/ 
$(this) 
.closest('table') 
.attr('tabindex', tabindex) 
.off('mouseenter') 
.on('mouseenter', function() 
    { 
    $(this).focus(); 
    }) 
.off('mouseleave') 
.on('mouseleave', function() 
    { 
    $(this).blur(); 
    properties.mousing = false; 
    properties.trajectory = null; 
    properties.mouseenterindex = null; 
    properties.mouseleaveindex = null; 
    properties.mouseintermediateindex = null; 
    }) 
.off("keyup") 
.on("keyup", function(e) 
    { 
    if(e.which == 16) 
     { 
     properties.shifting = false; 
     } 
    if(e.which == 17) 
     { 
     properties.ctrling = false; 
     } 
    }) 
.off("keydown") 
.on("keydown", function(e) 
    { 
    if(e.which == 16) 
     { 
     properties.shifting = true; 
     } 
    if(e.which == 17) 
     { 
     properties.ctrling = true; 
     } 
    if($(this).find('tr.selected').length > 0) 
     { 
     switch(e.which) 
      { 
      //case 37: // left 
       //break; 

      case 38: // up 
       var index = $(this).find('tr.selected').index(); 
       if(index > 0) 
        { 
        $(this).find('tr').removeClass('selected'); 
        $(this).find('tr td').removeClass('selected'); 
        $(this).find('tr:eq(' + index + ')').addClass('selected'); 
        $(this).find('tr:eq(' + index + ') td').addClass('selected'); 
        } 
       break; 

      //case 39: // right 
       //break; 

      case 40: // down 
       var index = $(this).find('tr.selected').index(); 
       if(index < $(this).find('tr').length - 2) 
        { 
        $(this).find('tr').removeClass('selected'); 
        $(this).find('tr td').removeClass('selected'); 
        $(this).find('tr:eq(' + (index+2) + ')').addClass('selected'); 
        $(this).find('tr:eq(' + (index+2) + ') td').addClass('selected'); 
        } 
       break; 

      case 117: // f6 
       var index = $(this).find('tr.selected').index(); 
       if(index > 0) 
        { 
        //Function to move tr 'up'. 
        } 
       break; 

      case 118: // f7 
       var index = $(this).find('tr.selected').index(); 
       if(index < $(this).find('tr').length - 1) 
        { 
        //Function to move tr 'down'. 
        } 
       break; 

      default: return; // exit this handler for other keys 
      } 
     e.preventDefault(); // prevent the default action (scroll/move caret) 
     } 
    return; 
    }); 


/** 
* Add tr specific events 
*/ 
return $(this) 
.off('click') 
.on('click', function() 
    { 
    if(!properties.shifting && properties.mouseenterindex != null) 
     { 
     properties.mouseenterindex = null; 
     properties.mousing = false; 
     } 

    if(!properties.ctrling && !properties.shifting && properties.mouseenterindex == null) 
     { 
     $(this).parent().find('tr').removeClass('selected'); 
    $(this).parent().find('tr td').removeClass('selected'); 
     $(this).addClass('selected'); 
     $(this).find('td').addClass('selected'); 
     } 
    else if(properties.ctrling && $(this).hasClass('selected')) 
     { 
     $(this).removeClass('selected'); 
     $(this).find('td').removeClass('selected'); 
     } 
    else if(properties.ctrling && !$(this).hasClass('selected')) 
     { 
     $(this).addClass('selected'); 
     $(this).find('td').addClass('selected'); 
     } 

    if(properties.mouseenterindex == null) 
     { 
     properties.mouseenterindex = $(this).index(); 
     } 
    else if(properties.shifting && properties.mouseenterindex != null) 
     { 
     properties.mouseleaveindex = $(this).index(); 
     highlightRange($(this).parent(), properties.mouseenterindex, properties.mouseleaveindex, properties.mouseenterindex); 
     properties.mouseenterindex = null; 
     properties.mouseleaveindex = null; 
     } 
    }) 
.off('contextmenu') 
.on('contextmenu', function(ev) 
    { 
    ev.preventDefault(); 
    $(this).parent().find('tr').removeClass('selected'); 
    $(this).parent().find('tr td').removeClass('selected'); 
    $(this).addClass('selected'); 
    $(this).find('td').addClass('selected'); 
    //Put your context menu here 
    return false; 
    }) 
.off('mousedown') 
.on('mousedown', function(e) 
    { 
    properties.mousing = true; 
    properties.mousestartindex = $(this).index(); 
    if(properties.shifting && properties.mousing && properties.mouseenterindex == null) 
     { 
     multiselectrow($(this)); 
     } 
    }) 
.off('mouseenter') 
.on('mouseenter', function(e) 
    { 
    properties.mouseenter = e.clientY; 

    if(properties.tmptrajectory === properties.trajectory) 
     { 
     if(properties.shifting && properties.mousing) 
      { 
      multiselectrow($(this)); 
      } 
     } 
    }) 
.off('mouseleave') 
.on('mouseleave', function(e) 
    { 
    properties.mouseleave = e.clientY; 

    if(properties.shifting && properties.mousing) 
     { 
     properties.tmptrajectory = properties.mouseenter - properties.mouseleave < 0?1:-1; 
     } 

    if(properties.trajectory != null && properties.tmptrajectory !== properties.trajectory && $(this).index() !== properties.mousestartindex) 
     { 
     if(properties.shifting && properties.mousing) 
      { 
      multiselectrow($(this)); 
      } 
     } 

    if(properties.shifting && properties.mousing) 
     { 
     if(properties.trajectory == null) 
      { 
      properties.trajectory = properties.tmptrajectory; 
      } 
     else if(properties.tmptrajectory !== properties.trajectory && $(this).index() === properties.mousestartindex) 
      { 
      properties.trajectory = properties.tmptrajectory; 
      } 
     } 
    }) 
.off('mouseup') 
.on('mouseup', function(e) 
    { 
    properties.mousing = false; 
    properties.trajectory = null; 
    if(!properties.shifting) 
     { 
     properties.mouseenterindex = null; 
     properties.mouseleaveindex = null; 
     } 
    }); 
} 

function multiselectrow(obj) 
{ 
if($(obj).hasClass('selected')) 
    { 
    $(obj).removeClass('selected'); 
    $(obj).find('td').removeClass('selected'); 
    } 
else 
    { 
    $(obj).addClass('selected'); 
    $(obj).find('td').addClass('selected'); 
    } 
} 

function highlightRange(obj, start, end, mouseenterindex) 
{ 
if(start < end) 
    { 
    for(var i=start; i<=end; i+=1) 
     { 
     if(i !== mouseenterindex) 
      { 
      multiselectrow($(obj).find('tr').eq(i)); 
      } 
     } 
    } 
else 
    { 
    for(var i=start; i>=end; i-=1) 
     { 
     if(i !== mouseenterindex) 
      { 
      multiselectrow($(obj).find('tr').eq(i)); 
      } 
     } 
    } 
}