标题过长使用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 相关文章推荐
HTML IMG标签 onload 内存溢出导致浏览器CPU占用过高
Mar 09 Javascript
硬盘浏览程序,保存成网页格式便可使用
Dec 03 Javascript
JavaScript中也使用$美元符号来代替document.getElementById
Jun 19 Javascript
jQuery的end()方法使用详解
Jul 15 Javascript
深入php面向对象、模式与实践
Feb 16 Javascript
基于bootstrap的文件上传控件bootstrap fileinput
Dec 23 Javascript
使用JS 插件qrcode.js生成二维码功能
Feb 20 Javascript
three.js绘制地球、飞机与轨迹的效果示例
Feb 28 Javascript
jQuery ajax动态生成table功能示例
Jun 14 jQuery
微信小程序实现选项卡效果
Nov 06 Javascript
使用Vue生成动态表单
Nov 26 Javascript
Vue鼠标滚轮滚动切换路由效果的实现方法
Aug 04 Vue.js
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中的多态性[译]
2011/08/02 PHP
php数组函数序列之end() - 移动数组内部指针到最后一个元素,并返回该元素的值
2011/10/31 PHP
php启用zlib压缩文件的配置方法
2013/06/12 PHP
PHP中绘制图像的一些函数总结
2014/11/19 PHP
laravel学习教程之关联模型
2016/07/30 PHP
动态表单验证的操作方法和TP框架里面的ajax表单验证
2017/07/19 PHP
什么是JavaScript
2009/08/13 Javascript
jquery中eq和get的区别与使用方法
2011/04/14 Javascript
『jQuery』.html(),.text()和.val()的概述及使用
2013/04/22 Javascript
JS Pro-深入面向对象的程序设计之继承的详解
2013/05/07 Javascript
jquery动态改变form属性提交表单
2014/06/03 Javascript
jQuery+ajax实现鼠标单击修改内容的思路
2014/06/29 Javascript
jQuery实现给input绑定回车事件的方法
2017/02/09 Javascript
基于HTML5+JS实现本地图片裁剪并上传功能
2017/03/24 Javascript
快速解决Vue项目在IE浏览器中显示空白的问题
2018/09/04 Javascript
监听element-ui table滚动事件的方法
2019/03/26 Javascript
ES6 Class中实现私有属性的一些方法总结
2019/07/08 Javascript
uniapp实现可以左右滑动导航栏
2020/10/21 Javascript
Python安装第三方库的3种方法
2015/06/21 Python
Django 多表关联 存储 使用方法详解 ManyToManyField save
2019/08/09 Python
kafka监控获取指定topic的消息总量示例
2019/12/23 Python
简单了解python shutil模块原理及使用方法
2020/04/28 Python
关于Keras Dense层整理
2020/05/21 Python
python基本算法之实现归并排序(Merge sort)
2020/09/01 Python
俄罗斯园林植物网上商店:Garshinka
2020/07/16 全球购物
Yahoo-PHP面试题2
2014/12/06 面试题
创建无烟单位实施方案
2014/03/29 职场文书
幼儿园小班评语大全
2014/04/17 职场文书
基层领导干部“四风”问题批评与自我批评
2014/09/23 职场文书
2014办公室年度工作总结
2014/12/09 职场文书
库房管理员岗位职责
2015/02/12 职场文书
小学教师读书笔记
2015/07/01 职场文书
考试后的感想
2015/08/07 职场文书
2016民族团结先进个人事迹材料
2016/02/26 职场文书
python实现自定义日志的具体方法
2021/05/28 Python
Python+Tkinter打造签名设计工具
2022/04/01 Python