簡體   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