标题过长使用javascript按字节截取字符串


Posted in Javascript onApril 24, 2014

做为一个前端开发人员在网页展示中经常会碰到,标题过长,需要截取字符串,用CSS的实现的话各种兼容问题,各种坑。

让后台程序截一下,又各种推托,让后台按字节截一下更是和要了后台老命一样,最后可能只会安字符长度给你截一下,最后不好看,对不齐,还是回头整CSS、调兼容;

有以上有感触的前端同学默默点个赞吧。

最近接触一个项目,后台只提供接口(json),所有页面的数据渲染,数据绑定都都交给了前端。终于,不考虑SEO,页面所有的主动权到偶的手中了,不经意间就碰到字节截取老问题了。

网络上流传一个Javascript简单获取字节长度的方法:

String.prototype.Blength = function(){//返回字符串字节长度 
return this.replace(/([^\x00-\xFF])/g, "aa").length; 
};

确实很简单,大于ASCII码的字符都算做两个字节,虽然严格来说不正确,但我们是用来辅助展示效果的,真严格起来反而不好了,

但总感觉为了一点投机取巧,而用正则这种较耗时东西不太好,其实也就节省了两行代码,所以我决定还是用正常方式计算:

function getBlength(str){ 
for(var i=str.length;i--;){ 
n += str.charCodeAt(i) > 255 ? 2 : 1; 
} 
return n; 
}

我并没有把方法扩展到String对像的原型上去,还是因为效率问题,以下是测试代码:
//扩展到String的prototype上 
String.prototype.Blength = function () { 
var str = this, 
n = 0; 
for (var i = str.length; i--; ) { 
n += str.charCodeAt(i) > 255 ? 2 : 1; 
} 
return n; 
} 
//给String对像增加一个方法 
String.getBlength = function (str) { 
for (var i = str.length, n = 0; i--; ) { 
n += str.charCodeAt(i) > 255 ? 2 : 1; 
} 
return n; 
} 
//先构造一个中英混合的长字符串 
var str = "javascript 高效按字节截取字符串方法 getBlengthjavascript 高效按字节截取字符串方法 getBlength"; 
str = str.replace(/./g, str).replace(/./g, str); 
console.log("创造的字符串长度为:",str.length) 
console.log("-------------测试开始--------------") 
console.log("str.Blength() >> ",str.Blength()) 
console.log("String.getBlength(str) >> ",String.getBlength(str)) 
console.log("--效率测试开始--") var time1 = new Date() 
for(var i=0;i<100;i++){ 
str.Blength() 
} 
console.log("Blength耗时:",new Date() - time1); 
var time2 = new Date() 
for(var i=0;i<100;i++){ 
String.getBlength(str) 
} 
console.log("getBlength耗时:",new Date() - time2);

结果效率差的不是一点半点,至于原因可能时间花费在了原型链的检索上了,我没有深究,知道的可以留言告诉我:

创造的字符串长度为: 314432
-------------测试开始--------------

str.Blength() >> 425408 
String.getBlength(str) >> 425408 
--效率测试开始-- 
Blength耗时: 1774 
getBlength耗时: 95

现在要截取字符串的基础函数有了,因为在这种情况下字符占的字节长度最长为2,所以用二分法来找到合适截取位置是再好不过了。

给一个效率应该算不错的截取函数:

//简单计算字节长度 
String.getBlength = function (str) { 
for (var i = str.length, n = 0; i--; ) { 
n += str.charCodeAt(i) > 255 ? 2 : 1; 
} 
return n; 
} 
//按指定字节截取字符串 
String.cutByte = function(str,len,endstr){ 
var len = +len 
,endstr = typeof(endstr) == 'undefined' ? "..." : endstr.toString(); 
function n2(a){ var n = a / 2 | 0; return (n > 0 ? n : 1)} //用于二分法查找 
if(!(str+"").length || !len || len<=0){return "";} 
if(this.getBlength(str) <= len){return str;} //整个函数中最耗时的一个判断,欢迎优化 
var lenS = len - this.getBlength(endstr) 
,_lenS = 0 
, _strl = 0 
while (_strl <= lenS){ 
var _lenS1 = n2(lenS -_strl) 
_strl += this.getBlength(str.substr(_lenS,_lenS1)) 
_lenS += _lenS1 
} 
return str.substr(0,_lenS-1) + endstr 
}

拿上面的字符串来测试一下,应该是载得越长越耗时,截个20W的长度试试:
console.log("创造的字符串长度为:",str.length," 字节长度为:",String.getBlength(str)) 
console.log("-------------测试开始--------------") 
console.log("String.cutByte('1开始1',6,'...') >> ",String.cutByte('1开始1',6,'...')) 
console.log("String.cutByte(str,12,'...') >> ",String.cutByte(str,12,'...')) 
console.log("String.cutByte(str,13,'..') >> ",String.cutByte(str,13,'..')) 
console.log("String.cutByte(str,14,'.') >> ",String.cutByte(str,14,'.')) 
console.log("String.cutByte(str,15,'') >> ",String.cutByte(str,15,'')) 
console.log("--效率测试开始--") 
var time1 = new Date() 
for(var i=0;i<100;i++){ 
String.cutByte(str,200000,'...') 
} 
console.log("耗时:",new Date() - time1);

