使用Javascript根据像素将字符串拆分为多个部分

时间:2018-02-07 16:58:18

标签: javascript html string split

我知道可以根据字符串的长度来分割字符串。但是如何在不切断单词的情况下基于像素拆分html字符串?

例如:

myString = "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s";
splitThroughPixel(myString, 100) // Shall return something like ["Lorem Ipsum has", "been the industry's", "dummy text", "since the", "1500s"] (not the true splitting, just to give an idea)

splitThroughPixel(myString, 100)会将myString分成100px个最大字符串(不包含字词)。

我怎样才能做到这一点?

我已经能够使用这个javascript方法获取字符串的完整像素长度(如果它可以帮助):

function getWidth(pText, pFontSize, pStyle) {
    var lDiv = document.createElement('div');

    document.body.appendChild(lDiv);

    if (pStyle != null) {
        lDiv.style = pStyle;
    }
    lDiv.style.fontSize = "" + pFontSize + "px";
    lDiv.style.position = "absolute";
    lDiv.style.left = -1000;
    lDiv.style.top = -1000;

    lDiv.innerHTML = pText;

    document.body.removeChild(lDiv);
    lDiv = null;

    return lDiv.clientWidth;
}

例如:getWidth(myString )返回510(这是字符串myString屏幕上的像素数)

感谢您抽出宝贵时间帮助我。

3 个答案:

答案 0 :(得分:2)

首先,我对你的getWidth函数进行了一些修正,因为你返回lDiv.clientWidth但是你之前将lDiv设置为null,所以它会抛出一个错误。因此,我将.clientWidth存储到变量中,然后将其返回:

function getWidth(pText, pFontSize, pStyle) {

    var lDiv = document.createElement('div');

    document.body.appendChild(lDiv);

    if (pStyle != null) {
        lDiv.style = pStyle;
    }

    lDiv.style.fontSize = "" + pFontSize + "px";
    lDiv.style.position = "absolute";
    lDiv.style.left = -1000;
    lDiv.style.top = -1000;

    lDiv.innerHTML = pText;
        const width = lDiv.clientWidth;

    document.body.removeChild(lDiv);
    lDiv = null;

    return width;

}

接下来,对于您的splitThroughPixel,您只需遍历每个单词,获取像素,然后检查句子是否大于宽度。如果它更大,则将前一个字符串添加到结果中。

function splitThroughPixel(string, width, size, style){

    const words = string.split(' ');
    const response = [];
    let current = '';

    for(let i=0; i<words.length; i++){

        const word = words[i];
        const temp = current + (current == '' ? '' : ' ') + word;

        if(getWidth(temp, size, style) > width){
            response.push(current.trim());
            current = '';
        }else{
            current = temp;
        }

    }

    return response;

}

实施例

const myString = "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s";
console.log(splitThroughPixel(myString, 100, 14));

示例的响应将是这样的数组:

["Lorem Ipsum has", "the industry's", "dummy text ever"]

演示

https://jsfiddle.net/ChinLeung/rqp1291r/2/

答案 1 :(得分:1)

您可以根据当前innerHTML重复使用相同的元素并添加/重置width,而不是像其他答案所建议的那样创建和删除每个循环的元素,这在性能上会很糟糕。

&#13;
&#13;
function wrapText(text, maxWidth) {
    const words = text.split(' ');
  
    var el = document.createElement('div');
    document.body.appendChild(el);

    el.style.position = "absolute";
    let rows = [];
    let row = [];
    let usedIndex = 0;
    
    // loop through each word and check if clientWidth is surpassing maxWidth
    for(let i = 0; i < words.length; i++) {
      const word = words[i];
      el.innerHTML += word;
      if (el.clientWidth > maxWidth) {
        rows.push(el.innerHTML);
        usedIndex = i;
        el.innerHTML = "";
      } else {
        el.innerHTML += " ";
      }
    }
    
    // handle remaining words
    words.splice(0, usedIndex);
    rows = rows.concat(words.join(" "));
    
    document.body.removeChild(el);

    return rows;
}

const text = "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s";
console.log(wrapText(text, 100));
&#13;
p {
  position: relative;
}

p::before {
  outline: 1px solid red;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 100px;
  content: '';
}
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以创建一个包含white-space: nowrapdisplay: inline的临时div,并为其添加单词,然后测试它的宽度。

此解决方案不允许子字符串超出您的像素限制,除非整个字超出该像素限制。

&#13;
&#13;
let myString = "Ipsum has been the industry's standard dummy text ever since the 1500s";
let split = splitThroughPixel(myString, 100);
console.log(split);

function splitThroughPixel(string, px) {
	let words = string.split(' ');
	let split = [];

	let div = document.createElement('div');
	div.style.cssText = 'white-space:nowrap; display:inline;';
	document.body.appendChild(div);

	for (let i = 0; i < words.length; i++) {
		div.innerText = (div.innerText + ' ' + words[i]).trim();
		let width = Math.ceil(div.getBoundingClientRect().width);
		if (width > px && div.innerText.split(' ').length > 1) {
			let currentWords = div.innerText.split(' ');
			let lastWord = currentWords.pop();
			split.push(currentWords.join(' '));
			div.innerText = lastWord;
		}
	}

	if (div.innerText !== '') {
		split.push(div.innerText);
	}

	document.body.removeChild(div);

	return split;
}
&#13;
&#13;
&#13;