我正在尝试制定一个时间表,我可以单击任何“时间”行并向下拖动以跨越该行,直到我“鼠标悬停”的行。例如,如果我在上午 7:30 点向下单击并向下拖动到 9:00,表数据元素将跨越适当的行数,以便表数据在该列中从 7:30 到 9:00 成为一个 block (即星期一)。这是“添加预约”按钮的功能。
我的计划是当我单击向下时存储 tr 的索引值,然后从我悬停到的 tr 的索引中减去该值(当鼠标按下时)。例如,如果我在第 1 行处向下单击,拖动到第 3 行,然后向上移动鼠标,则第一次单击的 td 的 rowspan 属性应设置为 2。
目前,我的函数将跨越多行,仅取决于我悬停的距离。所以它显然没有从点击中减去初始索引。我不知道为什么。有什么建议吗?
https://jsfiddle.net/Adam_M/fypw7jka/
这是我的时间表和按钮的 HTML:
<div class="row" id="control-panel">
<button onclick="addAppt()" id="add-appt" title="Add Appointment">+</button>
<p>= Add Appointment</p>
<button onclick="delAppt()" id="del-appt" title="Delete Appointment">-</button>
<p>= Delete Appointment</p>
</div>
<table>
<thead>
<tr class="days-of-the-week">
<th scope="col" class="time-col"></th>
<th scope="col">Sunday</th>
<th scope="col">Monday</th>
<th scope="col">Tuesday</th>
<th scope="col">Wednesday</th>
<th scope="col">Thursday</th>
<th scope="col">Friday</th>
<th scope="col">Saturday</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">7:30 AM</th>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
</tr>
<tr>
<th scope="row">8:00 AM</th>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
</tr>
<tr>
<th scope="row">8:30 AM</th>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
</tr>
<tr>
<th scope="row">9:00 AM</th>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
<td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td>
</tr>
</tbody>
</table>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script type="text/javascript" src="scheduler.js"></script>
相关函数的Javascript:
function addAppt() {
$('td').css('cursor', 'cell');
$('textarea').css('cursor', 'cell');
$('td').mousedown(function(){
var initIndex = $(this).parent().index();
$('td').hover(function(){
var spanCount = $(this).parent().index();
var span = spanCount - initIndex;
$(this).attr( 'rowspan', span);
$(this).addClass('highlight');
});
});
$('td').mouseup(function(){
$('td').off('mouseenter mouseleave');
});
}
最佳答案
这比我预想的要困难。但无论如何...
$(function() {
var $table = $("#myTable tbody");
var $rows = $table.children("tr");
var $cells = $table.find("td").not(".rowHdr");
var numCells = $cells.length;
var numRows = $rows.length;
var numCols = numCells / numRows; // skip row headings
// track which columns have rowspans by setting to 1
var matrix = new Array(numRows).fill(new Array(numCols).fill(0));
var matrix = new Array(numRows);
// init 2d matrix
for (var i = 0; i < 10; i++) {
matrix[i] = new Array(numCols);
}
//matrix[1][3] = 1; // test blocking cell
var startCol, startRow, endRow, lastValidCell;
var cellDown, cellOver, cellUp;
var mouseDown = false;
// used mouse event code from http://stackoverflow.com/a/19164149/1544886
$cells.on('mousedown touchstart', function(event) {
var cellPos;
cellDown = this;
event.preventDefault();
mouseDown = true;
cellPos = findCell(cellDown);
if (cellPos) {
startCol = cellPos.col;
startRow = endRow = cellPos.row;
highlightCells();
} else {
clearHighlights();
}
});
$cells.on('mousemove touchmove', function(event) {
event.preventDefault();
if (mouseDown && cellOver != this) {
var cellPos;
cellOver = this;
cellPos = findCell(cellOver);
if (cellPos) {
// limit to starting column only
if (cellPos.col === startCol) {
endRow = cellPos.row;
highlightCells();
}
}
}
});
$cells.on('mouseup touchend', function(event) {
var cellPos;
event.preventDefault();
cellUp = this;
cellPos = findCell(cellUp);
if (cellPos && cellUp === lastValidCell) {
createCellSpan();
}
});
$(window.document).on('mouseup touchend', function(event) {
mouseDown = false;
//cellDown = cellOver = null;
clearHighlights();
});
function findCell(cell) {
var col, row;
$cells.each(function(idx, el) {
if (cell === el) {
col = idx % numCols;
row = Math.floor(idx / numCols);
if (matrix[row][col] === 1) { // a rowspan already exists for this cell
//console.log('found', row, col);
col = null;
}
return false;
}
});
return (col != null) ? {
col: col,
row: row
} : null;
}
function highlightCells() {
clearHighlights();
if (endRow >= startRow) {
for (var row = startRow; row <= endRow; row++) {
if (matrix[row][startCol] !== 1) { // rowspan doesn't already exists for this cell
var $thisCell = $cells.eq(row * numCols + startCol);
$thisCell.addClass('highlight');
lastValidCell = $thisCell[0];
} else {
endRow = row - 1; // found a blocking cell
return false;
}
}
} else {
for (var row = startRow; row >= endRow; row--) {
if (matrix[row][startCol] !== 1) { // rowspan doesn't already exists for this cell
var $thisCell = $cells.eq(row * numCols + startCol);
$thisCell.addClass('highlight');
lastValidCell = $thisCell[0];
} else {
endRow = row + 1; // found a blocking cell
return false;
}
}
}
}
function clearHighlights() {
$cells.removeClass('highlight');
}
function createCellSpan() {
var sRow = Math.min(startRow, endRow);
var eRow = Math.max(startRow, endRow);
var rowSpan = eRow - sRow + 1;
for (var row = eRow; row >= sRow; row--) {
var $thisCell = $cells.eq(row * numCols + startCol);
if (row === sRow)
$thisCell.attr('rowspan', rowSpan).addClass('spanned');
else
$thisCell.remove();
matrix[row][startCol] = 1; // mark these cells as blocked
}
/*for (var row = sRow; row <= eRow; row++) {
var $thisCell = $cells.eq(row * numCols + startCol);
$thisCell.addClass('spanned');
matrix[row][startCol] = 1; // mark these cells as blocked
} */
}
});
.highlight {
background-color: yellow;
}
.spanned {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable" border="1" cellpadding="10">
<thead>
<tr>
<th></th>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
</tr>
</thead>
<tbody>
<tr>
<td class="rowHdr">1</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="rowHdr">2</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="rowHdr">3</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="rowHdr">4</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="rowHdr">5</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="rowHdr">6</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
关于javascript - 使用 mousedown 跨越表格的行并在 jquery 中拖动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42569531/