选择2打开焦点对话框

and*_*tor 29 jquery jquery-select2

我有一个包含多个文本输入和一些select2元素的表单.使用键盘在字段之间切换工作正常 - Select2元素的行为类似于表单元素,并在Tab键时获得焦点.我想知道当Select2元素获得焦点时是否可以打开下拉列表.

这是我到目前为止所尝试的:

$("#myid").select2().on('select2-focus', function(){
     $(this).select2('open');
});
Run Code Online (Sandbox Code Playgroud)

但是使用此代码会在选择后再次打开下拉列表.

Kyl*_*Mit 32

其中一个问题是,一旦打开,该tab键将关闭select2下拉列表并重新聚焦窗口小部件,这可以在尝试打开所有焦点事件的下拉列表时设置无限循环.

选择2焦点

一个技巧是寻找焦点事件类型之间的差异,如果我们从浏览器获得一个bonified焦点事件,则只打开下拉列表 - 而不是通过查看原始事件由jQuery生成的焦点事件.

所以我们可以像这样修改rain01的原始代码:

// on first focus (bubbles up to document), open the menu
$(document).on('focus', '.select2-selection.select2-selection--single', function (e) {
  $(this).closest(".select2-container").siblings('select:enabled').select2('open');
});

// steal focus during close - only capture once and stop propogation
$('select.select2').on('select2:closing', function (e) {
  $(e.target).data("select2").$selection.one('focus focusin', function (e) {
    e.stopPropagation();
  });
});
Run Code Online (Sandbox Code Playgroud)

jsFiddle和Stack Snippets中的工作演示:

$(this).siblings('select:enabled').select2('open');
Run Code Online (Sandbox Code Playgroud)
$('.select2').select2({});

// on first focus (bubbles up to document), open the menu
$(document).on('focus', '.select2-selection.select2-selection--single', function (e) {
  $(this).closest(".select2-container").siblings('select:enabled').select2('open');
});

// steal focus during close - only capture once and stop propogation
$('select.select2').on('select2:closing', function (e) {
  $(e.target).data("select2").$selection.one('focus focusin', function (e) {
    e.stopPropagation();
  });
});
Run Code Online (Sandbox Code Playgroud)

在Chrome,FF,Edge,IE11上测试过


小智 26

我尝试了@ irvin-dominin-aka-edward的答案,但也遇到了两个问题(必须点击下拉两次,并且Firefox抛出'事件未定义').

我确实找到了解决这两个问题的解决方案,但还没有遇到其他问题.这是基于@ irvin-dominin-aka-edward的答案,通过修改select2Focus函数,使得不是立即执行其余代码,而是将其包装在setTimeout中.

码:

$('.select2').select2({})
  .one('select2-focus', OpenSelect2)
  .on("select2-blur", function (e) {
    $(this).one('select2-focus', OpenSelect2)
  })

