Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract First n Words From String jQuery, Wordpress Style Excerpt In jQuery (x Number Of Words

I have a little jQuery snippet that works, but in order to improve my JS, I'd like suggestions on how to improve its efficiency.

This function shortens a WordPress Excerpt. It takes the original WordPress Excerpt and extracts the first 40 words, that's the part I care about. After that, it adds the 'Continue Reading' link at the end of the original Excerpt and adds it to the end of the truncated version.

Again, I just wondered what would be a faster/more concise way to return the truncated excerpt. I tried 'slice' and got a bunch of commas.

jQuery('.page-id-7 .promo_slider_excerpt').each(function (i) {
    var s = jQuery(this).html();
    var sw = s.split(' '); // separate contents into array of words
    var t = [];
    var v;
    if (sw.length > 40) {
        var a = jQuery(this).children('a'); // this is the Continue Reading link
        for (v = 0; v < 40; v++) {
            t = (t + ' ' + sw[v]); // Build the shortened excerpt (this is the part I wanted to improve)
        }
        t = (t + ' ' + a[0].outerHTML); // Add the Continue Reading onto the end
        jQuery(this).html(t);
    } else {
        t = s;
        jQuery(this).html(t);
    }
});
like image 863
jchwebdev Avatar asked Feb 21 '23 05:02

jchwebdev


1 Answers

For the first forty words and the continue reading link, I'd suggest:

var s = jQuery(this).text(),
    fortyWords = s.split(' ').slice(0,39).join(' '),
    link = document.createElement('a'),
    linkText = document.createTextNode('continue reading');
link.href = 'http://path.to.article/';
link.appendChild(linkText);
$(this).text(fortyWords).append(link);

JS Fiddle proof of concept.


Edited in response to further questions from OP (in comments, below):

1: Is there a way in Firebug to note the -efficiency- of one technique vs. another? IOW: your example looks good, but can I compare it's memory and speed vs my for loop?

I honestly don't know, I'm afraid I don't really use Firefox at all and, while I use Chromium almost exclusively, I've not worked with it long enough to discover the profiling tools for memory usage or speed.

There is, however, JS Perf, which will allow you to run tests to show the speed of operation of particular approaches; though it doesn't touch on memory-usage at all.

2: My version uses the .html() method and .outerHTML property. I keep seeing posts on the web that these are not -always- reliable. Is that some holdover from IE6? My users are all pretty current so I wonder why you choose to use .text() and then append a node?

html() is a good approach to use, but ideally to be used only if you want to work with the html, in a string format; in the above case it seemed easier to work with strings since all I really wanted to work with was the text-string. Had there been other elements within the element whose text() I was manipulating, then I'd've had to use html() otherwise those elements would have been over-written when writing/replacing the text into the DOM.

I seem to recall not having had much success using outerHTML historically, and, frankly, empirically. So I only rarely think to use it, though it is, simply, a matter of personal preference. As to its being a holdover from IE 6? I'm unsure; I wouldn't be surprised, but I don't know at all, unfortunately.

I chose to use text() because I was, as noted, working with text; and then I appended the node, separately, in html() because I was inserting an html node. Had I used passed the same contents entirely with html() then it would, I think, have worked. But, again, just personal preference and, I think, it makes it clear whether I'm manipulating/working with text or html.

References:

  • jQuery:
    • append().
    • slice().
    • text().
  • 'Plain' non-library JavaScript:
    • appendChild().
    • document.createElement().
    • document.createTextNode().
    • join().
    • slice().
    • split().
like image 189
David Thomas Avatar answered Apr 27 '23 17:04

David Thomas