代码之家  ›  专栏  ›  技术社区  ›  Houy Narun

在Select2 v3上选择值后隐藏虚拟键盘

  •  2
  • Houy Narun  · 技术社区  · 6 年前

    我只为我的项目使用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>

        $('#Salutation,#Gender').select2()
        .on('change select2-open',function(e){
            setTimeout(function(){
                $('.select2-input').blur();
            }, 500);
        });
    

    我已将输入搜索框设置为模糊,但键盘未关闭。

    我怎样才能把这个目的存档?请帮忙。谢谢。

    注:可以理解,select2 v4修复了这个错误,但是我无法升级select2版本,因为我的项目完全依赖于v3*

    2 回复  |  直到 6 年前
        1
  •  2
  •   toastrackengima    6 年前

    确保搜索框不自动对焦

    无论何时您尝试调用 blur() 对这个输入函数,它只是重新聚焦它。

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

    Select2似乎试图实现自己的 模糊() 以一种非常奇怪的方式发生(参见 here ).

    所以,与其尝试使用它,不如利用CSS选择器。这个 :focus CSS中的选择器选择任何有焦点的内容。由于Select2实际上没有添加任何新的DOM元素(即,一旦进入HTML,它就成为标准 <div> 元素, <input>

    因此,通过调用 $(":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>
        2
  •  0
  •   mhepton    6 年前

    我有一个替代的工作,我已经用了大约一个星期了。到目前为止,它似乎在我尝试过的所有安卓和ios设备上都运行良好。我在将“multiple”设置为false(即“single”类型)的select2实例上使用此选项。在这种情况下,我希望用户只做一个选择,键盘应该消失。

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

    这是因为select2 close处理程序被分成两部分,而“select2 close”事件在第1部分末尾(在第2部分之前)触发。第1部分是“抽象”关闭处理程序,它实际上关闭了选择对话框,并设置控件的值。第2部分是“单个”关闭处理程序,它实际上只会导致select2重新关注自己(这就是问题所在!)。

    对我来说,我在导航栏的一个按钮上添加了一个“.focus bait”类,在focusser的focus事件执行期间,我使用这个类来转移焦点。如果您在让这个重新聚焦步骤开始工作时遇到问题,请尝试其他元素(我在让它在我为集中精力而制作的按钮上工作时遇到问题)。我仍然不知道为什么,但我没有调查更多,因为我的导航按钮解决方案非常适合我的需要)。

    $('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>
              
    推荐文章