function OpenSelect2() {
  var $select2 = $(this).data('select2');
  setTimeout(function() {
    if (!$select2.opened()) { $select2.open(); }
  }, 0);  
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到一个演示:http://jsfiddle.net/mtLUp/156/


rai*_*n01 22

可以在页面上的所有select2实例上使用的简单方法.

$(document).on('focus', '.select2', function() {
    $(this).siblings('select').select2('open');
});
Run Code Online (Sandbox Code Playgroud)

更新:上面的代码似乎在IE11/Select2 4.0.3上无法正常工作

PS:还添加了过滤器以仅single选择选择字段.选择带multiple属性不需要它,如果应用可能会中断.

var select2_open;
// open select2 dropdown on focus
$(document).on('focus', '.select2-selection--single', function(e) {
    select2_open = $(this).parent().parent().siblings('select');
    select2_open.select2('open');
});

// fix for ie11
if (/rv:11.0/i.test(navigator.userAgent)) {
    $(document).on('blur', '.select2-search__field', function (e) {
        select2_open.select2('close');
    });
}
Run Code Online (Sandbox Code Playgroud)


Irv*_*nin 17

可能在选择之后select2-focus触发事件.

我发现的唯一方法是select2-focusselect2-blurevent以及jQuery one事件处理程序的组合.

因此第一次元素获得焦点时,select2被打开一次(因为一个),当元素模糊时,一个事件处理程序再次附加,依此类推.

码:

$('#test').select2({
    data: [{
        id: 0,
        text: "enhancement"
    }, {
        id: 1,
        text: "bug"
    }, {
        id: 2,
        text: "duplicate"
    }, {
        id: 3,
        text: "invalid"
    }, {
        id: 4,
        text: "wontfix"
    }],
    width: "300px"
}).one('select2-focus', select2Focus).on("select2-blur", function () {
    $(this).one('select2-focus', select2Focus)
})

function select2Focus() {
    $(this).select2('open');
}
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/IrvinDominin/fnjNb/

UPDATE

要让鼠标单击工作,您必须检查触发处理程序的事件,它必须open仅在事件发生时触发该方法focus

码:

function select2Focus() {
    if (/^focus/.test(event.type)) {
        $(this).select2('open');
    }
}
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/IrvinDominin/fnjNb/4/

SELECT2 V 4.0的更新

select2 v 4.0已更改其API并删除了自定义事件(请参阅https://github.com/select2/select2/issues/1908).所以有必要改变检测焦点的方式.

码:

$('.js-select').select2({
    placeholder: "Select",
    width: "100%"
})

$('.js-select').next('.select2').find('.select2-selection').one('focus', select2Focus).on('blur', function () {
    $(this).one('focus', select2Focus)
})

function select2Focus() {
    $(this).closest('.select2').prev('select').select2('open');
}
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/IrvinDominin/xfmgte70/


小智 9

有点晚了...但是要使用select2 4.0.0分享我的代码

$("#my_id").select2();
$("#my_id").next(".select2").find(".select2-selection").focus(function() {
    $("#my_id").select2("open");
});
Run Code Online (Sandbox Code Playgroud)


Mat*_*ier 6

这是Select2版本4.x的替代解决方案.您可以使用侦听器捕获焦点事件,然后打开选择.

$('#test').select2({
    // Initialisation here
}).data('select2').listeners['*'].push(function(name, target) { 
    if(name == 'focus') {
        $(this.$element).select2("open");
    }
});
Run Code Online (Sandbox Code Playgroud)

根据@tonywchen创建的示例,找到这里的工作示例


小智 5

问题是,内部焦点事件未转换为jQuery事件,因此我修改了插件,并将焦点事件添加到Select2 4.0.3的2063行的EventRelay中:

EventRelay.prototype.bind = function (decorated, container, $container) {
    var self = this;
    var relayEvents = [
      'open', 'opening',
      'close', 'closing',
      'select', 'selecting',
      'unselect', 'unselecting',
      'focus'
    ];
Run Code Online (Sandbox Code Playgroud)

然后在焦点发生时打开select2就足够了:

$('#select2').on('select2:focus', function(evt){
    $(this).select2('open');
});
Run Code Online (Sandbox Code Playgroud)

在Chrome 54,IE 11,FF 49,Opera 40上运行良好


小智 5

KyleMit 的回答对我有用(谢谢!),但我注意到对于允许搜索的 select2 元素,尝试使用 Tab 键切换到下一个元素是行不通的(Tab 键顺序实际上丢失了),所以我添加了代码来设置焦点当下拉列表关闭时到主 select2 元素:

$(document).on('focus', '.select2', function (e) {
    if (e.originalEvent) {
        var s2element = $(this).siblings('select');
        s2element.select2('open');

        // Set focus back to select2 element on closing.
        s2element.on('select2:closing', function (e) {
            s2element.select2('focus');
        });
    }
});
Run Code Online (Sandbox Code Playgroud)