使用JavaScript根据其像素将字符串分为零件



我知道可以根据字符的长度按字符数来拆分字符串。但是,如何在不切断单词的情况下根据像素分开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 max的字符串块(不切割单词(。

我该如何实现?

我已经能够使用此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屏幕上的像素数(

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

首先,我对您的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"]

demo

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

,而不是按照其他答案的建议,而不是创建和删除每个循环的元素,这在性能方面是不好的,您可以根据当前的width重复使用相同的元素并添加/重置innerHTML

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));
p {
  position: relative;
}
p::before {
  outline: 1px solid red;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 100px;
  content: '';
}

您可以创建一个具有white-space: nowrapdisplay: inline的临时Div并在其上添加单词,然后测试其宽度。

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

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;
}

最新更新