截断显示长字符串

传说有个很长的标题 “#%*……&#什么东西1234abcd 还不够长9876 efgh 好了就这样吧” ,标题有多长往往是不可预期的,比如日志的标题,用户还真有这么变态的,当然我们显示的时候,根据设计,不可能有多长显示多长,太长了屏幕也不够啊。


这个需求涉及到 获取string的长度 和 截取某个长度


搜了下相关资料,发现有人这么判断是否为双字节字符:

if(str.charCodeAt(i) & 0xff00) != 0){
	//双字节
}

charCodeAt()用于获取指定位置字符的 Unicode 编码;

0xff00是 “1111 1111 0000 0000” 的十六进制表示法;

&(与操作) 的计算方式为: 见0得0,全1得1;


来做个小练习:

1. "中"的 Unicode 编码为20013,求20013 & 0xff00

第一个问题的是20013的二进制怎么求?坑爹的我根本不会,也不想去算,所谓的十进制转二进制,在JS里是这样的:

20013..toString(2); //你没看错, 就是两个 .
(20013).toString(2);

据同事说是ECMA里这么规定的操作符,好吧,我对文档无爱。


计算结果为:100 1110 0010 1101


结果再从二进制换成十进制,怎么换?

parseInt('0100111000000000', 2)

最终为: 19968


2. "a"的Unicode编码为97,求97 & 0xff00

97的二进制表示法为: 110 0001

不用再换十进制了,是个人都能看出结果为 0


到这里,想必大家都清楚为什么这样写了,单字节的Unicode编码的二进制最多只有八位,与操作后,结果一定是0。那么单字节最大的Unicode是多少,1111 1111转换后等于255。


来见识一下传说中的255是什么

String.fromCharCode(255); // ÿ

再来看看传说中的256是什么

String.fromCharCode(256); // Ā


好了,既然判断Unicode编码大于255就能确定是双字节,我就写的直接一点:

/**
 * @param {string} str 要截取的字符串
 */
var getStrSize = function(str){
	var size = 0;
	for(var i = 0, len = str.length; i < len; i++){
		if (str.charCodeAt(i) > 255){
			size += 2;
		}else{
			size++;
		}
	}
	return size;
};
/**
 * @param {string} str 要截取的字符串
 * @param {number} size 截取长度(单字节长度)
 */
var subStr = function(str, size){
	var curSize = 0, arr = [];
	for(var i = 0, len = str.length; i < len; i++){
		arr.push(str.charAt(i));
		
		if (str.charCodeAt(i) > 255){
			curSize += 2;
			if(size === curSize || size === curSize - 1){
				return arr.join('');
			}
		}else{
			curSize++;
			if(size === curSize){
				return arr.join('');
			}
		}
	}
};

测试一下:

var str = '#%*……&#什么东西1234abcd 还不够长9876 efgh 好了就这样吧';
console.log(str.length);
console.log(getStrSize(str));
console.log(str.substr(0, 15));
console.log(subStr(str, 15));

输出:

40
56
#%*……&#什么东西1234
#%*……&#什么东


更新:最近有个新需求,如果字符串包含标签,如 '这是一个<span class="red">标题</span>,打开看看吧' ,我要截断显示10个字符,那么就不是这么简单了

解决办法:传送门

 

posted @ 2011-10-13 23:00  越己  阅读(1045)  评论(3编辑  收藏  举报