3

I'm binding an html string to view using ngBindHtml. the string contents are plain text along with anchor elements.
for a plain text with ngBind I can use a filter like this one to limit text length to a certain word count.

I've tried it by creating a temp element on document and traversing along it's child nodes and counting the length of textContent:

app.filter('sliceTextContent', function () {
  return function (str, max) {
    var counter = 0;
    var shortenedStr = '';
    var wrap = document.createElement('div');
    wrap.innerHTML = str;

    for (var i = 0; i < wrap.childNodes.length; i++) {

      if (wrap.childNodes[i].textContent.length + counter < max) {
        shortenedStr += (wrap.childNodes[i].innerHTML) ? wrap.childNodes[i].innerHTML : wrap.childNodes[i].textContent;
        counter += wrap.childNodes[i].textContent.length;
      } else {
        wrap.childNodes[i].textContent = wrap.childNodes[i].textContent.substr(0, max - counter);
        shortenedStr += (wrap.childNodes[i].innerHTML) ? wrap.childNodes[i].innerHTML : wrap.childNodes[i].textContent;
        break;
      }
    };
    return shortenedStr;
  }
});


I think this is not optimal and may cause timing issues while encountering long strings which I have in my database. Do you have ideas to improve it?

5
  • To be more clear, you need to limit content text of an html string to a certain word count using a filter inside view? Commented Jan 25, 2015 at 13:40
  • @Gordian yes. exactly. Commented Jan 25, 2015 at 13:41
  • Instead of asking is it possible why not show us what you tried and provide demo? Will get better and faster response that way Commented Jan 25, 2015 at 13:50
  • @charlietfl yes. you're right, Thank you. I've written that. working. but because I think it's not optimal, I didn't include it not to interrupt your mind. Now I've added it to the question Commented Jan 25, 2015 at 14:41
  • without going through it thoroughly , I would have expected something similar since you can't simply count words and break the string if it has only part of an <a> tag but not all of it Commented Jan 25, 2015 at 14:47

1 Answer 1

1

here is what I would do: It’s more performant because:

  • No virtual dom required
  • No need to iterate through the whole string (just iterate till max).

Assumptions:

  • Anchor tags are: "" closing. That should be the case for valid html.
  • Link text doesn’t add up to max.

Code:

var longString = "Lorem ipsum dolor <a href='#'>link 1 </a> sit amet, consectetur adipiscing elit. Duis in rhoncus nisi. Suspendisse elementum convallis <a href='#'>link 1 </a>  faucibus. Nam elit nisl, cursus a mauris sit amet, mattis volutpat nulla. Suspendisse fermentum urna in lobortis semper. Vivamus eu commodo diam, ut blandit justo. Etiam at venenatis purus, a lobortis nisl. Ut fringilla mi nibh, id congue est ultricies ut. In maximus vestibulum sodales. Nulla tempor diam bibendum sapien tempus facilisis. Praesent suscipit dolor sed fringilla vulputate. Nulla dapibus est vitae magna sagittis sodales. In finibus semper convallis.";



function Filter (str, max) {
     
    if (str.length <= max) return str;
    
    var i = 0;
    var counter = 0;
    var insideAnchor = false;
    
    while (i < str.length && counter < max){
        
        i++;
        if (str[i] === '<' && str[i+1] === 'a')insideAnchor = true;
        if (insideAnchor && str[i] === '>' && str[i-1] ==='a' && str[i-2] === '/')insideAnchor = false;

        if (insideAnchor === false)counter ++;       
    }
    return str.substring(0,i);   
}

document.getElementById("me").innerHTML = '>>>' + Filter(longString, 21) + '<<<';
<p id="me"></p> 

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

4 Comments

thanks. This is good but doesn't count up the text inside anchors. this problem is solvable. but I'm not sure if iterating over 625 characters is faster than iterating over (e.g. ) 3 text nodes and 2 anchors links.
@alihaghighatkhah My solution is WAY faster than yours (about 25 times faster). try to do any performance benchmark and you will find out. the main reason is that creating dom elements is an extremely expensive task.
@alihaghighatkhah Yeah that’s what I was talking about. I remove the console.log() from my solution (which was unnecessary) and iterating over the string is WAY faster here is the new test: jsperf.com/html-word-counter/2
I didn't know a single console.log can ruin the performance! thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.