当前位置: 首页 > 编程日记 > 正文

一个数字键盘引发的血案——移动端H5输入框、光标、数字键盘全假套件实现...

https://juejin.im/post/5a44c5eef265da432d2868f6

为啥要写假键盘?

还是输入框、光标全假的假键盘?

手机自带的不用非得写个假的,吃饱没事干吧?

装逼?炫技?

宝宝也是被逼的,宝宝也很委屈~.~

问题产生背景

移动端H5项目需求点:

进入某页面自动弹出带小数点的数字键盘,并且自带输入验证,比如金额——只能输入数字和小数点,并且只能输入一位小数点、小数位不超过2位,且输入前验证不合法就不让输入、(UE特加功能——定制光标颜色>.<简直是反人类的需求)。细分如下:

  • 进入相关页面,输入框自动获取焦点
  • 键盘自动弹出
  • 弹出带小数点的数字键盘
  • 数字输入前自动验证,只能输入一个小数点,小数位数不超过2位,超过就不能继续输入
  • 如果光标在第一位,此时键入的是'.',则自动放入'0'再插入'.'

实现方案拟定

1. 基于input + 手机自带键盘实现方案

(1)针对功能点1,可以给 input 设置属性 autofocus , 输入框就能自动聚焦。 轻松搞定

(2)针对功能点2 ,给input设置属性 autofocus 会自动聚焦但是键盘并不会自动弹出;

必须手动点击输入框键盘才会弹出; 于是在进入页面的时候用js触发click或者foucus,发现键盘也不会自动弹出,延时click、focus也没能弹出;那么只有最后一种方案——就是让NA端提供让键盘弹出的方法。 纯前端无法搞定,需要NA端协助/,或者找PM砍掉自动弹键盘的需求>.<(勉强能够接受)

(3)针对功能点3,弹数字键盘的方法可以设置 type = "number" 或者type = "tel"; 前者在Andriod可以弹出数字键盘在ios端只能弹全键盘,后者在Android和ios弹出的都是数字键盘,但是!!坑爹的,弹出的数字键盘没有小数点!(我的华为荣耀9倒是很给力的给我弹了个带小数点的数字键盘,不容易啊啊) 只能选择type = "number",勉强能接受ios弹全键盘吧

(4)针对功能点4, 设置type = "number",发现可以不停的输入小数点啊啊啊啊看着真的要疯了,第一次输入小数点也不能自动变成'0.'

图1 原生input type=number 效果

这时候聪明的你一定想到要使用事件监听键入的字符,在输入之前进行判断,然后决定是否放入输入框。

你肯定又会开心的想到一堆可能有用的事件:onkeydown,onkeyup,onchange,oninput,onpropertychange,textInput。

路漫漫其修远兮啊~经过不断尝试之后仍然发现很多问题。

  • onkeyup——虽然每增加删除字符都会触发,但增加字符的时候是值输入之后才触发,无法做到输入前验证;
  • onchange——是在内容改变(两次内容有可能相等)且失去焦点时触发,也无法做到输入前验证。
  • onpropertychange——onchange事件在内容改变(两次内容有可能还是相等的)且失去焦点时触发;即每增加或删除一个字符就会触发,通过js改变也会触发该事件,但是该事件IE专有。
  • oninput——移动端很多手机不支持。

(只剩下onkeyup/textInput,还有一线希望刚芭蕾>.<。)

  • onkeyup——其事件有两个相关属性event.key和event.keyCode。event.key在我的华为荣耀9手机上都不生效(其他低版本手机可想而知)。但其还有一个属性event.keyCode其在PC端的值是键入字符的ascii码。但在手机端输入任何数字或者小数点其值均为229(华为荣耀9测试),所以onkeyup也不能用。

  • ontextInput——在pc和移动端都支持!!!(功夫不负有心人)其event.data可以获取到输入的值。欢天喜地,举国欢庆,啊哈哈~~

终于松了一口气,只要能在输入前获取值就能验证了呀。

自信满满的一口气写完验证过程:

html

