Javascript: 防止选择时打开下拉菜单

Javascript: prevent dropdown open when selecting

我想防止在选择单元格范围时打开下拉菜单。 我知道,我可以添加一个 onmousedown 事件并调用 event.preventDefault()

问题是这也会禁用单击事件的下拉菜单。有没有办法区分范围的选择(鼠标按下而不立即释放)和单击单个单元格(鼠标按下并释放)? 我也尝试过 onselectstart 但在这种情况下它对我没有帮助。

这里是一个小演示: https://jsfiddle.net/vqsv99t4/2/

我已经根据您的需要更新了您的代码。

  1. 禁用文本选择:已从 Javascript 移除至 CSS

    .noselect {
      -webkit-touch-callout: none; /* iOS Safari */
        -webkit-user-select: none; /* Chrome/Safari/Opera */
         -khtml-user-select: none; /* Konqueror */
           -moz-user-select: none; /* Firefox */
            -ms-user-select: none; /* Internet Explorer/Edge */
                user-select: none; /* Non-prefixed version, currently
                                      not supported by any browser */
    }
    

    来源:

  2. 停止从 <td>document 的事件冒泡:event.stopPropagation() 将停止冒泡事件以记录 mousemove()mouseup() 监听器

  3. Logic:存储选择开始的第一个单元格(单元格上的mousedown()事件)。然后,检查选择停止的单元格(mouseup() 事件)。

  4. 已修改 HTML 以便更好地使用。

  5. 在单元格上添加了 data- 属性以存储行列信息

2016-11-11 更新

  1. 添加了 jQuery-UI Selectmenu 来替换 <select>

    Reason: <select> dropdown can't be triggered using JavaScript/JQuery.

//console.clear();

var BUTTON_LEFT = 1,
  BUTTON_RIGHT = 2;

var startCell = null;


(function() {

  $("#select").selectmenu();

  $(".mouse-event-cell")
    .on('mousedown', onMouseDown)
    .on('mouseup', onMouseUp)
    .on('mousemove', onMouseOver);
  $(document)
    .on('mousemove', onDocMouseOver)
    .on('mouseup', onDocMouseUp);
})();

function onDocMouseOver(e) {
  if (e.buttons !== BUTTON_LEFT) {
    startCell = null;
    clearFill();
  }
}

function onDocMouseUp(e) {
  if (e.buttons !== BUTTON_LEFT) {
    startCell = null;
    clearFill();
  }
}

function onMouseDown(e) {
  isInsideCell = true;

  if (startCell === null)
    startCell = e.currentTarget;
};

function onMouseOver(e) {
  if (startCell !== null) {
    fill(startCell, e.currentTarget, 'region');
  }
  e.stopPropagation();
}

function onMouseUp(e) {
  var endCell = e.currentTarget;

  if (startCell !== null) {
    fill(startCell, endCell, 'selected');
  }

  startCell = null;
  e.stopPropagation()
}

function fill(startCell, endCell, classToAdd) {
  var col0 = startCell.dataset['column'],
    row0 = startCell.dataset['row'],
    col1 = endCell.dataset['column'],
    row1 = endCell.dataset['row'],
    colMin = Math.min(col0, col1),
    colMax = Math.max(col0, col1),
    rowMin = Math.min(row0, row1),
    rowMax = Math.max(row0, row1);

  clearFill();

  if (startCell === endCell) {
    console.log('same-cell');
  } else {
    console.log('range-of-cell');
  }

  //console.log(startCell, endCell);


  for (var itCol = colMin; itCol <= colMax; itCol++) {
    for (var itRow = rowMin; itRow <= rowMax; itRow++) {
      $('#codexpl .mouse-event-cell#cell_' + itRow + '_' + itCol).addClass(classToAdd);
    }
  }
}

