Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Monday, November 3, 2008

Fast Trim Function for Javascript

Introduction

Following Steven Levithan's old post about string trimming.

I decided to give it another try after my first proposal.

I made a trim version, based on my aforementioned first attempt. It seems to be much faster on any browser and with different (string) lengths and whitespaces.


First of all...

I want to make clear that this version doesn't trim the exact same characters that other versions do.

In my first version, I simply tried to improve Steven's version without really giving it a deep thought.

This time I thought:Are all those characters really relevant?.

After thinking about this for a while I decided that, whatever /\s/ matches, should be trimmed.

Why ? because most major js libraries use the regex version. If their users are content, then those are the needed characters. Also, if my function would actually do better than others, it could go directly to jQuery's core (there's a ticket for that).

So I created a test page. The results weren't equal for all browsers, IE and Safari 3 yielded far less charCodes. I decided these are the ones I want to trim.


My Trim function

So, the basic modification I made to my previous version, was to check whether the charCode is lower than 33 instead of the whole map/object.

This one takes much less code and is quite faster, I humbly named it "myBestTrim", here it is:

// Licensed under BSD
function myBestTrim( str ){
 var start = -1,
  end = str.length;
 while( str.charCodeAt(--end) < 33 );
 while( str.charCodeAt(++start) < 33 );
 return str.slice( start, end + 1 );
};

The Benchmark

If you want to try the benchmark, get in here. The number should you care about (in my opinion) is the minimum. That's probably the one that ran a lower CPU level.

That test uses a string with 10K characters. Sounds like a lot but this blog's homepage has 55K of html. As oposed to a regex-based trim, this one should scale pretty well, because it doesn't need to check all the string.

That's actually why I removed any regex-based approach from this test, because they'd take too long.

If you have Firebug, I'd advice you to turn it off before getting into this test.

I made a similar test with small strings. It uses a string of 30 characters with 3 whitespaces on each side. In this case, the difference was smaller but still noticeable.

The only situation where another function was faster was on IE, with a small string WITH whitespaces. In this situation, jQuery's trim (the typical regex-based trim) was slightly faster, my trim got 2nd place.

Most situations don't really require much trimming and critical situations have very large strings, so I think this function scales well on those 2.


Conclusion

If all goes well, I'll put this function into jQuery's core. I'd like though, to get some results from other users, to verify my trim is really fast and effective.

Here's the ticket requesting a faster trim for jQuery: #2279.

11/6/08
Removed a dispensable check, thanks Andrea Giammarchi.

Wednesday, May 7, 2008

Textnode translator for Javascript

Introduction

This is a generic JS Class, that allows you to translate(parse) the content of text nodes, and replace them for the new content.
You only need to specify the parsing function, and the starting (root) node.
All the text nodes inside it, will get parsed.

Modes

The class supports synchronous and asynchronous parsing.
The parsing function will receive the original text as first argument.
If you can parse the text right away, then just return it from the parsing function.
If it needs to be delayed (f.e: AJAX request), then the set the attribute 'sync' of the instance, to false. By doing this, you will get a second argument in the parsing function, which will be a function that you need to call, passing it the parsed text.

Returned data

The parsed data you return can be:
  • a string
    This is the standard, a string replacing the old one.
  • nothing
    new If you don't return data, or the same string, it will just get skipped.
  • a node
    new You can return an html node.
  • an array
    new You can return an array with nodes and/or strings.

Filteringnew

Optionally, you can pass the translator, a filtering function. This way you can exclude elements (and their descendants) from the parsing.
To use it, pass the function as second argument to the constructor.
It will receive the (element) node, and it must return true or false.

How to use

Check the demo to see both modes and filtering in action.
You need to call the method 'traverse' of the instance, passing it the root node.
Remember to call the method after the html document is parsed, so you can access all the nodes in it.

Links

Downloads

Update 5/26/08
Added 1.0.1, updated the docs and demo.

Wednesday, February 20, 2008

Rotator

Introduction

This small Javascript class, serves as a generic rotator for different kind of collections.

Arguments

