Javascript 当鼠标快速移动时,如果条件未执行

Javascript 当鼠标快速移动时,如果条件未执行,javascript,jquery,Javascript,Jquery,CSS .selected { background-color: Red; color: #ffffff; } jQuery $(document).on('mousemove', '#mytable tr', function (e) { var currentColoumn = $(e.target).closest('td').index(); if ($(this).find("td").eq(currentColoumn).hasClass('sel

CSS

.selected
{
    background-color: Red;
    color: #ffffff;
}
jQuery

$(document).on('mousemove', '#mytable tr', function (e)
{
    var currentColoumn = $(e.target).closest('td').index();
    if ($(this).find("td").eq(currentColoumn).hasClass('selected') == true) {                                     
        e.preventDefault();
        return false;
    }
});
HTML

<table border="1" id="mytable ">
   <tr>
      <td>
          9:30 AM
      </td>
      <td>
          30
      </td>
      <td>
      </td>
      <td class="selected">
          SELECTED
      </td>
      <td>
      </td>
    </tr>
</table>

上午9:30
30
挑选出来的
我必须检查tr鼠标移动中的一个条件,如果td选择了类,则鼠标移动停止。 当鼠标快速移动时,如果条件未执行


然而,有一个半解决方案是可以做到的

在主体上使用CSS隐藏实际的鼠标光标,然后在鼠标位置显示一个假鼠标指针(只是一个常规图形)

如果鼠标指针超出边界,请在边界框处停止假光标


我不知道您的用例是什么,但如果您不隐藏真实的鼠标指针,而是在边界框中显示某种超大的鼠标指针,则会更好。基本上效果相同,用户友好得多。

这里使用的
方法是将事件侦听器附加到文档,并将回调应用到
#mytable
元素行上的任何
mousemove
事件。这意味着在内部,对
上的
的调用被转换为对
委托的调用
通常,我完全支持事件授权,原因很明显(性能是最明显的)。但是,当您委派鼠标事件时,每次触发事件时都会调用处理程序。鼠标何时不在
文档中的某个位置移动?当客户端读取时,窗口最小化或不在焦点中

尽管jQuery隐藏了这一点,但您的代码实际上做到了这一点:

document.body.addEventListener('mousemove',function(e)
{
    var parent, target = (e = e || window.event).target || e.srcElement;
    if (target.tagName.toLowerCase() === 'tr')
    {//this reverse DOM lookup is probably cached, but anyway
        parent = target;
        while(parent = parent.parentNode)
        {//or something
            if (parent.getAttribute('id') === 'myTable')
            {
                break;
            }
            if (parent === document.body)
            {//not child of #myTable
                return e;
            }
        }
        if (yourCallbackFunction.apply(target, [e]) === false)
        {//remember: return false in jQ == preventDefault + stopPropagation:
            e.preventDefault();
            e.stopPropagation();
        }
    }
}, false);
只有当元素是
#myTable
的子元素时,才会调用回调,但每次鼠标移动时,都会调用事件处理程序
当委派这样的活动时,更明智的做法是:

$('#myTable').on('mousemove', 'tr', function()
{
    //your code here
});
这样,只有当mousemove事件发生在
#myTable
元素中时,才会调用事件处理程序。既然这就是你感兴趣的,那就是你应该做的

你链接到的小提琴也充满了
live
呼叫
live
已被弃用多年,原因之一是:它是Sloow。
如果速度是一个问题,另一件需要研究的事情是:避免过多的DOM调用,例如使用闭包。DOM的呼叫很慢


如果速度仍然是个问题,不要使用jQuery:如果做得好,使用VanillaJs。。。它总是比lib快

考虑一种不同的方法来决定mousemove是否应该停止突出显示单元格。而不是“当它经过选定类的单元格时停止”


如果在初始单元格和当前单元格之间存在选定类别的单元格,请尝试停止。这样可以确保,如果快速移动阻止mousemove事件被委派给“选定”单元格,它仍然能够检测到您已经通过了一个单元格。

我认为这里的主要问题是鼠标没有在每个单元格上停止。鼠标通常看起来像是在连续移动,但当我快速移动它时,它会四处跳跃,跳过中间的大量空间

我想你已经看到了这种影响。因此,您将高亮显示一系列单元格,而不仅仅是指向的单元格(当前单元格)。但是,您只检查是否选择了当前单元格,而不检查是否选择了任何中间单元格

解决方案是检查单元格之间的所有输入,以确保它们未被选中。jQuery有一个
过滤器
函数,可以很好地实现这一点。我已重构您的代码以使用筛选器:

$("#contentPlaceHolderMain_tableAppointment tr").live('mousemove', function (e) {
    // Compares with the last and next row index.
    var currentRow = $(this).closest("tr")[0].rowIndex;
    var currentColoumn = $(e.target).closest('td').index();

    var allRows = $('#contentPlaceHolderMain_tableAppointment tr');
    var previousRowIndex = parseInt(lastRow, 10);
    var currentRowIndex = parseInt(currentRow, 10);

    var traversedRows;
    if (previousRowIndex < currentRowIndex)
        traversedRows = allRows.slice(previousRowIndex, parseInt(currentRowIndex + 1));
    else {
        traversedRows = allRows.slice(currentRowIndex, previousRowIndex)
    }

    var affectedCells = traversedRows.children(':nth-child(' + parseInt(currentColoumn + 1) + ')');

    if ($(this).find("td").eq(currentColoumn).hasClass('selected') == true ||
       affectedCells.filter('.selected').length > 0) {
        if (flag != false) {
            flag = false;
            e.preventDefault();
            return false;
        }
    }
    if (currentRow == 0) {
        flag = false;
        return false;
    }
    //cross cell selection.
    if (colIndex != currentColoumn) {
        flag = false;
        return;
    }

    if (flag) {
        affectedCells.addClass('csstdhighlight');
        e.preventDefault();
        return false;
    }
});
$(“#contentPlaceHolderMain_tableAppointment tr”).live('mousemove',函数(e){
//与上一行和下一行索引进行比较。
var currentRow=$(this).closest(“tr”)[0].rowIndex;
var currentcolumn=$(e.target).closest('td').index();
var allRows=$('#contentPlaceHolderMain_tableAppointment tr');
var-previousRowIndex=parseInt(最后一行,10);
var currentRowIndex=parseInt(currentRow,10);
var横穿方向;
if(上一行索引<当前行索引)
traversedRows=allRows.slice(previousRowIndex,parseInt(currentRowIndex+1));
否则{
traversedRows=allRows.slice(currentRowIndex,previousRowIndex)
}
var-affectedCells=traversedRows.children(':n第n个子项('+parseInt(currentcolumn+1)+');
if($(this).find(“td”).eq(CurrentColumn).hasClass('selected')==true||
affectedCells.filter('.selected')。长度>0){
如果(标志!=假){
flag=false;
e、 预防默认值();
返回false;
}
}
如果(currentRow==0){
flag=false;
返回false;
}
//跨细胞选择。
if(colIndex!=currentcolumn){
flag=false;
返回;
}
国际单项体育联合会(旗){
addClass('csstdhighlight');
e、 预防默认值();
返回false;
}
});
小提琴在:


仍然存在一个问题,即某些单元格应该高亮显示,但它们不是。现在您已经有了所选单元格的行,您可以重做切片逻辑,在正确的位置进行切片。我将把这一部分留给你。

请注意,如果这正是你的目标,那么它应该很容易适应。使用鼠标悬停可以减少通话次数,应该有更好的性能

摆弄:

$(文档).ready(函数(){
//设置
var doc=这个;
doc.checkOver=false;
doc.activeCell={
x:-1,
y:-1
};
doc.lastCell={
x:-1,
y:-1
};
doc.highlightClass='csstdhighlight';
doc.selectionClass='已选择';
doc.selectionText='已选定';
//开始检查mousedown
$('contentPlaceHolderMain'u tableAppointment td')。on('mousedown',函数(e){
doc.checkOver=true;
//
jQuery(function($) {
    document.onselectstart = function () { return false; }

    var $table = $('#contentPlaceHolderMain_tableAppointment'),
    columns = [],
    dragInfo = null;

    $table.find('td').each(function() {
        var i = $(this).index();
        (columns[i] = columns[i] || []).push(this);
    });
    $table.on('mouseup', function() {
        // reset selection
        dragInfo = null;
    });
    $table.on('mousedown', 'td', function() {
        var $this = $(this),
        columnIndex = $this.index();

        if ($this.is('.selected') || columnIndex < 2) {
            return;
        }

        var thisRow = $this.parent().index(),
        selectionRowAbove = -Infinity,
        selectionRowBelow = Infinity;

        $.each(columns[columnIndex], function(rowIndex) {
            if ($(this).is('.selected')) {
                if (rowIndex < thisRow && rowIndex > selectionRowAbove) {
                    selectionRowAbove = rowIndex;
                } else if (rowIndex > thisRow && rowIndex < selectionRowBelow) {
                    selectionRowBelow = rowIndex;
                }
            }
        });
        // unmark cells
        $table.find(".csstdhighlight").removeClass("csstdhighlight");

        dragInfo = {
            column: columnIndex,
            enclosure: {
                above: selectionRowAbove,
                below: selectionRowBelow
            },
            min: thisRow,
            max: thisRow
        };

        $this.addClass('csstdhighlight');
    });
    $table.on('mousemove', 'td', function() {
        if (!dragInfo) {
            return;
        }

        var $this = $(this),
        columnIndex = $this.index(),
        rowIndex = $this.parent().index();

        if (columnIndex != dragInfo.column || rowIndex == 0 ||  rowIndex <= dragInfo.enclosure.above || rowIndex >= dragInfo.enclosure.below) {
            dragInfo = null;
            return;
        }
        // mark cells
        var cells = [columns[columnIndex][rowIndex]];
        while (dragInfo.min > rowIndex) {
            cells.push(columns[columnIndex][dragInfo.min--]);
        }
        while (dragInfo.max < rowIndex) {
            cells.push(columns[columnIndex][dragInfo.max++]);
        }
        $(cells).addClass('csstdhighlight');
    });
});