选择2打开焦点对话框

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

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

$("#myid").select2().on('select2-focus', function(){ $(this).select2('open'); }); 

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

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

选择2焦点

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

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

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

jsFiddle和Stack Snippets中的工作演示:

 $('.select2-nosearch').select2({ minimumResultsForSearch: 20 }); $(document).on('focus', '.select2', function (e) { if (e.originalEvent) { $(this).siblings('select').select2('open'); } }); 
    

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

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

码:

 function select2Focus() { var select2 = $(this).data('select2'); setTimeout(function() { if (!select2.opened()) { select2.open(); } }, 0); } 

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

在页面上的所有select2实例上都可以轻松实现的function。

 $(document).on('focus', '.select2', function() { $(this).siblings('select').select2('open'); }); 

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

PS:还添加了filter以仅选择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'); }); } 

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

我发现的唯一方法是select2-focusselect2-blur事件以及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'); } 

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

UPDATE

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

码:

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

演示: 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'); } 

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

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

 $("#my_id").select2(); $("#my_id").next(".select2").find(".select2-selection").focus(function() { $("#my_id").select2("open"); }); 

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

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

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

问题是,内部焦点事件没有转换为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' ]; 

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

 $('#select2').on('select2:focus', function(evt){ $(this).select2('open'); }); 

适用于Chrome 54,IE 11,FF 49,Opera 40

我尝试了其中一些,最后提出了以下适合我的Select2 4.0.1。 element是元素。

 $.data(element).select2.on("focus", function (e) { $(element).select2("open"); }); 

对于我使用Select2.full.js版本4.0.3,以上解决方案都没有按照应有的方式工作。 所以我写了上面的解决方案的组合。 首先,我修改了Select2.full.js以将内部焦点和模糊事件转移到jquery事件,正如“Thomas Molnar”在他的回答中所做的那样。

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

然后我添加了以下代码来处理焦点和模糊以及聚焦下一个元素

 $("#myId").select2( ... ).one("select2:focus", select2Focus).on("select2:blur", function () { var select2 = $(this).data('select2'); if (select2.isOpen() == false) { $(this).one("select2:focus", select2Focus); } }).on("select2:close", function () { setTimeout(function () { // Find the next element and set focus on it. $(":focus").closest("tr").next("tr").find("select:visible,input:visible").focus(); }, 0); }); function select2Focus() { var select2 = $(this).data('select2'); setTimeout(function() { if (!select2.isOpen()) { select2.open(); } }, 0); } 

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'); }); } }); 

我遇到了两个问题:
1.在具有多个select2元素的表单中,下拉列表不会在选项卡上打开,您需要按空格键才能打开它
2.完成选择后,tabindex将不会被接受,您必须手动单击下一个输入字段

虽然通常的建议有效,但我提出了自己的版本,因为库脚本正在将普通选择转换为select2,因此我无法控制此初始化。

这是适合我的代码。

标签打开

 $(document).on("focus", ".select2", function() { $(this).siblings("select").select2("open"); }); 

选择时移到下一个

 var inputs = $("input,select"); // You can use other elements such as textarea, button etc. //depending on input field types you have used $("select").on("select2:close",function(){ var pos = $(inputs).index(this) + 1; var next = $(inputs).eq(pos); setTimeout( function() { next.focus(); if (next.siblings(".select2").length) { //If it's a select next.select2("open"); } }, 500); //The delay is required to allow default events to occur }); 

希望这可以帮助。

我用select2版本3.4.8尝试了这些解决方案,发现当你做blur ,select2触发首先select2-close然后select2-focus然后select2-blur ,所以最后我们最终重新打开select2。

然后,我的解决方案就是这个:

 $('#elemId').on('select2-focus', function(){ var select2 = $(this).data('select2'); if( $(this).data('select2-closed') ){ $(this).data('select2-closed', false) return } if (!select2.opened()) { select2.open() } }).on('select2-close', function(){ $(this).data('select2-closed', true) }) 

不知何故select2Focus在这里没有用空选择,无法弄清楚问题,因此我在焦点事件自动打开get触发后添加了手动控制。

这是coffeescript:

 $("#myid").select2() .on 'select2-blur', -> $(this).data('select2-auto-open', 'true') .on 'select2-focus', -> $(this).data('select2').open() if $(this).data('select2-auto-open') != 'false' .on 'select2-selecting', -> $(this).data('select2-auto-open', 'false') 

我尝试过一个非常难看的解决方案,但它解决了我的问题。

  var tabPressed = false; $(document).keydown(function (e) { // Listening tab button. if (e.which == 9) { tabPressed = true; } }); $(document).on('focus', '.select2', function() { if (tabPressed) { tabPressed = false; $(this).siblings('select').select2('open'); } }); 

这对我使用Select2 v4.0.3起作用了

 //Initialize Select2 jQuery('.js-select').select2(); // Make Select2 respect tab focus function select2Focus(){ jQuery(window).keyup(function (e) { var code = (e.keyCode ? e.keyCode : e.which); if (code == 9 && jQuery('.select2-search__field:focus').length) { jQuery('.js-select').select2('open'); } }); } select2Focus(); 

Irvin Dominin演示的分支: http : //jsfiddle.net/163cwdrw/

重要的是要始终保持多选。 最简单的方法是在代码中的’条件’上触发打开事件:

  

JavaScript的:

 $(".select2-select").select2({closeOnSelect:false}); $("#myList").select2("open"); 

小提琴: http : //jsfiddle.net/xpvt214o/153442/