The Rotator class constructor expects 3 arguments, the last 2 are optional.
  • collection
    Can be a string, an array or an array-like object( arguments, nodelist, numeric hash ).
    If it's a string, it will get split by character.
  • setter
    A function that receives a value, an element of the collection and it's index.
    It must, either set the value internally or return the new value.
    The scope (this) will be the element, the arguments are the value and then the index.
    If it's a string, it means you want to set the value to the attribute of the element with that name.
    If none is given, then Rotator.defaultSetter is used, which, by default, returns the new value.
  • getter:
    A function that receives an element of the collection and the index.
    It must return the desired information from them.
    The scope (this) will be the element and the first argument, the index.
    If it's a string, it means you want the attribute of the element with that name.
    If none is given, then Rotator.defaultGetter is assigned, which, by default, returns the element.

How to use

Once you create an instance (obj) of the class, you can get/set the collection using the method obj.collection().
To rotate the elements, call obj.left() or obj.right().
With each call, the elements will be rotated one position in the direction you specified, and the functions will be called.
Note that the collection held by the object won't be the same that you gave it. Yours remains untouched.

Check the demo to see it working. If you view the source, you'll see 3 different instances.

Links

Downloads

Saturday, February 2, 2008

Feedback

I thought I'd create a post where readers could easily add general opinions and/or suggestions. The scope of this post is the entire blog, so it can be about any jQuery plugin, Maxthon's console, or the script to add Static methods to Array. General input about the blog is welcomed too.

Also I'd like to know, if someone's using any of these scripts on a site. So if you do, please let me know by posting a comment.

I also plan to make a list of sites using these scripts. So if you are interested, add the url and I'll link to your site.

Saturday, December 8, 2007

Javascript Console for Maxthon (JSCM) 2.0

Features

  • Execution of any kind of native javascript.
  • jQuery is integrated, is possible to access the elements in the active tab.
  • It includes an 'inspect' option, similar to Firebug's.
  • Console's results are dumped in a colorful way.
  • Dumped HTML elements, will allow quick inspection of the matched elements.
  • Switching between recently executed scripts, with Page Down and Page Up.
  • Frequently used scripts can be stored, for further use.
  • Functions Window() and Document() to retrieve the document and window objects from the active tab.

FAQ

  • How to access the elements in the active tab
    Using jQuery's selectors with no context, will match the elements in the neighboring page. So $('a') or jQuery('a') will match all the links in the page. For further information about jQuery, visit http://jquery.com.
  • What does inspect mean
    When Inspect is activated, moving the mouse over any element in the active tab, will highlight it. When an element is clicked, the plugin will generate a selector that will match that specific element and it will appear in the console. The same applies to dumped HTML elements.
  • Where can I get more examples
    The pack contains a file called Manual.txt which includes some examples with a short explanation. You can also check http://docs.jquery.com for jQuery related information.

Links

Friday, November 30, 2007

Static methods for Array

I wrote today a small piece of code, to add static methods to Array. These methods allow developers to manipulate arrays, arguments, node collections and array-like hashes in a normalized way. Using the built-in methods that arrays have. The js won't add forEach, map, etc. It will only take, those methods available for arrays, will make them compatible for array-like objects, and will append them to the Array object.

Extending the prototype of native object is a bad practice (for many) and will pollute the global scope (I fully agree with this). The added functions, will be only fulfilling the lack of these methods, in browsers that don't support them( only Firefox supports them, that I know of ).

Array static methods in Firefox, don't support node collections though. So calling this:

Array.pop(document.getElementsByTagName('p'));
Will fail in Firefox. Using:
[].pop.apply(document.getElementsByTagName('p'));
Won't work for nodes, and will throw an error in any browser.

That's why there're two versions of this code. The one called array, and array.lite. The latter won't override existing methods. In consequence, node collections won't be supported. On the contrary, array, will override as much as possible, ensuring support for node collections for those methods found in the prototype.

Here's a small demo to show it's use. It has been tested on Windows XP in IE6, FF 2, Safari 3 and Opera 9.22. I'm not sure, but it seems to be a little buggy in Opera, I still haven't figured out why.

Links Downloads: If this code is added after normalizing the new iteration methods they will also be added to the Array object