2016-08-18 302 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)); 
      } 
     } 
    } 
}