function clearFill() {
  $('#codexpl .mouse-event-cell').removeClass('selected').removeClass('region');
}
.ui-selectmenu-button.ui-button {
  width: 5em;
}
select {
  width: auto;
}
table {
  border-collapse: separate;
}
td.mouse-event-cell {
  border: 1px solid #ddd;
  padding: 2px 10px;
  height: 30px;
  /*To disable the text selection*/
  -webkit-touch-callout: none;
  /* iOS Safari */
  -webkit-user-select: none;
  /* Chrome/Safari/Opera */
  -khtml-user-select: none;
  /* Konqueror */
  -moz-user-select: none;
  /* Firefox */
  -ms-user-select: none;
  /* Internet Explorer/Edge */
  user-select: none;
  /* Non-prefixed version, currently
                                  not supported by any browser */
}
td.selected {
  background-color: goldenrod;
  color: white;
}
td.region {
  border-style: dashed;
  border-color: #BBB;
}
<!DOCTYPE html>
<html>

<head>
  <meta name="description" content="selecting multiple cells">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>

  <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

  <link href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
  <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
  <script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>

</head>

<body>
  <table id="codexpl">
    <tr>
      <th>#</th>
      <th>Columna</th>
      <th>Relative</th>
      <th>Isso</th>
    </tr>
    <tr>
      <td id="cell_0_0" data-row="0" data-column="0" class='mouse-event-cell'>
        <select id="select">
          <option value="volvo">Volvo</option>
          <option value="saab">Saab</option>
          <option value="mercedes">Mercedes</option>
          <option value="audi">Audi</option>
        </select>
      </td>
      <td id="cell_0_1" data-row="0" data-column="1" class='mouse-event-cell'>cell[0][1]</td>
      <td id="cell_0_2" data-row="0" data-column="2" class='mouse-event-cell'>cell[0][2]</td>
      <td id="cell_0_3" data-row="0" data-column="3" class='mouse-event-cell'>cell[0][3]</td>
      <td id="cell_0_4" data-row="0" data-column="4" class='mouse-event-cell'>cell[0][4]</td>
    </tr>
    <tr>
      <td id="cell_1_0" data-row="1" data-column="0" class='mouse-event-cell'>cell[1][0]</td>
      <td id="cell_1_1" data-row="1" data-column="1" class='mouse-event-cell'>cell[1][1]</td>
      <td id="cell_1_2" data-row="1" data-column="2" class='mouse-event-cell'>cell[1][2]</td>
      <td id="cell_1_3" data-row="1" data-column="3" class='mouse-event-cell'>cell[1][3]</td>
      <td id="cell_1_4" data-row="1" data-column="4" class='mouse-event-cell'>cell[1][4]</td>
    </tr>
    <tr>
      <td id="cell_2_0" data-row="2" data-column="0" class='mouse-event-cell'>cell[2][0]</td>
      <td id="cell_2_1" data-row="2" data-column="1" class='mouse-event-cell'>cell[2][1]</td>
      <td id="cell_2_2" data-row="2" data-column="2" class='mouse-event-cell'>cell[2][2]</td>
      <td id="cell_2_3" data-row="2" data-column="3" class='mouse-event-cell'>cell[2][3]</td>
      <td id="cell_2_4" data-row="2" data-column="4" class='mouse-event-cell'>cell[2][4]</td>
    </tr>
    <tr>
      <td id="cell_3_0" data-row="3" data-column="0" class='mouse-event-cell'>cell[3][0]</td>
      <td id="cell_3_1" data-row="3" data-column="1" class='mouse-event-cell'>cell[3][1]</td>
      <td id="cell_3_2" data-row="3" data-column="2" class='mouse-event-cell'>cell[3][2]</td>
      <td id="cell_3_3" data-row="3" data-column="3" class='mouse-event-cell'>cell[3][3]</td>
      <td id="cell_3_4" data-row="3" data-column="4" class='mouse-event-cell'>cell[3][4]</td>
    </tr>
    <tr>
      <td id="cell_4_0" data-row="4" data-column="0" class='mouse-event-cell'>cell[4][0]</td>
      <td id="cell_4_1" data-row="4" data-column="1" class='mouse-event-cell'>cell[4][1]</td>
      <td id="cell_4_2" data-row="4" data-column="2" class='mouse-event-cell'>cell[4][2]</td>
      <td id="cell_4_3" data-row="4" data-column="3" class='mouse-event-cell'>cell[4][3]</td>
      <td id="cell_4_4" data-row="4" data-column="4" class='mouse-event-cell'>cell[4][4]</td>
    </tr>
  </table>
</body>

</html>