在 Select2 v3 上选择值后隐藏虚拟键盘
Hide virtual keyboard after selecting value on Select2 v3
我只为我的项目使用 select2 v.3.4.5。目前,在移动设备上查看时,键盘在打开并选择值后不会关闭,我想关闭它。我只想在用户关注它并输入内容时打开它。
$(document).ready(function() {
$('#Salutation,#Gender').select2()
.on('change select-open', function(e) {
setTimeout(function() {
$('.select2-input').blur();
}, 500);
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.min.js"></script>
<div class="container">
<div class="row">
<div class="col-xs-4 col-xs-offset-4">
<h3>Application Form</h3>
<form class="form" action="/action_page.php">
<div class="form-group">
<label for="GivenName">Given Name:</label>
<input class="form-control" type="text" id="GivenName">
</div>
<div class="form-group">
<label for="Surname">Surname:</label>
<input class="form-control" type="text" id="Surname">
</div>
<div class="form-group">
<label for="Salutation">Salutation:</label>
<select class="" name="" id="Salutation">
<option value="Mrs">Mrs</option>
<option value="Mr">Mr</option>
<option value="Miss">Miss</option>
</select>
</div>
<div class="form-group">
<label for="Gender">Gender:</label>
<select class="" name="" id="Gender">
<option value="Female">Female</option>
<option value="Male">Male</option>
<option value="Transgender">Transgender</option>
</select>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
作为这个 js
$('#Salutation,#Gender').select2()
.on('change select2-open',function(e){
setTimeout(function(){
$('.select2-input').blur();
}, 500);
});
我已经将输入搜索框设置为模糊,但键盘没有关闭。
我该怎么做才能存档这个目的?请帮忙。谢谢
PS: 可以理解,select2 v4 修复了这个错误,但我无法升级我的 select2 版本,因为我的项目完全依赖于 v3。*
确保搜索框不自动对焦
在 Select2 中无法很好地做到这一点 - 每当您尝试在此输入上调用 blur()
函数时,它只会重新聚焦它。
然而,通过监听 open
事件,我们可以用我们自己的搜索框替换搜索框,它不会自动对焦。只有当前活动的搜索框有 class select2-focused
,所以我们用它来找到它,然后创建一个新的搜索框(与相同的 select2-input
class 所以它保留相同的外观),然后我们自己重新实现搜索功能,最后将其插入 DOM,并删除旧的搜索框。
关闭 selection 弹出窗口后不显示键盘
Select2 似乎试图以一种非常奇怪的方式实现它自己的 blur()
事件(参见 here)。
因此,与其尝试使用它,不如利用 CSS select 或者。 :focus
select 或 CSS select 中的任何具有焦点的内容。由于 Select2 实际上并没有添加任何新的 DOM 元素(即一旦在 HTML 中,它就变成了标准的 <div>
元素、<input>
元素等),我们可以找到一个有焦点,并成功对其调用模糊。
因此,通过调用$(":focus").blur()
,我们找到了当前有焦点的DOM元素,并对其进行了模糊处理。
此外,通过使用 select2-close
而不是 change
作为我们的事件,即使用户没有 select 一个项目,而是点击了,键盘也不会打开在它之外。
我已经测试过了,它确实适用于 iPad 运行 iOS 11。这是最终的工作代码:
$(document).ready(function() {
$("#Salutation,#Gender").select2().on("select2-open",()=>{
let oldSearchBox = $(".select2-focused")[0]; //Get the current search box
let parent = oldSearchBox.parentNode; //The parent of the search box (i.e. the element that holds it)
let search = document.createElement("input"); //Create a new input box
search.classList.add("select2-input"); //Make it look like the old one
search.addEventListener("keyup", ()=>{ //Whenever someone releases a key, filter the results
let results = parent.parentNode.getElementsByClassName("select2-result"); //Get all of the select box options
let query = search.value.toLowerCase(); //Get what the user has typed (in lower case so search is case-insensitive)
for (let result of results) { //Loop through all of the select box options
let resultText = result.children[0].childNodes[1].nodeValue.toLowerCase(); //Get the text for that option (also in lower case)
result.style.display = (resultText.indexOf(query)==-1) ? "none" : "block"; //If the result text contains the search, it is displayed, otherwise it is hidden
}
})
parent.appendChild(search); //Add the new search box to the page
oldSearchBox.remove(); //Remove the old one
});
$("#Salutation,#Gender").select2().on("select2-close",()=>{
setTimeout(()=>{
$(":focus").blur();
}, 50);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.min.js"></script>
<div class="container">
<div class="row">
<div class="col-xs-4 col-xs-offset-4">
<h3>Application Form</h3>
<form class="form" action="/action_page.php">
<div class="form-group">
<label for="GivenName">Given Name:</label>
<input class="form-control" type="text" id="GivenName">
</div>
<div class="form-group">
<label for="Surname">Surname:</label>
<input class="form-control" type="text" id="Surname">
</div>
<div class="form-group">
<label for="Salutation">Salutation:</label>
<select class="" name="" id="Salutation">
<option value="Mrs">Mrs</option>
<option value="Mr">Mr</option>
<option value="Miss">Miss</option>
</select>
</div>
<div class="form-group">
<label for="Gender">Gender:</label>
<select class="" name="" id="Gender">
<option value="Female">Female</option>
<option value="Male">Male</option>
<option value="Transgender">Transgender</option>
</select>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
我有一个替代的解决方法,我已经使用了大约一个星期了。到目前为止,它似乎在我尝试过的所有 android 和 ios 设备上都运行良好。我在 'multiple' 设置为 false(即 'single' 类型)的 select2 实例上使用它。在这种情况下,我希望用户进行单一选择,键盘应该消失。
简而言之,在 select2-close 事件期间,您设置了一个标志,指示您要禁用 select2-focusser 接收的任何焦点事件。当焦点事件被触发时,您检查标志是否已设置,如果是,您只需将焦点移动到另一个目标。我将标志添加为数据 属性 并在一秒钟后使用 setTimeOut 重置此标志。
这是有效的,因为 select2 关闭处理程序分为两部分,并且 'select2-close' 事件在第 1 部分结束时(和第 2 部分之前)触发。第 1 部分是 'abstract' 关闭处理程序,它实际上关闭了选择对话框,并设置了控件的值。第 2 部分是 'single' 关闭处理程序,它实际上只是导致 select2 重新聚焦于自身(这就是问题所在!)。
对我来说,我在我的导航栏按钮之一中添加了一个“.focus-bait”class,我用它在 focusser 的焦点事件执行期间转移焦点。如果您在使此重新聚焦步骤起作用时遇到问题,请尝试使用不同的元素(我在为聚焦目的而制作的按钮上使其起作用时遇到了问题。我仍然不确定为什么,但我没有调查更多,因为我的导航按钮解决方案非常适合我的需要)。
$('body').on('focus','.select2-focusser', function(e) {
let isDisabled = $(this).parent().first().data("disable-focus");
if (isDisabled) {
console.log('Focusser: focus event aborted');
$('.focus-bait').focus();
}
});
//select2_focus_ctrl is a class that I add to any select2 container
//that I wish to use this focus logic e.g. add it to #Salutation,#Gender
$('body').on('select2-close','select2_focus_ctrl', function(e) {
console.log('Focusser: disabling focus event');
if ($(this).data('select2').opts.multiple != true) {
$(this).prev().data("disable-focus",true);
setTimeout(function() {
console.log('Focusser: enabling focusser');
$(this).prev().data("disable-focus",false);
}, 1000);
}
});
这是完整的代码片段。在编写它时,我注意到如果 select2 容器来自 'select' 元素,则 'multiple' 属性 不存在(我使用的是 'div'),所以我已经更改了一行代码:.opts.multiple != true
(而不是 == false
)。
$(document).ready(function() {
$('#Salutation').select2(
);
$('body').on('focus','.select2-focusser', function(e) {
let isDisabled = $(this).parent().first().data("disable-focus");
if (isDisabled) {
console.log('Focusser: focus event aborted');
$('.focus-bait').focus();
}
});
$('body').on('select2-close','.select2_focus_ctrl', function(e) {
console.log('Focusser: disabling focus event');
if ($(this).data('select2').opts.multiple != true) {
$(this).prev().data("disable-focus",true);
setTimeout(function() {
console.log('Focusser: enabling focusser');
$(this).prev().data("disable-focus",false);
}, 1000);
}
});
$('body').on('change','#Salutation', function(e) {
let theVal = $('#Salutation').select2("val");
$('#currentVal').val(theVal);
});
});
body {
background: #dddddd;
padding: 20px;
font-family: Helvetica;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
cursor: pointer;
}
button:focus {
background: #fff;
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.js"></script>
<button type="button" class="focus-bait">
Just the bait!
</button>
<br>
<div>
<input id="currentVal" style="height:20px;width:150px"/>
</div>
<br><br>
<select class="select2_focus_ctrl" id="Salutation" style="width:200px;">
<option value="Mrs">Mrs</option>
<option value="Mr">Mr</option>
<option value="Miss">Miss</option>
<option value="Esquire">Esquire</option>
<option value="Other Options">Other Options</option>
<option value="Just for interest">Interesting longer item</option>
</select>
我只为我的项目使用 select2 v.3.4.5。目前,在移动设备上查看时,键盘在打开并选择值后不会关闭,我想关闭它。我只想在用户关注它并输入内容时打开它。
$(document).ready(function() {
$('#Salutation,#Gender').select2()
.on('change select-open', function(e) {
setTimeout(function() {
$('.select2-input').blur();
}, 500);
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.min.js"></script>
<div class="container">
<div class="row">
<div class="col-xs-4 col-xs-offset-4">
<h3>Application Form</h3>
<form class="form" action="/action_page.php">
<div class="form-group">
<label for="GivenName">Given Name:</label>
<input class="form-control" type="text" id="GivenName">
</div>
<div class="form-group">
<label for="Surname">Surname:</label>
<input class="form-control" type="text" id="Surname">
</div>
<div class="form-group">
<label for="Salutation">Salutation:</label>
<select class="" name="" id="Salutation">
<option value="Mrs">Mrs</option>
<option value="Mr">Mr</option>
<option value="Miss">Miss</option>
</select>
</div>
<div class="form-group">
<label for="Gender">Gender:</label>
<select class="" name="" id="Gender">
<option value="Female">Female</option>
<option value="Male">Male</option>
<option value="Transgender">Transgender</option>
</select>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
作为这个 js
$('#Salutation,#Gender').select2()
.on('change select2-open',function(e){
setTimeout(function(){
$('.select2-input').blur();
}, 500);
});
我已经将输入搜索框设置为模糊,但键盘没有关闭。
我该怎么做才能存档这个目的?请帮忙。谢谢
PS: 可以理解,select2 v4 修复了这个错误,但我无法升级我的 select2 版本,因为我的项目完全依赖于 v3。*
确保搜索框不自动对焦
在 Select2 中无法很好地做到这一点 - 每当您尝试在此输入上调用 blur()
函数时,它只会重新聚焦它。
然而,通过监听 open
事件,我们可以用我们自己的搜索框替换搜索框,它不会自动对焦。只有当前活动的搜索框有 class select2-focused
,所以我们用它来找到它,然后创建一个新的搜索框(与相同的 select2-input
class 所以它保留相同的外观),然后我们自己重新实现搜索功能,最后将其插入 DOM,并删除旧的搜索框。
关闭 selection 弹出窗口后不显示键盘
Select2 似乎试图以一种非常奇怪的方式实现它自己的 blur()
事件(参见 here)。
因此,与其尝试使用它,不如利用 CSS select 或者。 :focus
select 或 CSS select 中的任何具有焦点的内容。由于 Select2 实际上并没有添加任何新的 DOM 元素(即一旦在 HTML 中,它就变成了标准的 <div>
元素、<input>
元素等),我们可以找到一个有焦点,并成功对其调用模糊。
因此,通过调用$(":focus").blur()
,我们找到了当前有焦点的DOM元素,并对其进行了模糊处理。
此外,通过使用 select2-close
而不是 change
作为我们的事件,即使用户没有 select 一个项目,而是点击了,键盘也不会打开在它之外。
我已经测试过了,它确实适用于 iPad 运行 iOS 11。这是最终的工作代码:
$(document).ready(function() {
$("#Salutation,#Gender").select2().on("select2-open",()=>{
let oldSearchBox = $(".select2-focused")[0]; //Get the current search box
let parent = oldSearchBox.parentNode; //The parent of the search box (i.e. the element that holds it)
let search = document.createElement("input"); //Create a new input box
search.classList.add("select2-input"); //Make it look like the old one
search.addEventListener("keyup", ()=>{ //Whenever someone releases a key, filter the results
let results = parent.parentNode.getElementsByClassName("select2-result"); //Get all of the select box options
let query = search.value.toLowerCase(); //Get what the user has typed (in lower case so search is case-insensitive)
for (let result of results) { //Loop through all of the select box options
let resultText = result.children[0].childNodes[1].nodeValue.toLowerCase(); //Get the text for that option (also in lower case)
result.style.display = (resultText.indexOf(query)==-1) ? "none" : "block"; //If the result text contains the search, it is displayed, otherwise it is hidden
}
})
parent.appendChild(search); //Add the new search box to the page
oldSearchBox.remove(); //Remove the old one
});
$("#Salutation,#Gender").select2().on("select2-close",()=>{
setTimeout(()=>{
$(":focus").blur();
}, 50);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.min.js"></script>
<div class="container">
<div class="row">
<div class="col-xs-4 col-xs-offset-4">
<h3>Application Form</h3>
<form class="form" action="/action_page.php">
<div class="form-group">
<label for="GivenName">Given Name:</label>
<input class="form-control" type="text" id="GivenName">
</div>
<div class="form-group">
<label for="Surname">Surname:</label>
<input class="form-control" type="text" id="Surname">
</div>
<div class="form-group">
<label for="Salutation">Salutation:</label>
<select class="" name="" id="Salutation">
<option value="Mrs">Mrs</option>
<option value="Mr">Mr</option>
<option value="Miss">Miss</option>
</select>
</div>
<div class="form-group">
<label for="Gender">Gender:</label>
<select class="" name="" id="Gender">
<option value="Female">Female</option>
<option value="Male">Male</option>
<option value="Transgender">Transgender</option>
</select>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
我有一个替代的解决方法,我已经使用了大约一个星期了。到目前为止,它似乎在我尝试过的所有 android 和 ios 设备上都运行良好。我在 'multiple' 设置为 false(即 'single' 类型)的 select2 实例上使用它。在这种情况下,我希望用户进行单一选择,键盘应该消失。
简而言之,在 select2-close 事件期间,您设置了一个标志,指示您要禁用 select2-focusser 接收的任何焦点事件。当焦点事件被触发时,您检查标志是否已设置,如果是,您只需将焦点移动到另一个目标。我将标志添加为数据 属性 并在一秒钟后使用 setTimeOut 重置此标志。
这是有效的,因为 select2 关闭处理程序分为两部分,并且 'select2-close' 事件在第 1 部分结束时(和第 2 部分之前)触发。第 1 部分是 'abstract' 关闭处理程序,它实际上关闭了选择对话框,并设置了控件的值。第 2 部分是 'single' 关闭处理程序,它实际上只是导致 select2 重新聚焦于自身(这就是问题所在!)。
对我来说,我在我的导航栏按钮之一中添加了一个“.focus-bait”class,我用它在 focusser 的焦点事件执行期间转移焦点。如果您在使此重新聚焦步骤起作用时遇到问题,请尝试使用不同的元素(我在为聚焦目的而制作的按钮上使其起作用时遇到了问题。我仍然不确定为什么,但我没有调查更多,因为我的导航按钮解决方案非常适合我的需要)。
$('body').on('focus','.select2-focusser', function(e) {
let isDisabled = $(this).parent().first().data("disable-focus");
if (isDisabled) {
console.log('Focusser: focus event aborted');
$('.focus-bait').focus();
}
});
//select2_focus_ctrl is a class that I add to any select2 container
//that I wish to use this focus logic e.g. add it to #Salutation,#Gender
$('body').on('select2-close','select2_focus_ctrl', function(e) {
console.log('Focusser: disabling focus event');
if ($(this).data('select2').opts.multiple != true) {
$(this).prev().data("disable-focus",true);
setTimeout(function() {
console.log('Focusser: enabling focusser');
$(this).prev().data("disable-focus",false);
}, 1000);
}
});
这是完整的代码片段。在编写它时,我注意到如果 select2 容器来自 'select' 元素,则 'multiple' 属性 不存在(我使用的是 'div'),所以我已经更改了一行代码:.opts.multiple != true
(而不是 == false
)。
$(document).ready(function() {
$('#Salutation').select2(
);
$('body').on('focus','.select2-focusser', function(e) {
let isDisabled = $(this).parent().first().data("disable-focus");
if (isDisabled) {
console.log('Focusser: focus event aborted');
$('.focus-bait').focus();
}
});
$('body').on('select2-close','.select2_focus_ctrl', function(e) {
console.log('Focusser: disabling focus event');
if ($(this).data('select2').opts.multiple != true) {
$(this).prev().data("disable-focus",true);
setTimeout(function() {
console.log('Focusser: enabling focusser');
$(this).prev().data("disable-focus",false);
}, 1000);
}
});
$('body').on('change','#Salutation', function(e) {
let theVal = $('#Salutation').select2("val");
$('#currentVal').val(theVal);
});
});
body {
background: #dddddd;
padding: 20px;
font-family: Helvetica;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
cursor: pointer;
}
button:focus {
background: #fff;
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.js"></script>
<button type="button" class="focus-bait">
Just the bait!
</button>
<br>
<div>
<input id="currentVal" style="height:20px;width:150px"/>
</div>
<br><br>
<select class="select2_focus_ctrl" id="Salutation" style="width:200px;">
<option value="Mrs">Mrs</option>
<option value="Mr">Mr</option>
<option value="Miss">Miss</option>
<option value="Esquire">Esquire</option>
<option value="Other Options">Other Options</option>
<option value="Just for interest">Interesting longer item</option>
</select>