在“多选”中对选项进行排序时,滚动条不会移动

Scroll bar does not move when sorting options in MultiSelect

本文关键字:排序 滚动条 移动 多选 选项      更新时间:2023-09-26

我有一个多选框,右边有两个按钮,它们在列表中上下排序一个选项。这很好,但如果我将选项向上或向下移动到多选的顶部或底部边界,滚动条将不会生效并相应移动。有什么建议吗?

JavaScript:

$(document).ready(function() {
  $("#mup")[0].attachEvent("onclick", moveUpItem);
  $("#mdown")[0].attachEvent("onclick", moveDownItem);
});
function moveUpItem() {
  $('#list option:selected').each(function() {
    $(this).insertBefore($(this).prev());
  });
}
function moveDownItem() {
  $('#list option:selected').each(function() {
    $(this).insertAfter($(this).next());
  });
}
//Holding down the Up/Down buttons
$(document).ready(function() {
  var timer;
  $("#mup, #mdown").on('mousedown', function() {
    if (this.id === 'mup') {
      timer = setInterval(moveUpItem, 250);
    } else {
      timer = setInterval(moveDownItem, 250);
    }
  }).on('mouseup', function() {
    clearInterval(timer);
  });
});
$(document).ready(function() {
  $("#submit").click(function() {
    $("#list").each(function() {
      $("#list option").attr("selected","selected");
    });
    $("#detColumnSortorder").submit;
  });
});

HTML:

<table>
  <tr>
    <td align="center">
      <select id="list" name="fieldNames" size="15" multiple="multiple" style="width: 250px;">
        <c:forEach var="field" items="${detFields}">
          <option value="${field.fieldName}">${field.displayName}</option>
        </c:forEach>
      </select>
    </td>
    <td>
      <button id="mup">
        <img src="../images/button_up.gif" alt="Hold to move up faster."/>
      </button>&nbsp;&nbsp;&nbsp;
    </td>
    <td>
      <button id="mdown">
        <img src="../images/button_down.gif" alt="Hold to move down faster."/>
      </button>
    </td>
  </tr>
  <tr>
    <td style="text-align: center;">
      <input name="action" id="submit" type="submit" value="Submit"/>
      <input name="action" type="submit" value="Cancel"/>
    </td>
  </tr>
</table>

哇,这很有趣。Chrome/WebKit在选择中处理选项移动的方式似乎存在一些错误。我不完全确定当前的行为是什么。有时它会移动,有时它不会。

所以,我想,简单。。。我只需要编写一个快速的解决方法。事实证明,这并不那么容易。WebKit不提供对某些信息的javascript访问,例如选项高度等。

所以,经过几次变通后,我有了一个似乎有效的破解方法:

http://jsfiddle.net/jtbowden/7NEqk/

照它的价值来对待。基本上,代码在选择框的可见窗口中跟踪所选项目。如果顶部在可见窗口上方,则向上移动等

注意事项:

  1. 向下移动.get().reverse()时,您需要反向迭代选定的选项,否则,如果您有相邻的选定项目,您只需让它们交换位置,而不是向下移动。(12下方移动,然后21下方移动)
  2. 如果浏览器没有返回选项元素的高度,那么我假设高度为17。这是我的最佳猜测,但你可以调整它。此外,这意味着你的选择不能有不同的高度。无论如何,我认为这在WebKit中是不可能的
  3. 在移动所选项目之前,我会检查与之交换的项目是否已选中。如果是,我不会交换。这可以防止当我们到达选择的底部或顶部时,选择进行交换,在那里没有任何可交换的内容。这与我在注释#1中所说的类似,但情况略有不同
  4. 我假设所有的选择都符合选择框架。如果它们不起作用,它仍然有效,但根据你想要的,它可能会有不同的处理方式
  5. 我将return false;放入mousedown处理程序中。这与event.preventDefault()等相同。它可以防止按钮从选择中窃取焦点,在Chrome中,这会使所选选项变为灰色,而不是正常的蓝色

当然,在说了所有这些之后,可能有一个更好的方法来管理这个选择系统。。。但是,我认为这是一个挑战,让它以我认为应该的方式工作。

附言:谁知道IE……我没有检查,我害怕。