<inputid="amount-input"autofocustype="number"@textInput="checkNumber"v-model="amount" require/> 复制代码

js

checkNumber(event) {var key = event.data || '';if (key.search(/[0-9\.]/) > -1) {var value = document.getElementById('amount-input').value;if (key === '.' && value.search(/\./) > -1) { event.preventDefault(); } if (value.search(/\.\d{2}/) > -1) { event.preventDefault(); } } else { event.preventDefault(); } }, 复制代码

杯具再次发生了~~~~~我所期望的效果仍然没有达到。

通过value获取输入框内所有字符失败

发现input type = number 取到的value只能是数值,无法获取输入框里的所有字符。

也就是说如果输入'12.',通过value获取到是'12',只输入'.',value获取到的是' '空字符串,获取不到小数点。这样就无法判断是否输入小数点,因而不能判断是否还能输入小数点,那就还是能输入无数个小数点,问题依然得不到解决。

尝试:

  • 使用VUE中双向绑定的this.amount来获取输入的所有字符,发现this.amount获取到的和value获取值的情况相同。尝试失败。
  • 通过textInput获取到的输入值,自己维护一个字符数组。但是textInput在删除时不会触发,因而不能实时获取input输入框里面的所有准确字符;而且由于无法获取光标在input输入框的具体位置而无法确定删除的是哪个字符,因而字符数组无法准确维护。尝试失败。

(5)针对功能点5,功能4解决了,功能5是小case。。。

所以基于input + 手机自带键盘实现方案要满足以上需求难以实现

2. 基于input + 假数字键盘实现方案

若是用假键盘加原生input输入框,需要做到:

  • 禁用手机自带键盘
  • 获取Input输入框中的内容

禁用手机自带键盘,在没有NA暴露的方法支持的情况下,可以设置Input的readonly属性。这样的话输入框也不能添加删除字符了。若在可以要NA端提供禁用手机自带键盘的方法的前提下,要实现点击假键盘输入框能添加删除字符。

若是只从后面添加删除,很容易实现,只需要将点击键盘对应的字符拼接到Input type=text获取到的value的后面,删除同理。但是要是光标不在最后一位,而是在中间

 图2 光标在数字中间示例图
复制代码

那么当我们点击假键盘添加或删除字符的时候,如何能知道添加或删除字符的位置呢。也许需要获取光标位置。目前只有IE和火狐支持的document.selection,selectionStart可以获取光标位置。

