2

我仅将 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。*

4

2 回答 2

2

确保搜索框不会自动对焦

在 Select2 中没有办法很好地做到这一点 - 每当您尝试blur()在此输入上调用该函数时,它只会重新聚焦它。

但是,通过监听open事件,我们可以用我们自己的替换搜索框,它不会自动对焦。只有当前活动的搜索框有类select2-focused,所以我们用它来找到它,然后创建一个新的搜索框(具有相同的select2-input类,所以它保持相同的外观和感觉),然后自己重​​新实现搜索功能,最后将其插入 DOM,并删除旧的搜索框。

关闭选择弹出窗口后不显示键盘

Select2 似乎试图blur()以一种非常奇怪的方式实现它自己的事件(参见此处)。

因此,与其尝试使用它,不如利用 CSS 选择器。CSS 中的:focus选择器选择任何有焦点的东西。由于 Select2 实际上并没有添加任何新的 DOM 元素(即一旦在 HTML 中,它就变成了标准<div>元素、<input>元素等),我们可以找到具有焦点的那个,并成功地对其调用 blur。

因此,通过调用$(":focus").blur(),我们找到了当前具有焦点的 DOM 元素,并对其进行了模糊处理。

此外,通过使用select2-close作为我们的事件,而不是change,即使用户没有选择一个项目,而是在它之外单击,键盘也不会打开。


我已经对其进行了测试,它确实适用于运行 iOS 11 的 iPad。这是最终的工作代码:

$(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>

于 2018-08-25T03:38:53.203 回答
0

我有一个替代工作,我已经使用了大约一周。到目前为止,它似乎在我尝试过的所有 android 和 ios 设备上都运行良好。我在'multiple'设置为false(即'single'类型)的select2实例上使用它。在这种情况下,我希望用户进行一次选择,并且键盘应该消失。

简而言之,在 select2-close 事件期间,您设置了一个标志,指示您要禁用 select2-focusser 接收到的任何焦点事件。当触发焦点事件时,您检查是否设置了标志,如果设置了,您只需将焦点移动到另一个目标。我将标志添加为数据属性,并在一秒钟后使用 setTimeOut 重置此标志。

这是因为 select2 关闭处理程序分为 2 部分,并且在第 1 部分结束时(和第 2 部分之前)触发了“select2-close”事件。第 1 部分是“抽象”关闭处理程序,它实际上关闭选择对话框,并设置控件的值。第 2 部分是“单一”关闭处理程序,它实际上只是导致 select2 重新关注自身(这是问题所在!)。

对我来说,我在我的导航栏按钮之一中添加了一个“.focus-bait”类,并在焦点事件执行期间使用它来转移焦点。如果您在使此重新聚焦步骤起作用时遇到问题,请尝试不同的元素(我无法让它在我为专注于而制作的按钮上工作。我仍然不确定为什么,但我没有进行更多调查,因为我的导航按钮解决方案非常适合我的需求)。

$('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>
          

于 2018-10-03T23:03:02.367 回答