js仿微博实现统计字符和本地存储功能


Posted in Javascript onDecember 22, 2015

随着移动设备和Web应用的普及,为了更好的便于用户的使用,对于网页或应用程序的用户体验要求就越来越高,确实是这样,作为用户更喜欢选择用户体验效果好的网站或应用程序,所以作为开发者的我们就需要开发出更人生化的应用程序了。

相信许多人有使用微博的经验,像微博这样的社交平台,好的用户体验就变得尤其重要了。

例如:我们在发微博时,文本框会实时地提示我们剩余字符数,这样人性化的提示方便了用户知道微博字数的限制,同时也限制了用户的输入字数。

有一句话我们要牢记在心的是:凡是输入,必有限制;凡是输入,必须校验。

在接下来的文章中,我们将介绍如何实现输入字符实时提示功能和本地存储(localStorage)技术。

1、jQuery字符统计插件
现在,我们以新浪微博发送微博输入框为例子,介绍使用jQuery实现实时提示用户剩余字符数。

新浪微博是限制140个中文(280个英文),当然还有各种其他字符空格的情况,在用户输入达到限制之前或达到了,好的用户体验应该提示用户接近或达到了限制,当然我们可以通过使用不同颜色或加粗字体方式提示用户。

js仿微博实现统计字符和本地存储功能

图1新浪微博用户输入限制

字符数统计插件会在输入框后创建一个同级元素span,它用来显示当前剩余字符数,当触发输入框的keyup、keydown和change事件时,实时修改span中剩余字符数,如果剩余字符数接近“warning”(接近零)修改CSS样式提示用户接近输入限制。

当剩余字符达到“warning”时,在span元素中添加相应的样式类,当剩余字符等于或大于输入限制时,添加相应的样式类提示用户已经超出字符数限制。

我们通过字符数统计插件在页面中动态地插入如下代码:

<!-- adds element dynamic -->
<span class="counter">140</span>

在默认情况下,字符限制是140个,当可输入字符数少于等于25个提示用户,当可输入字符数少于等于0时,提示用户字符数超出了限制。下面我们定义默认情况下条件对象:

// The default limitation.
var defaults = {
 allowed: 140,
 warning: 25,
 css: 'counter',
 counterElement: 'span',
 cssWarning: 'warning',
 cssExceeded: 'exceeded',
 counterText: ''
};

上面,我们定义了defaults对象,它包含allowed、warning、css、cssWarning和cssExceeded等属性,通过修改defaults对象属性,我们可以很方便修改字符统计插件。

  • Allowed:允许输入的字符数。
  • Warning:提示用户剩余字符数接近限零。
  • Css:添加到counter元素的CSS样式类名。
  • cssWarning:警告提示样式。
  • cssExceeded:超出字符限制提示样式。

接下来,我们在字符统计插件中定义方法calculate(),它计算当前剩余字符数,如果到达了警告范围则在页面中增加样式类“warning”,当剩余字符数少于等于零时,在页面中增加样式“exceeded”。

/***
* Calculates the char
* @param obj
*/
function calculate(obj) {

 // Get the count.
 var count = getLength($(obj).val());
 var available = options.allowed - count;

 if (available <= options.warning && available >= 0) {
  $(obj).next().addClass(options.cssWarning);
 }
 else {
  $(obj).next().removeClass(options.cssWarning);
 }
 if (available < 0) {
  $(obj).next().addClass(options.cssExceeded);
 }
 else {
  $(obj).next().removeClass(options.cssExceeded);
 }
 $(obj).next().html(options.counterText + available);
}

我们又定义方法getLength(),当输入字符是中文时totLen加1,如果是英文字符或数字时totLen加0.5(默认允许输入140个中文字符)。

/**
* Get the length of char.
* @param str
* @return {Number}
*/
function getLength(str) {
 var totLen = 0;
 for (var i = 0; i < str.length; i++) {
  // If the char is Chinese.
  if (str.charCodeAt(i) > 256) {
   totLen += 1;
  }
  else {
   totLen += 0.5;
  }
 }
 return Math.floor(totLen);
}

接下来,我们在控件中绑定keyup(),keydown()和change()事件方法,当页面对象触发keyup(),keydown()或change()事件方法时,调用calculate()方法计算当前剩余的字符数,并且添加相应的CSS样式到页面中。