// 获取光标位置
function getCursortPosition (textDom) {var cursorPos = 0;if (document.selection) {// IE SupporttextDom.focus ();var selectRange = document.selection.createRange();selectRange.moveStart ('character', -textDom.value.length);cursorPos = selectRange.text.length;}else if (textDom.selectionStart || textDom.selectionStart == '0') { // Firefox support cursorPos = textDom.selectionStart; } return cursorPos; } 复制代码

由于我们的是移动端H5开发项目,考虑兼容性,显然以上方法不能兼容大部分的机型。

3. 输入框、光标、数字键盘全假实现方案

以上两种方案均难以实现,因此我只能大胆想象,要实现满足以上需求的假键盘就得实现假输入框、假光标、假keyboard的一套装备。这样所有的元素我都能控制,上面的那些问题全部可以解决。

雏形若是实现只能从最后面增加删除没有光标的假键盘非常容易,只需要给每个键绑定一个click事件,维护一个数组,每次从后面push或者pop就能维护输入框中的内容。

 图3 只能从最后添加、删除且没有光标的效果图
复制代码

但是这样跟正真的输入框效果比体验太差了。

难点

要实现体验跟原生键盘一样并且自带输入验证的假键盘,难点主要在于:

  • 有光标,且光标闪动
  • 光标定位,点击数字中间光标自动移过去
  • 根据光标的位置实现插入删除
  • 失去焦点光标隐藏,点击输入框光标显示并且弹出键盘

原生js实现

对于光标实现,创造一个元素设置背景色,可以控制它隐藏和出现。

对于“点击数字中间光标自动移过去 ”,可以每添加一个数字或者小数点就先加一个带点击事件的空元素space,再添加要输入的字符。space是为了绑定一个点击事件,告诉光标要移动到的位置。

//字符插入,在光标前插入字符
function insert(value) {var span = document.createElement("span"); //创建包含值的元素span.className = 'val';span.innerText = value;var space = document.createElement("span");space.className = 'space'; space.addEventListener('click', moveCursor); var cursor = document.getElementsByClassName('cursor')[0]; inputArea.insertBefore(space, cursor);//插入空列 inputArea.insertBefore(span, cursor);//插入值 } 复制代码

删除时也是先删除光标之前的数字字符,再删除space元素。

//删除元素
function deleteElement() {setCursorFlash();var cursor = document.getElementsByClassName('cursor')[0]; var n = 2; //两个删除动作 while(cursor.previousSibling && n > 0) { inputArea.removeChild(cursor.previousSibling ); n--; } if(getInputStr().search(/^\.\d*/) > -1) { insert(0); } if(getInputStr() === ''){ //元素为空placeholder显示 var placeHolder = document.getElementsByClassName('holder')[0]; placeHolder.className = 'holder'; } } 复制代码

通过chrome里面元素审查可以看到添加删除的过程。

图4 添加、删除、光标移动元素变化图
复制代码

每一个space元素都绑定一个click事件,用来移动光标,最右边有个right-space可以用来放placeholder,也可以添加click事件,点击时光标总是移到最后一位。

//移动光标位置
function moveCursor(event) {var cursor = document.getElementsByClassName('cursor')[0];//获取光标if(event.currentTarget.className == 'right-space'){if(!cursor.nextSibling || cursor.nextSibling.nodeName == '#text'){ return; } else { var ele = cursor.nextSibling; inputArea.insertBefore(inputArea.lastElementChild, ele); inputArea.appendChild(cursor); } }else { var tempEle = event.currentTarget.nextSibling; // var nodeName = event.currentTarget.nextSibling.nodeName; // var cursor = document.getElementsByClassName('cursor')[0]; if(!tempEle || tempEle.nodeName == '#text') { var temp = event.currentTarget.previousSibling; var ele = inputArea.replaceChild( event.currentTarget, cursor);//把光标替换成当前元素 inputArea.appendChild(ele); } else { var temp = event.currentTarget.nextSibling; var ele = inputArea.replaceChild( event.currentTarget, cursor);//把光标替换成当前元素 inputArea.insertBefore(ele, temp); } } } 复制代码

从上面的GIF图可以看出,光标始终只有一个而且有个定时任务。光标的闪动设置如下,使用原生的setInterval实现。

//设置光标定时任务
function setCursorFlash() {//placeholder 隐藏var placeHolder = document.getElementsByClassName('holder')[0];placeHolder.className = 'holder hidden'; var cursor = document.getElementsByClassName('cursor')[0]; var inputContainer = document.getElementsByClassName('input-container')[0]; cursor.className = "cursor"; var isShowCursor = true; inputContainer.focus(); showKeyBoard(); if (intervalId) { clearInterval(intervalId); } intervalId = setInterval(function() { isShowCursor = !isShowCursor; if (isShowCursor) { cursor.className = 'cursor'; } else { cursor.className = 'cursor hidden'; } }, 1000); } 复制代码

最终使用原生js实现的带输入框、光标,keyboard的假数字键盘。

除了完成以上功能,还实现了输入前验证功能,为了跟接近真实输入框表现,同时实现了点击

输入框获取焦点、光标闪动、弹出键盘;失去焦点光标消失。

为什么不使用jQuery?

一是因为,当前的H5项目没有使用jQuery。

二是因为使用VUE之后很少需要直接操作DOM,少数方法自己实现更轻量,若是只为了使用

其一两个方法而引入jQuery,会使得项目更重。

原生js实现效果

图5 原生js实现输入框、光标、键盘全假套件效果图 源码github.com/DaisyWang88…

手机扫码验证: sandbox.runjs.cn/show/mvjrca…(chrome插件url二维码生成器GetCrx.cn)

由于移动端click事件有300毫秒延时,因此原生js实现的效果,有点不是很流畅。若使用原生JS实现版的需要使fastclick或zepto的tap事件解决延时问题。

PS:之前说‘VUE本身解决300毫秒延时问题’,考证之后发现不对,给大家带来困扰实在抱歉。

考证之后发现VUE的click事件都是原生的click并没有处理这个延时。为了不让大家困扰,github上的demo已经使用fastClick解决了延时问题,(之前太懒了>.<)。现在原生的js实现效果也很顺畅了。

VUE组件化

考虑到项目里有的应用场景有多个输入框,当然输入的时候只需要一个键盘,因此组件化的时候将输入框作为一个组件v-input,键盘作为一个组件v-keyboard。

输入框和键盘的交互

交互图如下:

 图6 VUE组件交互图
复制代码

考虑到本项目里面存在一个页面多个输入框的场景,因此需要控制键盘与哪个输入框配合使用。

为了达到这样的目的,采用“当点击输入框获取焦点的时候,将当前v-input输入框组件的实例传给v-keyboard键盘组件”的方式。

this.$refs.virtualKeyBoard.$emit('getInputVm', this.$refs.virtualInput); 如图6 ,v-keyboard组件会监听'getInputVm'事件,获取v-input的实例。

键盘组件v-keyboard获取到输入框组件v-input的实例之后就可以根据键盘的点击事件——添加或删除,操作输入框组件v-input来放入或者删除字符了。

这样即使有多个输入框,也方便控制键盘和输入框之间的操作。

输入框自动获取焦点,键盘自动弹出

需求里要求进入某个页面输入框自动获取焦点,键盘自动弹出。

  • 输入框自动获取焦点可以通过设置is-auto-focus来控制是否自动获取焦点。
<v-inputref="virtualInput"v-model="amount":placeholder="placeText":is-auto-focus="true"@show-key-board="showKeyBoard"> </v-input> 复制代码
  • 要自动弹出键盘如图6,需要在页面实例化完成之后将相应的输入框组件v-input的实例传给键盘组件v-keyboard。
this.$refs.virtualKeyBoard.$emit('getInputVm', this.$refs.virtualInput);
复制代码

键盘组间捕获'getInputVm'事件之后获取了相应输入框的实例,同时自动弹出。

this.$on('getInputVm', function(obj) {this.refObject = obj;this.isShow = true;
});
复制代码

v-model支持

vue支持自定义v-model,子组件设置一个value 的 props。

props: {value: {type: String,default: '',},
}
复制代码

在value改变的时候$emit一个'input'事件并把相应的值传出去就可以实现v-model的双向绑定了。this.getInputStr()是用来获取输入框中字符串的函数。

this.$emit('input', this.getInputStr());
复制代码

效果如下:

源码参见github.com/DaisyWang88…。

总结

原生的input 设置type =number,想要做输入前验证控制小数点个数和小数位数等功能基本很难实现,要在输入前取到值也是存在各种兼容性问题,目前只有ontextInput在移动端能在输入前准确取到值,还有个关键的问题type =number的时候取到的value不包含小数点,导致输入前使用正则验证几乎无法实现;若是设置type= text 虽然能取到输入框中所有字符,但是就无法弹出数字键盘。要想使用原生input输入小数,就必须有所取舍。

  • 要么不做输入前验证,使用type = number ,可以输入多个小数点,只在数值数值不合法的时候提示输入不合法,但是只有android可以弹出数字键盘,IOS仍然弹出全键盘。用户体验可能差些。
  • 要么使用type = text,虽然可以做到输入前验证(因为可以取到全部字符),但是所有机型都只会弹全键盘了,用户体验也一般。
  • 以上两种都无法实现进入页面键盘自动弹出,只能借助NA提供的方法实现。
  • 如果你是强迫症癌晚期患者,用户体验之上者,那么你就可以跟我一样做个假键盘,这样以上问题都不是问题。还可以添加附加功能,比如输入的时候若在第一位输入小数点的时候,前面自动补'0';删除的时候,若小数点在第一位前面自动补'0';还可以定制光标颜色、键盘样式等等。

很不幸,我就是一个强迫症癌晚期患者,目前实现的键盘套件改造成VUE组件已经成功在项目中使用,有单输入框的页面,也有多输入框的页面,支持placeholder 和v-model。


作者:百度外卖大前端技术团队
链接:https://juejin.im/post/5a44c5eef265da432d2868f6
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载于:https://www.cnblogs.com/chaoyuehedy/p/9530380.html

相关文章:

姿态检测 树莓派_怎样在树莓派上轻松实现深度学习目标检测?

原标题&#xff1a;怎样在树莓派上轻松实现深度学习目标检测&#xff1f;雷锋网按&#xff1a;本文为 AI 研习社编译的技术博客&#xff0c;原标题 How to easily Detect Objects with Deep Learning on Raspberry Pi&#xff0c;作者为 Sarthak Jain。翻译 | 小哥哥 狒狒 校对…

Linux目录读写和可执行权限

一 . 进入目录权限如果我在普通用户下创建了一个目录f1&#xff0c;然后使用chomd u-rwx,g-rwx,o-rwx之后&#xff0c;我在普通用户下想进入f1目录&#xff0c;权限不允许。然后我切换到超级用户下&#xff0c;再次尝试进入到f1目录&#xff0c;这个时候允许进入。然后回到普通…

【译】表变量和临时表的比较(转)

关于表变量是什么&#xff08;和表变量不是什么&#xff09;&#xff0c;以及和临时表的比较让很多人非常困惑。虽然网上已经有了很多关于它们的文章&#xff0c;但我并没有发现一篇比较全面的。在本篇文章中&#xff0c;我们将探索表变量和临时表是什么&#xff08;以及不是什…

grub加密。

一、介绍 安全无小事 linux系统的安全分为很多方面&#xff0c;什么端口啊&#xff0c;什么网络啊&#xff0c;听着都特么烦&#xff0c;今天谈谈最简单明显的密码安全。 二、单用户模式 单用户模式个人觉得相当有用&#xff0c;可以用来修复系统&#xff0c;修改密码…… 但是…

Linux下stat + 文件名后, Access,Modify,Change的含义

我们首先在一个目录下创建了一个文件使用命令touch file然后输入命令&#xff1a;stat file&#xff0c;这个时候会输出一系列信息大家注意红色框中的三个时间Access : 文件最近一次被访问的时间Modify: 文件内容最近一次被修改的时间Change: 文件属性最近一次被改变的时间接着…

基于设计模式的学习之旅-----访问者模式(附源码)

基于设计模式的学习之旅-----访问者模式 1、初始访问者模式 2、什么是访问者模式 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 3、模式结构图 4、模式代码事例 场景&#xff1a;年会&#xff0c;每个小组表演…

x is y python_Python 基础

2.1 程序与用户交互在python3中#input&#xff1a;无论用输入何种类型&#xff0c;都会存成字符串类型nameinput(please input your name:) #name18print(id(name),type(name),name)在python2中#raw_input与python3的input是一样的nameraw_input(please input your name:)print…

【leetcode 简单】 第八十九题 赎金信

给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串&#xff0c;判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成。如果可以构成&#xff0c;返回 true &#xff1b;否则返回 false。 (题目说明&#xff1a;为了不暴露赎金信字迹&#xff0c;要从杂…

创建专属博客栏目

今天给大家get新技能了&#xff0c;是不是很期待捏我们一般看到的博客页面是这样的但是你是不是特别期待这样的捏其实技术上面也不是特别的 难&#xff0c;我们登录自己的csdn博客&#xff0c;然后选择“管理博客”&#xff0c;跳转页面之后选择“博客栏目”进入到这个页面之后…

《帝企鹅日记》观后感

第一次看到是在高中的英语周报上&#xff0c;那时候蛮好奇的&#xff0c;企鹅也写日记&#xff0c;呵呵&#xff0c;后来想了想应该是纪录片&#xff0c;时隔三年&#xff0c;发现当初的猜测果然不假。 我觉得那些企鹅很可爱&#xff0c;也很漂亮。最重要的是&#xff0c;那一条…

合并道路_资质改革已经确定!盘点被合并的资质!有这资质的要注意了

资质改革可以说是在行业里掀起了轩然大波&#xff0c;众多资质面临改革&#xff0c;有的资质被取消&#xff0c;有的资质被合并&#xff0c;有的资质继续保留。此文就带大家来盘点一下那些在近期资质定稿中被取消&#xff0c;被改变的资质&#xff1a;勘察资质勘察资质中&#…

如何为ccflow工作流引擎增加一个优先级PRI?

为什么80%的码农都做不了架构师&#xff1f;>>> 如何为ccflow工作流引擎增加一个优先级PRI&#xff1f; 对于一条流程的优先级可分为 低&#xff0c;中&#xff0c;高三个级别&#xff0c;用这个状态来标示这条流程的紧急程度。 以以前版本的ccflow中是以节点表…

SQL Server (MSSQLSERVER) 服务因 2148081668 服务性错误而停止。

https://zhidao.baidu.com/question/151448005.html 具体步骤&#xff1a;运行-> 输入&#xff1a;“services.msc” ->找到 “SQL Server (SQLEXPRESS)” 服务&#xff0c;双击 -> 在“SQL Server (SQLEXPRESS) 的属性”界面&#xff0c;点登录 -> 默认登录身份是…

面试题--特别是字节对齐

来源&#xff1a;http://www.cnblogs.com/Braveliu/archive/2013/01/04/2844757.html 【1】设置或者清除某位。 示例代码如下: 1 #include<iostream>2 using namespace std;3 4 #define BIT3 (0x1<<3)5 6 void Set_bit3(int &a)7 {8 a|BIT3;9 } 10 11…

vim基础入门

一. vim的三种模式在Linux操作系统下&#xff0c;我们一般会使用vim进行文本编辑&#xff0c;它相当于Windows下的记事本&#xff0c;但是它比记事本的功能强大的多。vim一般有三种模式分别是普通模式&#xff0c;编辑模式和命令模式。普通模式和编辑模式可以来回的切换&#x…

python html解析查找字符串_用python的BeautifulSoup分析html

序言之前用python爬取网页的时候&#xff0c;一直用的是regex或者自带的库sgmllib里的SGMLParser。但是遇到复杂一点的情况时&#xff0c;SGMLParser往往就不那么给力了&#xff01;(哈&#xff0c;难道说我 too native了&#xff1f;毕竟beautifulSoup是继承sgmlparser的么~)所…

ejb 3中bean的种类

会话bean(session bean) 主要用来编写业务逻辑和对数据库进行操作&#xff0c;Session Bean用于实现业务逻辑&#xff0c;它分为有状态bean和无状态bean。每当客户端请求时&#xff0c;容器就会选择一个Session Bean来为客户端服务。Session Bean可以直接访问数据库&#xff0…

Android学习 —— 数据的存储与访问方式一: 文件存取

笔记摘要&#xff1a; 在Android中主要提供了四种数据存储与访问的方式&#xff0c;文件、SharedPreference&#xff08;偏好参数保存&#xff09;、SOLite数据库、内容提供者&#xff08;Content provider&#xff09;和网络&#xff0c; 本篇文章先介绍使用文件的方式进行数据…

react的安装使用

react的重要思想是通过组件来开发应用&#xff0c;而组件就是能够完成某个特定功能而独立、可复用的代码。 react是可以像JQuery那样直接下载引入使用&#xff0c;也可以直接引用官网提供的CDN的地址&#xff1a; <script src"https://unpkg.com/react16/umd/react.dev…

锐捷交换机配置snmp版本_snmp交换机配置

华为交换机1、查询交换机当前是snmp配置命令dis cur2、进入全局模式 int ethernet1/0/7 shutdown 关 undoshutdown 激活sys3、进入SNMP配置snmp-agent4、配置只读字符串snmp-agent community read abcd5、配置写字符串snmp-agent community write abcd6、开启snmp版本支持功能 …

Linux命令find的35个实例

注&#xff1a;本文内容参考《35 Practical Examples of Linux Find Command》 网址&#xff1a;http://www.tecmint.com/35-practical-examples-of-linux-find-command/ Linux 查找命令是Linux系统中最重要和最常用的命令之一。查找用于根据与参数匹配的文件指定的条件来搜索…

PHP使用APNS的 feedback service

http://blog.csdn.net/gnicky/article/details/7544202 1. URL是不一样的&#xff0c;端口是2196 2. 使用同样的Certificate&#xff0c;建立安全连接&#xff0c;接受数据&#xff0c;直到数据不存在&#xff0c;类似table select操作 3.每条纪录是一个token&#xff0c;serve…

洛谷——P2341 [HAOI2006]受欢迎的牛//POJ2186:Popular Cows

P2341 [HAOI2006]受欢迎的牛/POJ2186:Popular Cows 题目背景 本题测试数据已修复。 题目描述 每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶 牛都是自恋狂&#xff0c;每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜 欢…

学习使用Bing Maps Silverlight Control(五):离线使用和自定义地图模式

6 离线使用 在笔记第一部分的时候就提到如果要使用Bing Maps Silverlight Control 进行开发&#xff0c;需要申请一个key&#xff0c;不让会显示一个错误提示出来。但是在实际开发或使用过程中&#xff0c;使用环境和地图数据可能不是在线的&#xff0c;但控件因为验证失败仍然…

python123第k序元素查找_Python实现折半查找并用matplotlib实现动态过程可视化

折半查找是算法中减治策略的基本例子&#xff0c;实现起来也很简单&#xff0c;但是在网上看到的图片教程不觉得很乾巴麽&#xff1f;&#xff1f;在这里插入图片描述这是一个简单的实现&#xff1a;def Reduction(lists, k):""":param lists: 元素列表:param k…

vim进阶技巧

本篇博文是在之前的《vim基础入门》的基础之上写的&#xff0c;不懂的同学可以先看之前的分享 1. 视觉范围的选择 普通模式下&#xff0c;按v键确定范围起点&#xff0c;然后移动光标&#xff0c;光标所在位置为范围的终点&#xff0c;然后按操作键完成其他操作&#xff0c;之…

Flex Air程序打包成独立的exe安装文件

2019独角兽企业重金招聘Python工程师标准>>> 开发背景&#xff1a; FlexBuilder3.2开发生成的Air程序需要能够独立安装&#xff0c;事先不需要安装AdobeAir运行环境 实现方法&#xff1a; 1)用winrar打开xx.air文件爱能&#xff0c;并将它解压在D:\airapp目录中。 2…

《C++primer》第一章--开始

之前开始读《Cprimer》&#xff0c;想着读书不动笔不如不读书&#xff0c;于是就想做一个读书笔记的内容&#xff0c;于是就想起了写一个《Cprimer读思录》的一个专栏。一是为了给自己平时读书做笔记&#xff0c;方便自己随时查看。二是为了督促自己每天学习。三是为了知识的分…

对于计算机网络的整体框架的概括(转载) 个人感觉很好

作者&#xff1a; 阮一峰 日期&#xff1a; 2012年5月31日 我们每天使用互联网&#xff0c;你是否想过&#xff0c;它是如何实现的&#xff1f; 全世界几十亿台电脑&#xff0c;连接在一起&#xff0c;两两通信。上海的某一块网卡送出信号&#xff0c;洛杉矶的另一块网卡居然就…

Centos修改系统语言

使用man page帮助时&#xff0c;发现居然是中文的&#xff0c;不过想想即便英语再水&#xff0c;也要逼着自己去适应。于是百度找了一下修改系统语言的方法。 首先使用 locale 命令查看当前的系统语言 然后修改时一般有两种方法&#xff0c;一是临时修改&#xff0c;立即生效&a…