我正在使用带有 bootstrap 的 select2.js 版本:3.4.3 我有一个下拉菜单。
当我单击下拉菜单时,我会得到一个包含搜索文本字段的列表。
但是我的光标没有聚焦在搜索文本字段上。
<form:select path="yearAge" id="yearAgeId"
cssClass="form-control search-select static-select">
<form:option value="">Years</form:option>
<c:forEach var="i" begin="1" end="125" >
<form:option value="${i}" label="${i}"></form:option>
</c:forEach>
</form:select>
$(".search-select.static-select").select2({
placeholder: $(this).attr('placeholder'),
allowClear: true
});
当我单击下拉菜单时,指针焦点应自动设置为搜索文本字段。
如果 jQuery 3.6.0 导致了这个问题,你可以使用这个:
$(document).on('select2:open', () => {
document.querySelector('.select2-search__field').focus();
});
试试这个
$(document).on('select2:open', (e) => {
const selectId = e.target.id
$(".select2-search__field[aria-controls='select2-" + selectId + "-results']").each(function (
key,
value,
){
value.focus();
})
})
测试并使用 jQuery 3.6.0:
$(document).on("select2:open", () => {
document.querySelector(".select2-container--open .select2-search__field").focus()
})
这就是我全局修复的方法
$(document).on('select2:open', (e) => {
const selectId = e.target.id;
$(".select2-search__field[aria-controls='select2-"+selectId+"-results']").each(function (key,value,){
value.focus();
});
});
不要在 DOM 中搜索元素。相反,直接从引发
$search
事件的实例获取 select2:open
元素。由于该错误仅发生在单选时,因此您还应该排除多选:
$(document).on('select2:open', e => {
const select2 = $(e.target).data('select2');
if (!select2.options.get('multiple')) {
select2.dropdown.$search.get(0).focus();
}
});
这个问题可以通过使用 setTimeout() 函数延迟 focus() 的执行时间来解决,我们可以通过修改 select2.js 第 3321 行的函数来实现这一点
container.on('open', function () {
self.$search.attr('tabindex', 0);
//self.$search.focus(); remove this line
setTimeout(function () { self.$search.focus(); }, 10);//add this line
});
我尝试了 google 和 stackoverflow 的所有建议,并花了 4 个小时。 唯一有效的方法是将 jQuery 从 3.6 降级到 3.5
"jquery": "^3.6.0" -> "jquery": "3.5.1"
放这个就可以了,节省时间
https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js
this答案中的方法在iOS/iPadOS 15.4中失败了。
一个可行的替代方案是直接侦听父级上的单击事件并从那里激发焦点:
document.querySelector("#your-select-field-id").parentElement.addEventListener("click", function(){
const searchField = document.querySelector('.select2-search__field');
if(searchField){
searchField.focus();
}
});
对于 NPM 或 Laravel:由于我在 Laravel 应用程序中依赖 NPM 包管理器,因此我必须在 package.json 中将 jQuery 从 3.6 恢复到 3.5.1,然后运行 npm install 和 npm run prod。然后问题就解决了。
"jquery": "^3.6.0" -> "jquery": "3.5.1",
只需在调用 select2 函数后添加自定义 jQuery 行即可将焦点强制到特定搜索字段。只需将“#target”替换为搜索输入字段的 ID 即可。
$( "#target" ).focus();
$(document).on('select2:open', (e) => {
var c = e.target.parentElement.children
for (var i = 0; i < c.length; i++) {
if (c[i].tagName === 'SPAN') {
c = c[i].children
break
}
}
for (var i = 0; i < c.length; i++) {
if (c[i].tagName === 'SPAN' && c[i].className === 'selection') {
c = c[i].children
break
}
}
for (var i = 0; i < c.length; i++) {
c = c[i]
}
$(
".select2-search__field[aria-controls='select2-" +
c.getAttribute('aria-owns').replace('select2-', '').replace('-results', '') +
"-results']",
).each(function (key, value) {
value.focus()
})
})
另一种方法是:
// Find all existing Select2 instances
$('.select2-hidden-accessible')
// Attach event handler with some delay, waiting for the search field to be set up
.on('select2:open', event => setTimeout(
// Trigger focus using DOM API
() => $(event.target).data('select2').dropdown.$search.get(0).focus(),
10));
注意:触发焦点写入
.get(0).focus()
而不是 .trigger('focus')
(用于使用 DOM API),因为这不适用于 JQuery 3.6.0
我决定开发一个这样的网络应用程序
$(document).on('select2:open', '.select2', function (e) {
setTimeout(() => {
const $elem = $(this).attr("id");
document.querySelector(`[aria-controls="select2-${$elem}-results"]`).focus();
});
});
也许这有帮助:
$(document).on('select2:open', () => {
document.querySelector('.select2-container--open .select2-search__field').focus();
});