标题过长使用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 相关文章推荐
网络之美 JavaScript中Get和Set访问器的实现代码
Sep 19 Javascript
Jquery动态替换div内容及动态展示的方法
Jan 23 Javascript
原生js编写autoComplete插件
Apr 13 Javascript
Bootstrap按钮下拉菜单组件详解
May 10 Javascript
BootStrap创建响应式导航条实例代码
May 31 Javascript
JSON对象转化为字符串详解
Aug 11 Javascript
Javasript设计模式之链式调用详解
Apr 26 Javascript
layui实现数据分页功能
Jul 27 Javascript
Vue 实现把表单form数据 转化成json格式的数据
Oct 29 Javascript
AngularJs的$http发送POST请求,php无法接收Post的数据问题及解决方案
Aug 13 Javascript
vue如何批量引入组件、注册和使用详解
May 12 Vue.js
js 实现验证码输入框示例详解
Sep 23 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
php5.4传引用时报错问题分析
2016/01/22 PHP
PHP设计模式之工厂模式详解
2017/10/24 PHP
jQuery checkbox全选/取消全选实现代码
2009/11/14 Javascript
jquery获取选中的文本和值的方法
2014/07/08 Javascript
javascript继承机制实例详解
2014/11/20 Javascript
JS简单计算器实例
2015/01/20 Javascript
JS基于VML技术实现的五角星礼花效果代码
2015/10/26 Javascript
jquery控制页面的展开和隐藏实现方法(推荐)
2016/10/15 Javascript
详谈$.data()的用法和作用
2017/02/13 Javascript
javascript作用域链与执行环境详解
2017/03/25 Javascript
element上传组件循环引用及简单时间倒计时的实现
2018/10/01 Javascript
JS二级菜单不同实现方法分析【4种方法】
2018/12/21 Javascript
深入理解JavaScript 箭头函数
2019/05/30 Javascript
[02:41]《西雅图我们来了》2015国际邀请赛出征全记录
2015/07/23 DOTA
用Python的Django框架编写从Google Adsense中获得报表的应用
2015/04/17 Python
opencv python 傅里叶变换的使用
2018/07/21 Python
Python数据分析:手把手教你用Pandas生成可视化图表的教程
2018/12/15 Python
利用Python+阿里云实现DDNS动态域名解析的方法
2019/04/01 Python
详解PyTorch中Tensor的高阶操作
2019/08/18 Python
python中提高pip install速度
2020/02/14 Python
20行Python代码实现视频字符化功能
2020/04/13 Python
通过Python扫描代码关键字并进行预警的实现方法
2020/05/24 Python
如何在python中处理配置文件代码实例
2020/09/27 Python
详解CSS3的perspective属性设置3D变换距离的方法
2016/05/23 HTML / CSS
俄罗斯韩国化妆品网上商店:Cosmasi.ru
2019/10/31 全球购物
Linux管理员面试题 Linux admin interview questions
2016/07/08 面试题
幼儿园元旦亲子活动方案
2014/02/17 职场文书
主管竞聘书范文
2014/03/31 职场文书
教师考核评语
2014/04/28 职场文书
美丽家庭事迹材料
2014/05/03 职场文书
店长岗位职责
2015/02/11 职场文书
学期个人自我总结
2015/02/13 职场文书
2015年母亲节活动策划方案
2015/05/04 职场文书
单位工资证明范本
2015/06/12 职场文书
2016年师德学习心得体会
2016/01/12 职场文书
继承Win10缺点!教你关闭Win11烦人的网络搜索
2021/11/23 数码科技