可輸入/選擇的下拉框 -- 非同步編程

来源:http://www.cnblogs.com/lengxiaobao/archive/2017/08/15/7362236.html
-Advertisement-
Play Games

在實際開發開發中我們會用到各種瀏覽器、HTML、JS等提供的原生的組件/介面,但是這樣並不一定滿足我們的要求,所以我們需要自己寫一些我們需要的組件。 平常我們會經常用`select` 標簽做下拉選項,不過這個只能選擇不能手動輸入,當然網上也有很強大的select2插件,如果只要輸入和選擇兩個功能的話 ...


版權聲明:本文為博主原創文章,如要轉載或者其他合作請郵件告知我將會在24小時內回覆,郵箱:lengroubao@163.com

在實際開發開發中我們會用到各種瀏覽器、HTML、JS等提供的原生的組件/介面,但是這樣並不一定滿足我們的要求,所以我們需要自己寫一些我們需要的組件。 平常我們會經常用`select` 標簽做下拉選項,不過這個只能選擇不能手動輸入,當然網上也有很強大的select2插件,如果只要輸入和選擇兩個功能的話那麼強大的功能並不是我們需要的。這篇文章我們就來寫一個簡單實用的select

需求

需求很簡單我們要做的是兩個功能 輸入和下拉選擇,為了交互體驗更好,我們需要做動畫和事件。保證交互的流暢。而且我們還需要做一些簡單的驗證來檢測非法輸入。

交互

首先,我們要先明白要寫那些事件,通過之前的gif 我們可以看到 一共有三個事件,獲取焦點,焦點事情,點擊事件。 除了事件,還需要做一些過度,如果對相容性沒有嚴格要求的話(IE低版本)過度用CSS就好了。如果對相容性有嚴格要求那麼就用JS來寫。這裡的是用CSS3的 `transition` 來做一個0.3秒的過渡

驗證

除了交互還要驗證是否輸入了非法字元,這裡最合適的是用正則表達式來做,我們這個例子是驗證正整數 `/^[1-9]\d*$/` 如果是要驗證郵箱`/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/` 驗證只能輸入數字和英文的 `/^[0-9a-zA_Z]+$/` 如果不會正則表達式可以網上百度,基本上你需要的表達式都能查到。

具體實現

知道要做什麼了 你們就直接上代碼吧,這裡JS是重點,所有我先貼html結構和JS,CSS最後放。HTML結構

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

  這裡的li列表可以寫死可以動態渲染。 data-value是用來存數據的,比如數據的ID或者其他的什麼。 data-height是用來存ul的高度的,主要是過度動畫需要

JS 註意 這裡依賴JQ的選擇器和data()方法 可以直接用百度的CDN

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

 

獲取焦點事件(focus)

這個事件的邏輯是 獲取焦點->如果用戶還沒輸入那麼把輸入框清空方便用戶輸入 ->根據列表數計算UL高度存入data-height屬性里->然後設置高度,CSS會自動出現過度效果

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

  

失去焦點事件(blur)

這裡的邏輯很簡單 如果用戶沒有輸入就設置預設值0,否則就判斷,然後`非同步`執行關閉下拉事件。

$('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('請輸入正整數')
				alert('請輸入正整數')
			}
        }
        setTimeout(function () {
            ul.css('height',0)
        },100)
    })

  

點擊事件(click)

點擊事件就是賦值加關閉

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

  

解BUG-非同步編程

在事情焦點事件里最後的關閉一定要用非同步來做(setTimeout),否則會出BUG,因為JS是單線程的,必須先執行完blur才能執行click,但是執行blur的時候會關閉UL,導致click無法觸發(因為我們這裡有300毫秒的過度所以會有一部分能觸發click一部分不能)。為了保證交互 那段關閉UL的代碼也必須存在,所有隻能用非同步來做。 等個100毫秒,在關閉,在這100毫秒里足夠JS處理完click的事件了。 有興趣的同學可以試試不用非同步會發生什麼,或者將100毫秒縮短到1毫秒? 如果對非同步感興趣的同學可以百度“js 非同步編程”。以後我也會寫一篇關於非同步的博文。

 

