我已经解决了dom操纵问题,但是我不相信这是解决它的最干净,最清晰的方法。
旧问题:将innerHTML从一组元素转换为三个范围,并用新转换的范围替换每个元素的innerHTML。
例如:
<h1>This is awesome<h1>
<h1>
<span class="color-1">This</span>
<span class="color-2">is</span>
<span class="color-3">awesome</span>
</h1>
我已经使用了很多切片和连接以及递归函数,但是我认为用更少的代码可能会得到相同的结果,例如,使用更多的es6数组辅助方法。你能帮我吗?
只有2个单词,第一个和第二个跨度应包含每个1个单词,最后一个跨度为空。
const elements = Array.from(document.querySelectorAll("h1, h2 , h3, h4"));
convertElements(elements);
function convertElements(elements) {
const textsInsideElements = elements.map(htmlElement => htmlElement.innerHTML);
textsInsideElements.forEach((text, index) =>
convertToSeparateSpans(elements, text, index));
}
function convertToSeparateSpans(elements, string, index) {
const wordsPerSpan = calculateWordsPerSpan(string, 3);
const wordParts = pushWordSpansToSeparateArrays([], string, wordsPerSpan, -1);
const joinedTextSpans = wordsToSpanElements(wordParts);
elements[index].innerHTML = joinedTextSpans;
}
function calculateWordsPerSpan(string, totalSpans) {
const totalLength = string.split(' ').length;
const residual = totalLength % totalSpans;
const firstPart = residual === 0 ?
totalLength / totalSpans : Math.ceil(totalLength / totalSpans);
const middlePart = residual === 1 ? firstPart * 2 - 1 : firstPart * 2;
const endPart = totalLength;
return [].concat(firstPart).concat(middlePart).concat(endPart);
}
function pushWordSpansToSeparateArrays(result, string, stringPartials, index) {
const firstIteration = index === -1;
const indexOutOfBounds = stringPartials[index + 1] === undefined;
const stringToArr = string.split(' ');
const firstString = stringToArr.slice(0, stringPartials[index + 1]).join(' ');
const subsequentString = stringToArr
.slice(stringPartials[index], stringPartials[index + 1])
.join(' ');
if(firstIteration) {
result.push(firstString);
pushWordSpansToSeparateArrays(result, string, stringPartials, index + 1)
return result;
} else if (!firstIteration && !indexOutOfBounds) {
result.push(subsequentString);
pushWordSpansToSeparateArrays(result, string, stringPartials, index + 1);
}
}
function wordsToSpanElements(wordParts) {
const spanArray = wordParts.map((part, index) =>
`<span class="color-${index+1}">${part}</span>`);
return spanArray.join(' ');
}
在@Nathan Stockton的帮助下,我终于用以下代码格式化了代码:
function pushWordSpansToSeparateArrays(string) {
const splitString = string.trim().split(" ");
const hasResidual1 = splitString.length%3 === 1;
const firstThird = Math.ceil(splitString.length/3);
let secondThird = hasResidual1 ? firstThird * 2 - 1 : firstThird * 2;
return []
.concat(splitString.slice(0, firstThird).join(' '))
.concat(splitString.slice(firstThird, secondThird).join(' '))
.concat(splitString.slice(secondThird, splitString.length).join(' '));
}
const test = "This is a long string";
console.log(pushWordSpansToSeparateArrays(test))
// output ["This is", "a long", "string"]
这种方法的问题在于它不能重复使用超过3个部分。
新问题:是否有一种方法可以使此函数具有通用性,使其能够根据参数将单词分为任意数量的部分,例如pushWordSpansToSeparateArrays(string,totalParts);
答案 0 :(得分:1)
接受2条回复-我现在上床睡觉,希望它能起作用!
String.prototype.splitInto = function (parts) {
const splitString = this.trim().split(" ");
obResponse = {};
obResponse.values = [];
var chunkSize = Math.floor(splitString.length/(parts));
var spares = splitString.length%parts;
var start = 0;
for(var i = 0; i < parts; i++) {
obResponse.values[i] = splitString.slice(start, start+chunkSize+(spares>i?1:0));
start = start+chunkSize+(spares>i?1:0);
}
return obResponse;
}
var segments = "test a b k l m n o ".splitInto(3);
console.log(segments.values);
答案 1 :(得分:0)
这似乎要短得多,可以适应您的需求(我认为是):
String.prototype.splitInto3 = function () {
const splitString = this.trim().split(" ");
var firstThird = Math.ceil(splitString.length/3);
var secondThird = splitString.length-Math.floor((splitString.length-firstThird)/2);
var obResponse = {
firstSegment: splitString.slice(0, firstThird),
secondSegment: splitString.slice(firstThird, secondThird),
thirdSegment: splitString.slice(secondThird, splitString.length)
}
return obResponse;
}
var segments = "test a b c d e f g h i j k l m n o ".splitInto3();
console.log("First third ("+segments.firstSegment.length+"): "+segments.firstSegment);
console.log("Second third ("+segments.secondSegment.length+"): "+segments.secondSegment);
console.log("Third third ("+segments.thirdSegment.length+"): "+segments.thirdSegment);
或作为数组
String.prototype.splitInto3 = function () {
const splitString = this.trim().split(" ");
var firstThird = Math.ceil(splitString.length/3);
var secondThird = splitString.length-Math.floor((splitString.length-firstThird)/2);
var obResponse = [splitString.slice(0, firstThird), splitString.slice(firstThird, secondThird), splitString.slice(secondThird, splitString.length)]
return obResponse;
}
var segments = "test a b c d e f g h i j k l m n o ".splitInto3();
console.log("First third ("+segments[0].length+"): "+segments[0]);
console.log("Second third ("+segments[1].length+"): "+segments[1]);
console.log("Third third ("+segments[2].length+"): "+segments[2]);