标题过长使用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 相关文章推荐
跨浏览器的 mouseenter mouseleave 以及 compareDocumentPosition的使用说明
May 04 Javascript
jquery中获得元素尺寸和坐标的方法整理
May 18 Javascript
js实现有过渡渐变效果的图片轮播相册(兼容IE,ff)
Jan 19 Javascript
基于twbsPagination.js分页插件使用心得(分享)
Oct 21 Javascript
Vue 实时监听窗口变化 windowresize的两种方法
Nov 06 Javascript
vue项目中将element-ui table表格写成组件的实现代码
Jun 12 Javascript
Vue中跨域及打包部署到nginx跨域设置方法
Aug 26 Javascript
小程序组件传值和引入sass的方法(使用vant Weapp组件库)
Nov 24 Javascript
创建与框架无关的JavaScript插件
Dec 01 Javascript
vue使用echarts图表自适应的几种解决方案
Dec 04 Vue.js
js实现自动锁屏功能
Jun 02 Javascript
vue实力踩坑之push当前页无效
Apr 10 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横向重复区域显示二法
2008/09/25 PHP
浅析echo(),print(),print_r(),return之间的区别
2013/11/27 PHP
php将文本文件转换csv输出的方法
2014/12/31 PHP
PHP如何实现订单的延时处理详解
2017/12/30 PHP
php微信公众号开发之快递查询
2018/10/20 PHP
PHP连接SQL Server的方法分析【基于thinkPHP5.1框架】
2019/05/06 PHP
修改Laravel自带的认证系统的User类的命名空间的步骤
2019/10/15 PHP
测试你的JS的掌握程度的代码
2009/12/09 Javascript
判断浏览器的javascript版本的代码
2010/09/03 Javascript
window.location.href中url中数据量太大时的解决方法
2013/12/23 Javascript
js实现的复制兼容chrome和IE
2014/04/03 Javascript
浅谈javascript的调试
2015/01/28 Javascript
jquery实现动态操作select选中
2015/02/11 Javascript
JavaScript在Android的WebView中parseInt函数转换不正确问题解决方法
2015/04/25 Javascript
微信小程序 PHP生成带参数二维码
2017/02/21 Javascript
详解Vue爬坑之vuex初识
2017/06/14 Javascript
React BootStrap用户体验框架快速上手
2018/03/06 Javascript
Vue异步组件处理路由组件加载状态的解决方案
2018/09/07 Javascript
微信小程序下拉框功能的实例代码
2018/11/06 Javascript
javascript面向对象三大特征之继承实例详解
2019/07/24 Javascript
Python的Flask开发框架简单上手笔记
2015/11/16 Python
利用Python开发微信支付的注意事项
2016/08/19 Python
Python使用Selenium+BeautifulSoup爬取淘宝搜索页
2018/02/24 Python
对python中的xlsxwriter库简单分析
2018/05/04 Python
Python拼接微信好友头像大图的实现方法
2018/08/01 Python
对python中类的继承与方法重写介绍
2019/01/20 Python
python TK库简单应用(实时显示子进程输出)
2019/10/29 Python
Python + Requests + Unittest接口自动化测试实例分析
2019/12/12 Python
Python处理PDF与CDF实例
2020/02/26 Python
Python Map 函数的使用
2020/08/28 Python
Docker如何部署Python项目的实现详解
2020/10/26 Python
中国医药集团国药在线:国药网
2017/02/06 全球购物
英国最大的女士服装零售商:Bonmarché
2017/08/17 全球购物
自荐信的格式
2014/03/10 职场文书
贷款委托书怎么写
2014/08/02 职场文书
mysql性能优化以及配置连接参数设置
2022/05/06 MySQL