Input/Select Dropdown Box-Asynchronous Programming

Keywords: Javascript Programming IE JQuery

Copyright Statement: This is a blogger's original article. If you want to reprint or cooperate, please email me and inform me that I will reply within 24 hours. Mailbox: lengroubao@163.com

In actual development, we will use native components/interfaces provided by various browsers, HTML, JS, etc., but this does not necessarily meet our requirements, so we need to write some components we need. Usually we often use the `select'tag as a drop-down option, but this can only be selected without manual input. Of course, there are also powerful select2 plug-ins on the Internet. If we only need to input and select two functions, then the powerful function is not what we need. In this article, we will write a simple and practical selection.

demand

The requirement is very simple. What we need to do is two function input and drop-down selection. In order to have a better interactive experience, we need to do animation and events. Ensure smooth interaction. And we also need to do some simple verification to detect illegal input.

interactive

First of all, we need to understand what events we want to write. Through the previous gif, we can see a total of three events, get the focus, focus and click on events. In addition to events, we need to do some excessive, if there is no strict requirement for compatibility (IE low version) excessive use of CSS would be good. If there are strict requirements for compatibility, then use JS to write. Here's a 0.3 second transition using CSS 3's `transition'.

Verification

In addition to interaction, we also need to verify whether illegal characters have been input. The most appropriate way to do this is regular expressions. Our example is to verify positive integers /^[[1-9]\ *$/`d*$$/``if it is to verify mailbox `/^([a-zA-Z0-Z0-Z0-Z0-9_--]+ @([a-zA-Z0-Z0-Z0-Z0-9_-----]]+//`validation can only input numbers and English /^[[^[0-9a-9a-zA-Z Z]]+ /``expressions on Baidu Internet, basically if Baidu $$/``The results of this study are as follows:1. You can find all the expressions you need.

Concrete realization

Know what to do, you can go directly to the code, where JS is the focus, all I paste the HTML structure and JS, CSS last. html structure

<div class="canInpSelection">
	<input type="text" class="canInp" name="">
	<ul class="select" data-height="">
		<li data-value='1'>1</li>
		<li data-value='2'>2</li>
		<li data-value='3'>3</li>
		<li data-value='4'>4</li>
	</ul>
</div>

The li list here can be written to death and rendered dynamically. data-value is used to store data, such as the ID of the data or something else. data-height is used to store ul's height, mainly for excessive animation needs

JS Notes that depending on JQ selectors and data() methods, Baidu CDN can be used directly.

<script type="text/javascript" src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/js/lib/jquery-1.10.2_d88366fd.js"></script>

 

Get focus events

The logic of this event is to get the focus - > Clear the input box for user input if the user hasn't entered it - > Calculate UL height according to the list number, store it in the data-height attribute - > and set the height, CSS will automatically overeffect.

$('body').on('focus ','.canInpSelection',function () {
        var ul =$(this).find('.select')
		if($(this).find('input').val() == 0){
            $(this).find('input').val('')
		}
        if(ul.data('height') == ''){
            var h= ul.find('li').length *25
            ul.data('height',h)
        }
        var ch = ul.css('height')
        var dh = ul.data('height')
        if(ch == '0px'){
            ul.css('height',dh)
        }
    })

  

Loss of focus event (blur)

The logic here is very simple. If the user does not input, set the default value of 0. Otherwise, judge. Then `asynchronous'execution closes the drop-down event.

$('body').on('blur ','.canInpSelection',function () {
        var ul =$(this).find('.select')
        var val = $(this).find('input').val()
        if(val== ''){
            $(this).find('input').val('0')
        }else{
        	var ex = /^[1-9]\d*$/;
			if(!ex.test(val)){
				$(this).find('input').val('0')
				// tips.error('Please enter a positive integer')
				alert('Please enter a positive integer')
			}
        }
        setTimeout(function () {
            ul.css('height',0)
        },100)
    })

  

click Events

Click event is assignment plus closure

$('body').on('click ','.select li',function () {
		var value = $(this).data('value')
		$(this).parent().prev().val(value)
		$(this).parent().css('height','0')
	})

  

Solving BUG-Asynchronous Programming

In event focus events, the final closure must be done asynchronously (setTimeout), otherwise BUG will be generated, because JS is single-threaded and must first complete blur before click can be executed, but when blur is executed, UL will be closed, resulting in click can not be triggered (because we have 300 milliseconds of excess, so there will be some can trigger click part can not). In order to ensure that the code for interacting to close UL must also exist, all can only be done asynchronously. Wait a hundred milliseconds, turn it off, and in that 100 milliseconds JS can handle click events. Interested students can try what happens without asynchrony, or shorten 100 milliseconds to 1 milliseconds? If you are interested in asynchronism, you can Baidu "js asynchronous programming". I will also write a blog about asynchronism in the future.

 

Component-based

For componentization, I think it should be based on the actual working environment: if you use the framework, you can use the framework approach, such as NG directive or vue directive and so on. If you don't use a tool library like underscore without a framework, you can also use. template to write generic. If not, it can also be extracted in an object-oriented way. This componentization, according to the actual development environment, different people have different opinions. If written as a component, regular expressions are best passed in as parameters. It's not difficult for me to provide ideas here.

CSS

Actually, nothing can be changed according to the style of your company. The main thing here is the following CSS

-webkit-transition: height ease-out .3s;
         transition: height ease-out .3s;

transition height takes 300 milliseconds to program according to height. It is worth noting that transition must be based on specific values, such as auto. And this element must exist, or it will not work. Here is the complete CSS

div,ul,li,input{
		box-sizing: border-box;
	}
	ul{
		list-style-type: none;
	}
	.canInpSelection{
		position: relative;
		width: 200px;
	}
	.canInp{
	    width: 100%;
	    height: 34px;
	    padding: 6px 12px;
	    font-size: 14px;
	    line-height: 1.42857143;
	    color: #555;
	    background-color: #fff;
	    background-image: none;
		border-color: #ddd;
	    border: 1px solid #ccc;
	    border-radius: 4px;
	    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
	    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
	    -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
	    -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
	    transition: border-color ease-in-out;
	    box-shadow: none;
    	-webkit-box-shadow: none;
	    -webkit-tap-highlight-color: rgba(0,0,0,0);
	}
	.select{
		position: absolute;
         top: 33px;
         left: 0px;
         right: 0px;
         background-color: #fff;
         background-image: none;
         z-index: 10;
         text-align: left;
         height:0;
		 overflow: hidden;
         -webkit-transition: height ease-out .3s;
         transition: height ease-out .3s;
         border-radius: 0 0 5px 5px;
         padding: 0;
         margin: 0;
     }
     .select li{
         height: 25px;
         line-height: 25px;
		 cursor: pointer;
         border: 1px solid #ccc;
		 border-top: 0;
		 border-bottom: 0;
         width: 100%;
         padding-left: 10px;
     }
     .select li:last-child{
		 border-bottom:1px solid #ccc;
	 }
     .select li:first-child{
         border-top:1px solid #ccc;
     }

  

summary

Throughout the whole component, it's not difficult to get the idea straight. I think the most interesting thing is to use `setTimeout'to do asynchronous processing.

Posted by homerjsimpson on Tue, 04 Jun 2019 10:34:54 -0700