我正在编写一个简单的javascript库来更新基于HTML5输入范围滑块的section
元素中显示的文本量(即单词数)。
我的版本适用于单个p
元素,但不适用于p
中的多个section
元素。
HTML
<section>
<p>Text example:</p>
<section data-range="true">
<input type="range">
<p>Contemporary web applications utilize a Representational State Transfer (REST) software architectural schema through the combination of front and back-end model-view-controller (MVC) and routing frameworks. The implementation of a MVC framework on the front-end helps to create the effect of a seamless single page application where data is asynchronously processed by the server, and updated in the view.</p>
<p>The controller on the front-end is responsible for communicating with the server via HTTP requests. Data objects on the front-end are usually encapsulated in JavaScript Object Notation (JSON) and asynchronously sent to the server for performing various logic, or RESTful operations identified by Uniform Resource Identifiers (URIs) in HTTP requests.</p>
</section>
</section>
JS
/* updateInnerText
* Update inner text based on range section
* @param the event elemenet (range input)
* @param range value, number of words to display
*/
function updateInnerText(el, length) {
var paragraphs = [];
for (var p = 0; p < numParagraphs; p++) {
var ob = {};
ob['text'] = el.srcElement.parentNode.children[p + 1].attributes["data-text"].value;
ob['numWords'] = el.srcElement.parentNode.children[p + 1].attributes["data-text"].value.split(' ').length;
paragraphs.push(ob);
}
// update on the DOM
for (var x = numParagraphs; x >= 0; x--) {
var diff = fullText.split(' ').length - length;
diff = +diff + +length;
el.srcElement.parentNode.children[x].innerHTML = paragraphs[x - 1]['text'].substring(0, diff);
}
}
更新
以下是原始工作版本的JSbin。
以下是更新的JSbin尝试多个段落。
答案 0 :(得分:1)
这是函数的修改版本,它在元素及其子树上递归递归。它删除超出单词计数的文本节点(必要时拆分边框文本节点。)
此更新后的JSbin应该可以满足您的需求。
// updateInnerText :: Event, Number -> undefined
function updateInnerText(el, length) {
var curNode = null,
curWords = [],
nodesToRemove = [],
remainingWords = length,
wordsSoFar = 0,
walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
while (curNode = walker.nextNode()) {
curWords = getWords(curNode.textContent);
remainingWords = length - wordsSoFar;
if (remainingWords <= 0) {
nodesToRemove.push(curNode);
} else if (remainingWords >= curWords.length) {
wordsSoFar += curWords.length;
} else {
wordsSoFar = length;
nodesToRemove.push(curNode.splitText(remainingWordsCharCount()));
}
curNode = walker.nextNode();
}
nodesToRemove.forEach(function (n) { n.remove(); });
// getWords :: String -> [String]
function getWords(text) {
return text.split(/\s+/ig)
.map(function (s) { return s.trim(); })
.filter(Boolean);
}
// remainingWordsCharCount :: undefined -> Number
function remainingWordsCharCount() {
return curWords.slice(0, remainingWords).join(' ').length;
}
}