0

I wastry to add three dots after 130 characters of string which grabbed from a DIV through the JavaScript innerHTML method. Inside the innerHTML may have more tags and attributes which need to skip while counting. Also need to keep and re-assign the truncated HTML into the same DIV after the operation completed.

Here is some sample input string and expected outputs -

Input 1:

<p>There are many <i>variations</i> of passages of <b>Lorem Ipsum</b> available, but the majority have suffered alteration in some form, by injected humour, or randomised words that don't look even slightly believable.</p> 

Output 1:

 <p>There are many <i>variations</i> of passages of <b>Lorem Ipsum</b> available, but the majority have suffered alteration in some form, by injecte...</p> 

input 2:

<p><span class="header3">There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words that don't look even slightly believable.</span></p> 

output 2:

<p><span class="header3">There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injecte...</span></p> 

Input 3:

<h4><span class="santral-pullquote-32"><span class="body-regular">There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words that don't look even slightly believable.</span></span></h4> 

Output 3:

<h4><span class="santral-pullquote-32"><span class="body-regular">There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injecte...</span></span></h4> 

Using the following function Input type 1 is only working but not others:

function cutString = (str) => { let stringCount = 0; let keepCounting = true; let ans = ''; let openTags = []; for (let i = 0; i < str.length; i++) { if (str[i] == "<") { keepCounting = false; if (str[i + 1] != `/`) openTags.push(str[i + 1]) continue; } if (str[i] == ">") { keepCounting = true; if (str[i - 2] == `/`) openTags.splice(openTags.indexOf(str[i - 2]), 1) continue; } if (keepCounting) stringCount++ if (stringCount == 131) { ans = str.slice(0, i); break; } } openTags.forEach(tag => ans = ans + `&#8230;</${tag}>`); return ans; } 

I'm using pure JavaScript (no jQuery). Any help would be greatly appreciated! Thanks in advance.

1 Answer 1

1

you can try this. Note that this code updates the html directly, if you wish to keep the original content, clone the node you want to play with, and use the cloned version to run the trim:

function map_node(f_objNode,f_currLimit){ for(var i=0;i<f_objNode.childNodes.length;i++){ var l_node = f_objNode.childNodes[i]; if(f_currLimit == 0){ //max length exceeded, remove node l_node.remove(); i--; //move index backwards to account for the deleted node continue; }else if(l_node.nodeType == 3){ //textnode var l_strText = l_node.nodeValue; if((f_currLimit - l_strText.length) < 0){ //the text length //exceeds the limit //trim and 0 the limit l_node.nodeValue = l_strText.substring(0,f_currLimit) + '...'; f_currLimit = 0; }else{ //max length is below the text length, update the limit f_currLimit -= l_strText.length } } //process the children of the node, //you can add check here to skip the call if no children f_currLimit = map_node(l_node,f_currLimit); } return f_currLimit } //this is how you use it. function test(){ var l_textLimit = 100; //your limit var l_div = document.getElementById("test-div"); //your node var l_data = map_node(l_div,l_textLimit); //parse the shit out of it //not really used, but if you replace the //the limit integer with {} you can add postprocessing console.log(l_data) } 

as a side note, be aware of parsing as a way to tokenize html. It certainly has its uses, but it can get pretty complicated if you want to maintain the structure of the node. In such cases, it is easier and more efficient to roll with the DOM directly. Going that direction also has issues- larger DOM (sub)trees are not ideal target for recursive processing, so you need to pick your approach for the concrete context.

Sign up to request clarification or add additional context in comments.

7 Comments

with your function HTML text truncated at 43 chars when putting limit 60.
Input: <p><span class="header3">There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humor, or randomized words that don't look even slightly believable.</span></p>
Output: <p><span class="header3">There are many variations of passages of Lo...</span></p>
May be there was whitespace, as while console- f_objNode.childNodes; its show me like - three array, text, p, text. When I print 1st or last array on the console its return me like - "\n " and "\n\n " for last
I don't know, you have to fix it by yourself, I tried in jsfiddle and it works well enough to illustrate the principle.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.