繁体   English   中英

禁用Select2输入时选择当前项目

[英]Select current item when tabbing off Select2 input

这是以下类似的 SO问题和几个github问题的主题,包括:

但是建议的解决方案或问题已平等地对待所有模糊事件 ,无论如何调用它们。 对于大多数答案,通过设置selectOnClose来利用自动选择

理想情况下,仅将鼠标悬停在选项上之后单击下拉列表(转义)不应更改该值:

SelectOnClose违反最小惊奇原则

如何在跳出时更新选择,但不能更新其他关闭事件?

这是jsFiddle和StackSnippets中的MCVE:

 $('.select2').select2({}); 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script> <div class="form-control"> <label for="foods2">Select2</label> <select id="foods2" class="select2" > <option value="1">Apple</option> <option value="2">Banana</option> <option value="3">Carrot</option> <option value="4">Donut</option> </select> </div> 

这可以通过修改第323行上的原始源代码来简单地处理,该源代码对选项卡和esc键的处理相同:

if (key === KEYS.ESC || key === KEYS.TAB || (key === KEYS.UP && evt.altKey)) {
    self.close();
    evt.preventDefault();
}

但是,理想情况下,应通过请求请求来修改第三方库。 因此,在为此创建包装器时遇到了两个问题。 原则上,检测选项卡 keypress事件很难 如果我们为时已晚,可能会取代其他动作,或者将其完全发射到另一个领域。

捕获选项卡事件和保留信息的情况似乎分为两个部分:

  1. 按下制表符之前和关闭之后进行监视
  2. 拦截制表符按下并同步修改

无论哪种情况,我们都必须知道Tab键是导致菜单关闭的有问题的项目。

如果我们使用tab监听按键事件,则在打开的输入中,如果没有搜索,则它们将从.select2-selection发生;如果启用了搜索,则它们将从select2-search__field

$("body").on('keydown', e => { if (e.keyCode === 9) console.log(e.target) });

选择2选项卡事件

但是 ,如果我们像上面那样将其设置为委托处理程序,则当事件一直持续到“ body”时,菜单已经关闭,从而清除了当前突出显示的项目,甚至清除了我们是否指示我们不是从开放开始的。

我们可以通过注册select2:closing事件来在菜单关闭之前进行拦截如下所示:

$("body").on('select2:closing', e => { console.log(e,e.target) });

但是 ,select 2不会保留原始事件信息,而是创建自己的新jQueryEvent ,因此我们尚不知道是否由于tab事件而关闭( body.keypress事件随后触发)


我们将监视select2:closing事件并捕获我们需要知道的内容。 接下来,我们需要附加一个处理程序,以侦听事件管道完成后对初始单击或击键的后续触发。 对于每个关闭选项,我们只需要触发一次 为此,我们可以使用扩展名$.fn.once 如果通过标签将其抬起,它将更新在关闭期间检测到的任何值。 如果没有,该值和处理程序将消失。

总而言之,它应该像这样:

// monitor every time we're about to close a menu
$("body").on('select2:closing', function (e) {
  // save in case we want it
  var $sel2 = $(e.target).data("select2");
  var $sel = $sel2.$element;
  var $selDropdown = $sel2.$results.find(".select2-results__option--highlighted")
  var newValue =  $selDropdown.data("data").element.value;

  // must be closed by a mouse or keyboard - listen when that event is finished
  // this must fire once and only once for every possible menu close 
  // otherwise the handler will be sitting around with unintended side affects
  $("html").once('keyup mouseup', function (e) {

    // if close was due to a tab, use the highlighted value
    var KEYS = { UP: 38, DOWN: 40, TAB: 9 }
    if (e.keyCode === KEYS.TAB) {
      if (newValue != undefined) {
        $sel.val(newValue);
        $sel.trigger('change');
      }
    }

  });

});

$.fn.once = function (events, callback) {
    return this.each(function () {
        $(this).on(events, myCallback);
        function myCallback(e) {
            $(this).off(events, myCallback);
            callback.call(this, e);
        }
    });
};

jsFiddle和StackSnippets中的工作演示:

 $('.select2').select2({}); // monitor every time we're about to close a menu $("body").on('select2:closing', function (e) { // save in case we want it var $sel2 = $(e.target).data("select2"); var $sel = $sel2.$element; var $selDropdown = $sel2.$results.find(".select2-results__option--highlighted") var newValue = $selDropdown.data("data").element.value; // must be closed by a mouse or keyboard - setup listener to see when that event is completely done // this must fire once and only once for every possible menu close // otherwise the handler will be sitting around with unintended side affects $("html").once('keyup mouseup', function (e) { // if close was due to a tab, use the highlighted value var KEYS = { UP: 38, DOWN: 40, TAB: 9 } if (e.keyCode === KEYS.TAB) { if (newValue != undefined) { $sel.val(newValue); $sel.trigger('change'); } } }); }); $.fn.once = function (events, callback) { return this.each(function () { $(this).on(events, myCallback); function myCallback(e) { $(this).off(events, myCallback); callback.call(this, e); } }); }; 
 .form-control { padding:10px; display:inline-block; } select { width: 100px; border: 1px solid #aaa; border-radius: 4px; height: 28px; } 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script> <div class="form-control"> <label for="foods2">Select2</label> <select id="foods2" class="select2" > <option value="1">Apple</option> <option value="2">Banana</option> <option value="3">Carrot</option> <option value="4">Donut</option> </select> </div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM