7b72d5a18ab92129692e97a76a153fe0

This function returns a jQuery object containing all descendent text nodes (and <br/> line breaks) within the context node. I'm looking to make this function as fast as possible, since I need to call it very frequently.

$.fn.textNodes = function() {
  var ret = [];
  this.each( function() {
    var fn = arguments.callee;
    $(this).contents().each( function() {
      if ( this.nodeType == 3 || $.nodeName(this, "br") ) 
        ret.push( this );
      else fn.apply( $(this) );
    });
  });
  return $(ret);
}

// example: wrap all text nodes in a span
$("body").textNodes().wrap("<span/>");

Refactorings

No refactoring yet !

Ee251c8e33a6ee0920d6bf43c5d0f541

jp.stacey

June 29, 2008, June 29, 2008 21:32, permalink

1 rating. Login to rate!

From what you say, you only need the descendants, not the starting node(s). So you can get it a bit smaller (and a little bit quicker) by removing one of your two function() blocks. How does this look to you?

You might get even quicker by using this.childNodes (which is what jQuery's contents() function uses internally), as long as you don't need to worry about iframes.

$.fn.textNodes = function() {
  var ret = [];
  this.contents().each( function() {
    var fn = arguments.callee;
      if ( this.nodeType == 3 || $.nodeName(this, "br") ) 
        ret.push( this );
      else $(this).contents().each(fn);
  });
  return $(ret);
}
5a00a3a98dcf6f9cd717440fd2b606e5

Eineki

June 30, 2008, June 30, 2008 10:43, permalink

1 rating. Login to rate!

Let me say that I'm rather new to jquery and my suggestions are probably naif.
Why don't you use something like this?
It is too slow?

$.fn.textNodes = function() {
   return this.find(*).filter(function(index) { return (this.nodeType==3)||(this.nodeName="br")}).andSelf();
}
7b72d5a18ab92129692e97a76a153fe0

jed

July 8, 2008, July 08, 2008 16:27, permalink

No rating. Login to rate!

@jp.stacey

Good catch. I did some informal profiling, and here's what I got on average:

(1) my original code: ~4100ms
(2) your refactor: ~2800ms
(3) your refactor w/ childNodes and no arguments.callee variable: ~2600ms

Not too shabby, thanks for your help!

@Eineki

Unfortunately, this.find(*) does not return text nodes.

$.fn.textNodes = function() {
  var ret = [];
  $.each(this[0].childNodes, function() {
      if ( this.nodeType == 3 || $.nodeName(this, "br") ) 
        ret.push( this );
      else $.each(this.childNodes, arguments.callee);
  });
  return $(ret);
}
915f797ee0f6ca0cf98c6b8565aa5fc7

Artur Honzawa

August 25, 2008, August 25, 2008 16:52, permalink

No rating. Login to rate!

Care to profile this version? I've skipped the jQuery library altogether, should be faster.

$.fn.textNodes = function() {
    var ret = [];

    (function(el){
        if (!el) return;
        if ((el.nodeType == 3)||(el.nodeName =="BR"))
            ret.push(el);
        else
            for (var i=0; i < el.childNodes.length; ++i)
                arguments.callee(el.childNodes[i]);
    })(this[0]);
    return $(ret);
}
D41d8cd98f00b204e9800998ecf8427e

Artur Honzawa

August 25, 2008, August 25, 2008 17:18, permalink

No rating. Login to rate!

Oops. The "if (!el) return;" is not necessary.

D41d8cd98f00b204e9800998ecf8427e

Anonymous

March 7, 2009, March 07, 2009 02:00, permalink

No rating. Login to rate!

eineki had the right idea

$.fn.textNodes = function()
{
  return $(this).contents().filter(function(){ return this.nodeType == 3 || this.nodeName == "BR" ; });
}
D41d8cd98f00b204e9800998ecf8427e

Fred

March 10, 2009, March 10, 2009 17:40, permalink

No rating. Login to rate!

This is not a refactoring, just a quick way of modifying text nodes within a tag, without modifying everything else.
e.g.: <a id='a' href='#'> <img src='' /> some text <img src='' /> </a>
$("#a").setFirstRealTextNode("other value");

will change " some text " to "other value"

jQuery.fn.setFirstRealTextNode=function(txt){return this.each(function(){var $=jQuery,c=$(this).contents().filter(function(){return this.nodeType==3&&$.trim(this.nodeValue).length>0;})[0];if(c)c.nodeValue=txt;})};
90577764446fabe1157fbc8a11e9ef78

OvellaAvele

August 30, 2011, August 30, 2011 09:41, permalink

No rating. Login to rate!

Hello,
http://www.azithromycinforsale.com/ - zithromax medication
Try to not rub your skin with a towel, and be sure that it is a clean towel, otherwise you may be putting bacteria on your face.
http://www.azithromycinforsale.com/ - cheap zithromax

B3faa5433e882f65cefe0c49a70eb30c

ingerfirm

September 14, 2011, September 14, 2011 16:29, permalink

No rating. Login to rate!

jeogrargy http://www.ryanfinnoceanracing.com/ - purchase klonopin Patients as well as medical professionals prefer Klonopin because it has a very low toxicity, a short half life, and it also begins to work quite quickly. http://www.ryanfinnoceanracing.com/ - clonazepam online

A256339a4ec2a66f43559b60c41a0726

AntinaTab

October 18, 2011, October 18, 2011 09:39, permalink

No rating. Login to rate!

AntinaTab, http://www.achetercialis-fr.com/ - cialis naturel Il est conseillГ© de consulter son mГ©decin avent de prendre le Cialis puisque le Cialis peut aussi avoir des interactions non dГ©sirГ©es avec certains mГ©dicaments http://www.achetercialis-fr.com/ - cialis pas cher

Bb5dc4ef405d7c2fd607cb596d489694

SwonseKes

October 15, 2011, October 15, 2011 00:12, permalink

No rating. Login to rate!

Hi, SwonseKes http://www.ordercheapbuspar.com/ - buspar drug This medication should not be stopped without the advice of a doctor. http://www.ordercheapbuspar.com/ - order buspar online

Your refactoring





Format Copy from initial code

or Cancel