输出结果:

创造的字符串长度为: 314432 字节长度为: 425408
-------------测试开始--------------

String.cutByte('1开始1',6,'...') >> 1开始1 
String.cutByte(str,12,'...') >> javascrip... 
String.cutByte(str,13,'..') >> javascript .. 
String.cutByte(str,14,'.') >> javascript 高. 
String.cutByte(str,15,'') >> javascript 高

--效率测试开始--
耗时: 155

其实把截取字符长度改到30W 40W的耗时也差不了多少,在二分法面前,这都是一个级别的

对比之前的计算字节长度的耗时,用二分法查找截取只消耗了不到两次字节长度的记算的时间.

最后,同学们,来挑战一下效率吧!

Javascript 相关文章推荐
jquery 图片缩放拖动的简单实例
Jan 08 Javascript
js数组的基本操作(很全自己整理的)
Oct 16 Javascript
JS/Jquery判断对象为空的方法
Jun 11 Javascript
jquery实现LED广告牌旋转系统图片切换效果代码分享
Aug 26 Javascript
JS实现的仿东京商城菜单、仿Win右键菜单及仿淘宝TAB特效合集
Sep 28 Javascript
使用JavaScript解决网页图片拉伸问题(推荐)
Nov 25 Javascript
Bootstrap CSS组件之导航(nav)
Dec 17 Javascript
JS实现搜索框文字可删除功能
Dec 28 Javascript
jQuery实现6位数字密码输入框
Dec 29 Javascript
jquery表单验证插件validation使用方法详解
Jan 20 Javascript
JS原型与原型链的深入理解
Feb 15 Javascript
微信小程序实现即时通信聊天功能的实例代码
Aug 17 Javascript
JS对img标签进行优化使用onerror显示默认图像
Apr 24 #Javascript
原生javascript模仿win8等待提示圆圈进度条
Apr 24 #Javascript
js如何判断用户是在PC端和还是移动端访问
Apr 24 #Javascript
jquery 扑捉回车键事件代码
Apr 24 #Javascript
IE中的File域无法清空使用jQuery重设File域
Apr 24 #Javascript
js 动态为textbox添加下拉框数据源的方法
Apr 24 #Javascript
from表单多个按钮提交用onclick跳转不同action
Apr 24 #Javascript
You might like
php面向对象的用户登录身份验证
2017/06/08 PHP
JavaScript DOM学习第六章 表单实例
2010/02/19 Javascript
JavaScript异步编程:异步数据收集的具体方法
2013/08/19 Javascript
jquery 中的each()跳出循环的语句
2014/05/23 Javascript
JavaScript实现为指定对象添加多个事件处理程序的方法
2015/04/17 Javascript
JavaScript中解析JSON数据的三种方法
2015/07/03 Javascript
jQuery超赞的评分插件(8款)
2015/08/20 Javascript
javascript实现tab切换的四种方法
2015/11/05 Javascript
JavaScript中的this,call,apply使用及区别详解
2016/01/29 Javascript
详解基于vue的移动web app页面缓存解决方案
2017/08/03 Javascript
如何优雅地在vue中添加权限控制示例详解
2019/03/07 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
vue 监听窗口变化对页面部分元素重新渲染操作
2020/07/28 Javascript
[52:52]完美世界DOTA2联赛PWL S3 LBZS vs access 第一场 12.10
2020/12/13 DOTA
[01:04:29]DOTA2-DPC中国联赛 正赛 Phoenix vs XG BO3 第二场 1月31日
2021/03/11 DOTA
实例讲解Python中的私有属性
2014/08/21 Python
Python函数式编程指南(四):生成器详解
2015/06/24 Python
Python for Informatics 第11章之正则表达式(四)
2016/04/21 Python
TensorFlow实现简单卷积神经网络
2018/05/24 Python
解决python测试opencv时imread导致的错误问题
2019/01/26 Python
keras实现theano和tensorflow训练的模型相互转换
2020/06/19 Python
openCV提取图像中的矩形区域
2020/07/21 Python
用python批量下载apk
2020/12/29 Python
英国银首饰公司:e&e Jewellery
2021/02/11 全球购物
转预备党员政审材料
2014/02/06 职场文书
品牌宣传方案
2014/03/21 职场文书
干部对照检查材料范文
2014/08/26 职场文书
校园主题婚礼活动策划方案
2014/09/15 职场文书
2014年党员加强作风建设思想汇报
2014/09/15 职场文书
中小学生学籍证明
2014/10/25 职场文书
会计出纳岗位职责
2015/03/31 职场文书
2015年村计划生育工作总结
2015/04/28 职场文书
党员反四风学习心得体会
2016/01/22 职场文书
人身损害赔偿协议书
2016/03/22 职场文书
浅谈mysql执行过程以及顺序
2021/05/12 MySQL
一文简单了解MySQL前缀索引
2022/04/03 MySQL