前端angularJS利用directive實現移動端自定義軟鍵盤的方法

来源:http://www.cnblogs.com/TheKingLei/archive/2017/09/19/7554906.html
-Advertisement-
Play Games

最近公司項目的需求上要求我們iPad項目上一些需要輸入數字的地方用我們自定義的軟鍵盤而不是移動端設備自帶的鍵盤,剛接到需求有點懵,因為之前沒有做過,後來理了一下思路發現這東西也就那樣。先看一下實現之後的效果: 實現的效果就是當點擊頁面中需要彈出軟鍵盤的時候軟鍵盤彈出,浮在頁面的中間,和模態框一樣的效 ...


 

最近公司項目的需求上要求我們iPad項目上一些需要輸入數字的地方用我們自定義的軟鍵盤而不是移動端設備自帶的鍵盤,剛接到需求有點懵,因為之前沒有做過,後來理了一下思路發現這東西也就那樣。先看一下實現之後的效果:

 

實現的效果就是當點擊頁面中需要彈出軟鍵盤的時候軟鍵盤彈出,浮在頁面的中間,和模態框一樣的效果,可以在軟鍵盤中輸入任何數字,附帶的功能有小數點、退格、清空、確定等功能。當在鍵盤上點擊數字的時候頁面中的表單中實時的添加對應的數字,上圖中可以看到。

產品經理那邊給的原因是iPad屏幕本來就小,如果軟鍵盤彈出的話會占用一半的屏幕,影響產品的美觀,無奈只能想辦法搞定。

自定義的軟鍵盤使用angularJS的directive的自定義指令來做到的,angularJS的directive這裡不做解釋,如果不清楚的話可以去angular官網看看。用的是自定義一個屬性(restrict:'A'),這樣封裝過之後在需要用到軟鍵盤的時候只需要在<input>中加入自定義的屬性即可調出軟鍵盤,使用起來非常簡單,自定義的directive如下:

angular.module('ng-calculator', []).directive('calculator', ['$compile',function($compile) {
return {
restrict : 'A',
replace : true,
transclude : true,
template:'<input/>',

link : function(scope, element, attrs) {
var keylist=[1,2,3,4,5,6,7,8,9,0,'.'];
var calculator = '<div class="ngcalculator_area"><div class="bg"></div>'
+'<div class="calculator">'
+'<div class="title close">'+attrs.title+'</div><div class="inputarea">'
+'<input type="text" id="text" ng-tap="getInput()" class="'+attrs.class+'" ng-model="' +attrs.ngModel+'">'
+'</div><div class="con">'
+'<div class="left">';
$.each(keylist,function(k,v){
calculator += '<div class="keyboard num" value="'+v+'">'+v+'</div>';
});

calculator += '</div>'
+'<div class="right">'
+'<div class="keyboard blueIcon backstep"></div>'
+'<div class="keyboard blueIcon cleanup">清空</div>'
+'<div class="keyboard ensure ensure">確<br>定</div>'
+'</div>'
+'</div>'
+'</div>'
+'</div>';
calculator = $compile(calculator)(scope);
element.bind('focus',function(){
document.body.appendChild(calculator[0]);
document.activeElement.blur();
});

$(calculator[0]).find("input").focus(function(){
document.activeElement.blur();
});
//關閉模態框
$(calculator[0]).find(".close").click(function(){
calculator[0].remove();
var callback = attrs.callback;
if(typeof callback!="undefined"){
scope[callback]();
}
});
$(calculator[0]).find(".bg").click(function(){
calculator[0].remove();
});
//退格
$(calculator[0]).find(".backstep").click(function(){
if(typeof $(calculator[0]).find("input").val()=="undefined"){
$(calculator[0]).find("input").val("");
}
$(calculator[0]).find("input").val($(calculator[0]).find("input").val().substring(0,$(calculator[0]).find("input").val().length-1)).trigger('change');
});
//清空
$(calculator[0]).find(".cleanup").click(function(){
$(calculator[0]).find("input").val("").trigger('change');
});
//點擊數字
$(calculator[0]).find(".num").click(function(){
var val = $(calculator[0]).find("input").val();
var filter = attrs.filter;
if(typeof filter!="undefined"){
val = scope[filter](val,$(this).attr("value"));
}else{
val = val+''+$(this).attr("value");
}
$(calculator[0]).find("input").val(val).trigger('change');
});
//確認
$(calculator[0]).find(".ensure").click(function(){
calculator[0].remove();
var callback = attrs.callback;
if(typeof callback!="undefined"){
scope[callback]();
}
});
//點擊效果
$(calculator[0]).find(".keyboard").click(function(){
$(this).addClass("keydown");
var that = this;
setTimeout(function(){
$(that).removeClass("keydown");
},100)
});
var position = {
startX:0,
startY:0
};
calculator[0].getElementsByClassName("title")[0].addEventListener('touchstart', function(e) {
e.preventDefault();
var transform = $(calculator[0]).find(".calculator").css("transform").match(/translate\((.*),(.*)\)/);
if(transform==null){
position.startX = e.targetTouches[0].clientX;
position.startY = e.targetTouches[0].clientY;
}else{
position.startX = e.targetTouches[0].clientX-parseInt(transform[1]);
position.startY = e.targetTouches[0].clientY-parseInt(transform[2]);
}
}, false);
calculator[0].getElementsByClassName("title")[0].addEventListener('touchmove', function(e) {
e.preventDefault();
var moveX = e.targetTouches[0].clientX-position.startX;
var moveY = e.targetTouches[0].clientY-position.startY;
$(calculator[0]).find(".calculator").css("transform","translate("+moveX+"px,"+moveY+"px)");
}, false);
}
};
}]);