組件化

對於組件化我覺得要根據實際工作環境來說: 如果用框架的可以用框架的方式來,比如NG的directive或者vue的directive之類的。 如果不用框架用了underscore之類的工具庫,也可以用_.template來寫通用的。 如果都不用,也可以用面向對象的方式抽出來。 這個組件化,根據實際開發環境來,仁者見仁智者見智。 如果 要寫成組件的話,正則表達式最好作為參數傳進去。我這裡只提供思路,並不難。

CSS

其實CSS沒啥 可以根據自己公司的風格隨便改。這裡最主要的就是下麵這段CSS

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

  transition height 就是根據height的編程做過度 用時300毫秒。 值得註意的是 transition 所根據的屬性必須是具體值,比如auto就不可以。而且這個元素也必須存在,不然也不會有效果。 下麵是完整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;
     }

  

總結

縱觀整個組件,思路理清楚了其實並不難,我覺得最有意思的就是用`setTimeout` 來做非同步處理了。

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 什麼是函數 函數是組織好的,可重覆使用的,用來實現單一,或相關聯功能的代碼段。函數能提高應用的模塊性,和代碼的重覆利用率。你已經知道Python提供了許多內建函數,比如print()。但你也可以自己創建函數,這被叫做用戶自定義函數。 python函數格式: 註意了,函數一定是有返回值,沒有返回值,就 ...
  • 題目描述 如題,現在有一個並查集,你需要完成合併和查詢操作。 輸入輸出格式 輸入格式: 第一行包含兩個整數N、M,表示共有N個元素和M個操作。 接下來M行,每行包含三個整數Zi、Xi、Yi 當Zi=1時,將Xi與Yi所在的集合合併 當Zi=2時,輸出Xi與Yi是否在同一集合內,是的話輸出Y;否則話輸 ...
  • 當資料庫中數據條數過多時,一個頁面就不能顯示,這是要設置分頁查詢,首先要使用的是資料庫sql語句的limit條件實現分組查詢sql語句大概形式為: select * from table limit 開始索引,顯示條數 用該語句就會實現分塊查詢,並且每頁顯示固定條數。首先要實現後臺分頁,我們需要知道 ...
  • php 基於socket的基本通信 1、前言 Socket是應用層與TCP/IP協議族通信的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對用戶來說,一組簡單的介面就是全部,讓Socket去組織數據,以符合指定的 ...
  • 概覽 Dubbo是阿裡巴巴SOA服務化治理方案的核心框架,每天為2,000+個服務提供3,000,000,000+次訪問量支持,並被廣泛應用於阿裡巴巴集團的各成員站點(Alibaba.com、1688.com、Aliexpress.com、阿裡雲、阿裡學院等等),自開源後,已有不少非阿裡系公司在使用 ...
  • 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 import socket 5 #創建一個socket對象 6 sk1 = socket.socket() 7 #綁定ip和埠 8 sk1.bind(('127.0.0.1', 8001)) ...
  • 在提到高性能伺服器編程的時候肯定有聽過reactor模式,如果只是簡單的寫一個伺服器和客戶端建立連接的程式來熟悉一下使用socket函數編程,一般這種情況都是同步方式實現的,伺服器阻塞等待客戶端的連接,期間伺服器不能做其他事情。是不是有更好的實現方式,讓伺服器可以提高效率,這就是反應堆模式要做的。 ...
  • 1.jQuery 語法 Tips: 通過 CDN(內容分髮網絡)引用JQuery:(link的引用最好放在script的引用之前) 獲取CDN網址:http://cdn.code.baidu.com/ jQuery 語法是為 HTML 元素的選取編製的,可以對元素執行某些操作。 基礎語法是:$(se ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...