// Binds text area keyup, keydown and change event.
this.each(function() {
 $(this).after('<' + options.counterElement + ' class="' + options.css + '">' + options.counterText + '</' +
    options.counterElement + '>');
 calculate(this);
 $(this).keyup(function() { calculate(this), storeWeibo(this) });
 $(this).keydown(function() { calculate(this), storeWeibo(this) });
 $(this).change(function() { calculatea(this) });
});

2、Web Storage
现在,我们基本实现了jQuery字符数统计插件功能了,相信许多人都注意到,如果我们在发微博时,没有发送出去的微博下次打开页面,发送框依然保存着我们未发送的微博,即使关闭浏览器重新打开页面,我们没发送的信息依然存在。

其实,要实现这一个功能方法是多种多样的,例如我们可以使用:Cookies,Session等技术。

随着HTML5规范的制定,与此同时W3C制定了网络存储(Web Storage)的规范,它提供将数据存储在客户端中,直到Session过期(会话存储)或超出本地容量(本地存储),它比传统的Cookies存储功能更强大、更容易实现和容量更大(大部分浏览器支持5M的本地存储)。

会话存储
会话存储:它将数据保存在会话中,一旦我们关闭浏览器选项卡时,会话中的数据将失效。

本地存储
本地存储:当数据需要持久地保存在客户端中,这时我们可以使用本地存储(Local Storage),它是以key/value 的形式来存储数据的,如果关闭了页面或浏览器后,重新打开页面数据依然存在,它提供了数据的持久保存。一个简单的应用是:记录用户访问页面的次数。

js仿微博实现统计字符和本地存储功能

图2存储空间的对比

接下来,我们将介绍如何使用本地存储保存用户数据。

由于,localStorage提供了setItem(),getItem(),removeItem(),key()和clear() 5个方法,和一个属性length,具体定义如下:

// Storage definition.
interface Storage {
 readonly attribute unsigned long length;
 DOMString key(in unsigned long index);
 getter any getItem(in DOMString key);
 setter creator void setItem(in DOMString key, in any value);
 deleter void removeItem(in DOMString key);
 void clear();
};

在现代浏览器中使用本地存储是非常的简单,我们只需在Javascript代码中直接调用localStorage对象的方法或属性就OK了。

// stores the username 'jkrush',
// then get the username.
localStorage.setItem('username', 'jkrush');
var userName = localStorage.getItem('username');

上面,我们通过调用localStorage的setItem()和getItem()方法实现数据的存储和获取,由于localStorage是以Key/Value形式存储数据的,所以我们在存储时需要提供Key/Value值,然后调用getItem()方法获取存储在Key中的值。

由于本地存储是以Key/Value的形式进行存储的,那么我们可以很容易存储字符串类型的数据,如果我们需要存储对象类型,那么本地存储就显得捉襟见肘了。

假设,我们把一个student对象存储到localStorage中,具体代码如下:

// Defines a student object.
var student = {
 name: 'JK_Rush',
 age: '26',
 sex: 'male'
};

// Prints student object
console.log(student);

// Stores student object.
// Gets student object again.
localStorage.setItem('student', student);
console.log(localStorage.getItem('student'));

js仿微博实现统计字符和本地存储功能

图3 localStorage存储对象

通过上面示例,我们注意到在Firebug的控制台中输出的并不是真正的student对象,而是student对象的信息而已。

那么我们该如何把对象存储到localStorage中呢?其实,我们可以把对象序列化为JSON数据进行存储,最后通过反序列化把JSON数据转换为对象。具体实现如下:

// Defines a student object.
var student = {
 name: 'JK_Rush',
 age: '26',
 sex: 'male'
};

console.log(student);

// Serializes the object to json string.
localStorage.setItem('student', JSON.stringify(student));

// Deserializes the json string to object.
console.log(JSON.parse(localStorage.getItem('student')));

上面示例中,在存储student对象之前,我们使用JSON的stringify()方法序列化对象为JSON字符串,然后存储到localStorage中;如果我们要获取student对象,只需使用JSON的parse()方法反序列化字符串为对象。

js仿微博实现统计字符和本地存储功能

图4 localStorage存储对象

上面,我们实现了student对象转换为JSON格式字符串存储到localStorage中,接下来,我们在前面的例子中添加localStorage功能,具体代码如下:

/**
* Store user data into local storage.
* @param obj
*/
function storeWeibo(obj) {

 // Checks the browser supports local storage or not.
 if (window.localStorage) {
  localStorage.setItem('publisherTop_word', $(obj).val());
 }
 else {

  // For instance, ie 6 and 7 do not support local storage,
  // so we need to provider other way.
  window.localStorage = {
   getItem: function(sKey) {
    if (!sKey || !this.hasOwnProperty(sKey)) { return null; }
    return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g,
       "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
   },
   key: function(nKeyId) {
    return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]);
   },
   setItem: function(sKey, sValue) {
    if (!sKey) { return; }
    document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
    this.length = document.cookie.match(/\=/g).length;
   },
   length: 0,
   removeItem: function(sKey) {
    if (!sKey || !this.hasOwnProperty(sKey)) { return; }
    document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
    this.length--;
   },
   hasOwnProperty: function(sKey) {
    return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
   }
  };
  window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
 }
}

现在我们在自定义字符统计插件(jquery.charcount.js)中,添加方法storeWeibo(),首先我们判断当前浏览器是否支持localStorage,主流的浏览器如:Chrome、Firefox、Opera、Safari以及IE 8都支持本地存储(localStorage)和会话存储(sessionStorage)。

如果浏览器支持本地存储,那么我们可以直接调用localStorage的setItem()方法,将textarea中的数据存储起来;当我们再次打开页面或浏览器,首先检查localStorage是否存储了相应的数据,如果有数据存储,那么我们再次把数据取出显示到textarea中。

但由于一些用户可能使用旧版的浏览器(如:IE6和IE7),考虑到兼容我们必须提供支持旧版浏览器的方案。

我们知道旧版浏览器(如:IE6和IE7),它们支持Cookies的持久化存储方式,所以我们使用Cookies实现getItem(), setItem()和removeItem()等方法。

js仿微博实现统计字符和本地存储功能

js仿微博实现统计字符和本地存储功能

图5 主流浏览器支持Web Storage

现在,我们已经完成了字符统计插件jquery.charcount.js,由于时间的关系我们已经把发送框的界面设计好了,具体的HTML代码如下:

<!-- From design-->
<body>
 <form id="form" method="post">
 <h2>
  有什么新鲜事想告诉大家?</h2>
 <div>
  <label class="mali_oglas_kategorija" for="message">
   有什么新鲜事想告诉大家?<b></b></label>
  <textarea id="weiboMsg" placeholder="请Fun享"></textarea>
  <span class="counter"></span>
  <input onclick="SaveCache()" type="submit" value="发布">
 </div>
 </form>
</body>

js仿微博实现统计字符和本地存储功能

图6 发送框界面设计

接下来,我们在页面代码中引用jQuery库和自定义字符统计插件jquery.charcount.js,具体代码如下:

<!-- Adds Javascript reference -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="./js/jquery.charcount.js"></script>

上面,我们直接引用Google提供的jQuery库,当然我们也把jQuery库下载到本地,然后引入到项目中,接下来我们在HTML页面中添加调用字符统计插件的代码,具体代码如下:

<!-- When document ready invokes charCount function-->
<script type="text/javascript">
 $(document).ready(function () {
  // Uses default setting.
  $("#weiboMsg").charCount();
 });
</script>

上面,我们完成了在页面代码中调用字符统计插件,每当我们在文本框中输入字符时,都会实时地显示剩余的字符数,而且我们在文本框中输入的字符都会保存到localStorage中。

接下来,我们分别在Chrome和Firefox中查看保存在localStorage中的数据。

首先,我们打开Chrome的“开发者工具”(Ctr+Shift+I),然后我们选择“Resources”选项,这时我们就可以看到保存在localStorage中的数据了。

js仿微博实现统计字符和本地存储功能

图7 Chrome的本地存储

同样,我们打开Firefox的“Firebug”(F12),然后我们选择“DOM”选项,这时我们需要查找window的对象localStorage,这样就可以看到保存在localStorage中的数据了。

js仿微博实现统计字符和本地存储功能

图8 Firefox的本地存储

我们知道IE8也是支持localStorage对象的,但是我做测试时候发现IE8中一直提示localStorage对象未定义,后来我上Stackoverflow查看了一下,有人说在IE8中,localStorage对象是依赖于域名的,所以需要运行在Web服务器中才可以成功保存数据到localStorage中。

我们注意到微博通过本地存储技术,保存用户在发送框中的数据,一旦数据发送了就清空本地存储,反之保存用户的输入。

本文通过微博发送框例子介绍了如何定义jQuery字符统计插件和本地存储技术,首先,我们知道限制用户输入是必须的,但如何有效而且人性化提示用户输入限制呢?这里我们通过定义一个jQuery插件,动态地统计剩余字符数,希望对大家学习javascript程序设计有所启发。