dom中調用如下:
<input type="text" placeholder="按價格搜索" ng-model="spaAndHairSeaInPrice" title="按價格搜索" calculator>


可以看到只是定義了一個 calculator 屬性,然後在dom中只需要加入 calculator 即可使用軟鍵盤。


我的軟鍵盤亮點:
1、calculator 調用的時候表單獲取焦點,有人會問移動端設備在獲取到焦點的時候會彈出軟鍵盤,那豈不是會出來兩個鍵盤呢?實際不然,directive中對此做了處理:

即在獲取到焦點的同事失去焦點,這樣就能完美的避免設備自帶的鍵盤。

 

2、數字鍵盤中的數據和頁面的表單中的數據實時聯動起來是通過ng-model實現的,在獲取焦點的時候directive中會獲取到ng-model的值並賦給頁面中的表單,這樣就能實現數據聯動起來,讓軟鍵盤更加完美,可參考第一張圖。

 

3、為了讓軟鍵盤點擊的時候更加逼真,在自定義的directive中對按鈕元素進行了處理,當點擊按鈕的時候給當前被點擊的元素添加一個class,效果帶陰影效果的按鈕往下移動了幾像素,看起來有點擊的效果,產品和UI沒有給我這個需求,是我自己自由發揮的,哈哈。

 

4、在項目中用到自定義的這個軟鍵盤的時候有些需要在點擊鍵盤的確定按鈕之後需要進行一些數據處理,於是後來在directive的確定安妮中中加了一個回調,我們可以在點擊確定之後調用這個回調,可以達到確定數字之後緊接著自動去執行需要執行的事件。只需要在dom中加上callback="functionItem()"即可。

 

當然如果是英文字母的話也可以用這種方法,只需要在初始的數組中寫上英文字母佈局排好即可,異曲同工而已。

以上是我寫的簡單的移動端數字鍵盤,希望對看到的人有所幫助。

如果有不足的地方還望指正大家相互交流,如果有更好的方法也請告訴我一下,作為一隻程式猿,我要碼無止境的優化我的代碼。

每天進步一丟丟。







 


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

-Advertisement-
Play Games
更多相關文章
  • 由於最近新上的項目很多模塊沒有做數據緩存,大量的請求都會到資料庫去查詢,為了減輕資料庫的壓力以及提高網站響應速度,所以在這裡採用了spring 提供的註解+redis實現對數據的緩存,主要針對非熱點數據,例如 省市,銀行卡列表等做緩存,在這裡主要是查詢做一個緩存實例。 pom.xml (加入spri ...
  • 序 好久沒寫設計模式了,自從寫了兩篇之後,就放棄治療了,主要還是工作太忙了啊(藉口,都是藉口),過完年以後一直填坑,填了好幾個月,總算是穩定下來了,可以打打醬油了。 為什麼又重新開始寫設計模式呢?學習使我快樂啊(我裝逼起來我自己都害怕),其實主要是最近填坑的時候看源代碼有點暈,很多代碼不知道他們為什 ...
  • 單例,故名思議,一個只能創建一個實例的類。 單例被廣泛應用於Spring的bean(預設)、線程池、資料庫連接池、緩存,還有其他一些無狀態的類如servlet。 一個沒必要多例的類實現了單例可以節約空間(顯而易見),節省資源(線程、資料庫連接)。 單例模式有這麼多好處,那我們來實現它吧,首先想到的是 ...
  • 報錯 原因 action與result-type順序搞錯了 package里元素必須按照一定的順序排列: result-types interceptors default-interceptor-ref default-action-ref default-class-ref global-res ...
  • 【一朝,王母娘娘設宴,大開寶閣,瑤池中做蟠桃勝會】 有一天,王母娘娘要在瑤池辦party,就需要準備大量的食材。要知道,天上的神仙也分三六九等,九曜星、五方將、二十八宿、四大天王、十二元辰、五方五老、普天星相、河漢群神等等,不同等級的神仙在宴會中吃的東西也不一樣。 為了方便管理,我們把神仙分為低級神 ...
  • 對很多創業公司而言,很難在初期就預估到流量十倍、百倍以及千倍以後網站架構會是什麼樣的一個狀況。同時,如果系統初期就設計一個千萬級併發的流量架構,很難有公司可以支撐這個成本。 因此,這裡主要會關註架構的眼花。在每個階段,找到對應該階段網站架構所面臨的問題,然後在不斷解決這些問題,在這個過程中整個架構會 ...
  • 單體應用程式通常具有一個單一的關係型資料庫。使用關係型資料庫的一個主要優點是您的應用程式可以使用 ACID 事務。很不幸的是,當我們轉向微服務架構時,數據訪問將變得非常複雜。這是因為每個微服務所擁有的數據對當前微服務來說是私有的,只能通過其提供的 API 進行訪問。封裝數據可確保微服務松耦合,獨立演... ...
  • 上篇中解釋到什麼是架構風格和應該以怎樣的視角來理解REST(Web的架構風格)。本篇來介紹一組自洽的術語,用它來描述和解釋軟體架構;以及列舉下對於基於網路的應用來說,哪些點是需要我們重點關註的。 1 軟體架構 軟體架構方面研究的是如何以最佳的方式劃分一個系統、如何標識組件、組件之間如何通信、信息如何 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...