Javascript 相关文章推荐
javascript里的条件判断
Feb 27 Javascript
拖动布局之保存布局页面cookies篇
Oct 29 Javascript
js模拟滚动条(横向竖向)
Feb 22 Javascript
使用jquery实现简单的ajax
Jul 08 Javascript
Javascript 多物体运动的实现
Dec 24 Javascript
JS解析XML文件和XML字符串详解
Apr 17 Javascript
js实现的Easy Tabs选项卡用法实例
Sep 06 Javascript
Bootstrap3.0学习教程之JS折叠插件
May 27 Javascript
vuejs使用$emit和$on进行组件之间的传值的示例
Oct 04 Javascript
一个简易时钟效果js实现代码
Mar 25 Javascript
JS回调函数 callback的理解与使用案例分析
Sep 09 Javascript
详解jQuery的核心函数和事件处理
Feb 18 jQuery
Bootstrap轮播加上css3动画,炫酷到底!
Dec 22 #Javascript
对象题目的一个坑 理解Javascript对象
Dec 22 #Javascript
IE6-IE9使用JSON、table.innerHTML所引发的问题
Dec 22 #Javascript
JavaScript+CSS无限极分类效果完整实现方法
Dec 22 #Javascript
JS实现的表格操作类详解(添加,删除,排序,上移,下移)
Dec 22 #Javascript
JS控制按钮10秒钟后可用的方法
Dec 22 #Javascript
js实现C#的StringBuilder效果完整实例
Dec 22 #Javascript
You might like
php imagecreatetruecolor 创建高清和透明图片代码小结
2010/05/15 PHP
php获取mysql数据库中的所有表名的代码
2011/04/23 PHP
PHP连接数据库实现注册页面的增删改查操作
2016/03/27 PHP
PHP实现登录搜狐广告获取广告联盟数据的方法【附demo源码】
2016/10/14 PHP
jquery滚动组件(vticker.js)实现页面动态数据的滚动效果
2013/07/03 Javascript
jquery+ajax+text文本框实现智能提示完整实例
2016/07/09 Javascript
webpack+vue.js实现组件化详解
2016/10/12 Javascript
基于Angularjs+mybatis实现二级评论系统(仿简书)
2017/02/13 Javascript
JQuery实现文字无缝滚动效果示例代码(Marquee插件)
2017/03/07 Javascript
easyui下拉框动态级联加载的示例代码
2017/11/29 Javascript
微信小程序使用video组件播放视频功能示例【附源码下载】
2017/12/08 Javascript
vue.js提交按钮时进行简单的if判断表达式详解
2018/08/08 Javascript
微信小程序静默登录的实现代码
2020/01/08 Javascript
vue.js实现简单的计算器功能
2020/02/22 Javascript
[09:23]国际邀请赛采访专栏:iG战队VK,Tongfu战队Cu
2013/08/05 DOTA
Pyhton中防止SQL注入的方法
2015/02/05 Python
浅谈Python中的私有变量
2018/02/28 Python
pip安装时ReadTimeoutError的解决方法
2018/06/12 Python
python+pandas+时间、日期以及时间序列处理方法
2018/07/10 Python
对python csv模块配置分隔符和引用符详解
2018/12/12 Python
Python提取转移文件夹内所有.jpg文件并查看每一帧的方法
2019/06/27 Python
django框架auth模块用法实例详解
2019/12/10 Python
Django分组聚合查询实例分享
2020/04/29 Python
python的链表基础知识点
2020/09/13 Python
Python实现EM算法实例代码
2020/10/04 Python
The Hut德国站点:时装、家居用品、美容等
2016/09/23 全球购物
意大利男装网店:Vrients
2019/05/02 全球购物
给老师的一封建议书
2014/03/13 职场文书
捐献物资倡议书范文
2014/05/19 职场文书
领导干部廉政自律承诺书
2014/05/26 职场文书
我的中国梦演讲稿初中篇
2014/08/19 职场文书
体育专业大学生职业生涯规划范文:打造自己的运动帝国
2014/09/12 职场文书
员工试用期自我鉴定范文
2014/09/15 职场文书
青年志愿者活动感想
2015/08/07 职场文书
2016关于学习党章的心得体会
2016/01/15 职场文书
javascript数组includes、reduce的基本使用
2021/07/02 Javascript