The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. September 16, 2019, 11:15:10 PM

Login with username, password and session length


Pages: [1] 2
  Print  
Author Topic: jQuery earns a place in Perk’s toolbox: 3 Clear Examples  (Read 21981 times)
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« on: February 21, 2010, 10:03:54 PM »

Although I’ve been taken by jQuery’s impressive API and all the discussion about it, there’s been limited need for me to really go in depth because I’m quite good with DOM manipulation routines and really, how can you go much faster than var target = document.getElementById(‘targetID’) ? Another angle here is that, having not known about jQuery through my learning curve of Javascript, I developed a way of thinking that took care of speed and code readability without it.

But all that said, I’ve been keeping my eyes open for opportunities to use jQuery both for personal edification and because I do believe it can make life easier.

Now, over the course of the last several months there have been 3 distinct examples where my life has been made much easier with jQuery. So with that, it’s become fixture in my toolbox and something that will get more of my attention as needs warrant. What I’d like to do in this post is outline my 3 examples as clearly as possible, hoping both to enlighten other jQuery n00bs and to entice jQuery experts to chew up my methods and tell me how to do things better.

Unobtrusive Javascript and late-bound GUI effects
My first real example is perhaps the most dramatic. I have a client with loads of web pages and loads of data on those pages. They wanted to make large blocks of those pages drop-downs, rather than huge scrollable pages. I’m not sure that it’s my favorite GUI design, but that’s immaterial here. From an SEO perspective, I did not want to damage our ranking or context at all by adding JavaScript or lots of crap to the content that Google would have to wade through. Consider the following HTML:

<div class=”pHead”>Lorem ipsum dolor sit amet</div>
<div class=”pBody”> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</div>

Now this could be done with P or any other number of CSS mechanisms, let’s not go into that here. The point is that I have multiple paragraphs, under the notion of a header, and the client wanted the header to be a drop-downable arrow rather than just huge, scrollable text. Additionally, there’s lots of this stuff on the site – and lots of folks involved in the content, certainly not just me. I needed to give them a DIV structure they could work with and do the code part outside of the content. This is where the “Unobtrusive” part of this example comes into play.

My strategy was to bind the onClick event of appropriate DIVs to a little bit of code so that I could simply change classes or styles of the content to create the effect. So my jQuery code will jump on the Page Complete event, looking for certain DIVs, vector their events to (me) and then use jQuery’s native functions to effect the transition as attractively as possible.

My solution was to wrap a “droppable” element into a new div, which I could style. Consider:

<div class=”pChunk”>
   <div class=”pHead”>Lorem ipsum dolor sit amet</div>
   <div class=”pBody”> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
   </div>
</div>


The code is incredibly small.  There are only 3 parts here: the code that jumps on the page-ready event, the function that binds onMouseOver, onMouseOut and onClick and the actual collapse logic:

Code:
function collapse(e)
{
var parent = e.target.parentNode;
var divs = parent.getElementsByTagName('DIV');
var target = $(divs[1]);
if (target.is(':visible'))
{
target.fadeOut('fast');
parent.style.backgroundImage = 'url(/graphics/rightTri.gif)';
} else {
target.fadeIn('fast');
parent.style.backgroundImage = 'url(/graphics/downTri.gif)';
}
}

function bind()
{
jQuery('.cChunk .pHead').bind('click', collapse).bind('mouseover mouseout', function(e) { e.target.style.textDecoration = (e.type == 'mouseover') ? 'underline' : 'none';} );
}

jQuery(function($) { bind(); } );

CSS file additions include:

.pChunk {
   background-position: 0 3px;
   background-image: url(/graphics/rightTri.gif);
   background-repeat: no-repeat;
   padding-left: 15px;
   margin-bottom: 10px;
}
.pChunk .pHead {
   cursor: pointer;
}
.pChunk .pBody {
   display: none;
}


The last bit of code is what jumps at the page ready, and it calls the bind() function. The Bind function binds the click event for any element that has a class pHead that is a child of an element that has a class pChunk. Using jQuery’s chaining feature, I continue on to bind the mouseOver and mouseOut events to an inline function that changes the text-decoration of the sender to underlined if mouseOver, non-underlined if mouseOut. The chaining feature of jQuery is definitely cool.

Now then: Someone clicks on a pChunk div and the collapse function is called. The (e) parameter is the jQuery event object – it is more lush than normal event objects and it is standardized, regardless of browser. Essentially, I get all the DIVs that are children of the clicked-on DIV, and based on their visibility, I either fade them out or fade them in. As you can see from the CSS styling of the pChunk, I have room for a little graphic on the left-hand side. The default is a right-facing triangle. As the element is clicked, it changes to facing down (content visible) and facing right (content hidden).

The net-net is that I was able to have the content people do minimal work, in fact only wrap chunks they wanted droppable, and my code did all the rest. As a site-wide inclusion, it made it so that any pages they added the simple pChunk wrapper around a block of content instantly became a drop down.

You want a demo? Of course you do, everyone loves a demo. CLICK HERE

Alternating Gray Bars on Rows of Content
I must admit, I was completely //yawn// about having jQuery do color alternation for me. I mean really. I’m already creating the content in PHP server side, the CSS file contains the definition for both colored rows, what’s the big deal for me?

The answer came when I added a content manipulation tool for a client. This client has a restaurant and I create a chalkboard of “Today’s Specials” for him (some of you may remember where I posted about it in a thread here). What I added was a “Move Up” / “Move Down” feature to the menu manager. The problem was that as the content rows (whole DIVs) moved up or down, they took their coloration with them! So I was obliged to re-color rows.

And so, this simple example from the first book I read became a life saver:

$('.menu_menuBlock:even').addClass('gray');
$('.menu_menuBlock:odd').removeClass('gray');

This is really, deceptively cool. First off, for those that don’t know: jQuery uses the JavaScript macro, $ for brevity. You may use jQuery or $ interchangeably in my examples. There are some libraries that want to make use of $ so make sure you read up on that if you use other libs than jQuery. Anyhoo, that first little line, called right after any Move Up or Move Down button is clicked, says “create a wrapped set out of every element that has the class menu_menuBlock (I only use this on DIVs I want to do this to) – but only the EVEN number among them, not all. In other words, DIV 0, 2, 4, 6 etc. To those, add the class ‘gray’ – the next line removes the gray class from any odd items. In fact, experienced jQuerysters will tell you that there are even more clever ways to do this, but it is pretty obvious here. So now, the colored bars appear to stay, the content moves in them. It’s a great look and super efficient.

Moving DIVs in relationship to each other
My last example is actually borne of frustration. I’d been trying to use the .prev() and .next() function in jQuery for several hours and just could not get them to work correctly. And here is my only complaint in this post about jQuery: it’s so big, so complicated and so powerful that it’s difficult to get your arms all the way around it, as well it’s difficult to know how to search for appropriate help with problems. I have several books on the subject, and a reasonably good Googler and nothing helped here. I am certain that I was doing something wrong, but it’s indicative of the nature of the package that I could not find an example or help with my problem. But I digress.

This example pertains to the same challenge I had in example 2: I want to move whole chunks of content above and below other chunks. Of course, my strategy is to simply reposition DIVs above or below their siblings. The appendBefore and appendAfter functions are particularly helpful here, because they will automatically do the parent change for me (In fairness, the DOM functions do the same, but it felt better here).

The code that comes from the AJAX handler sends back a DIV with the class “menu_menuBlock” and a bunch of stuff within it. The function that calls this is a button in each block with the onClick handler set to “menu_moveUp(this).” The handling code is as follows:
Code:
function menu_moveUp(sender)
{
var myBlock = $(sender).parents('.menu_menuBlock')[0];
var allBlocks = $('.menu_menuBlock', myBlock.parentNode);
var idx = allBlocks.index(myBlock);
if (idx == 0) return false;
$(myBlock).insertBefore(allBlocks[idx - 1]);
}
function menu_moveDown(sender)
{
var myBlock = $(sender).parents('.menu_menuBlock')[0];
var allBlocks = $('.menu_menuBlock', myBlock.parentNode);
var idx = allBlocks.index(myBlock);
if (idx >= allBlocks.size() - 1) return false;
$(myBlock).insertAfter(allBlocks[idx + 1]);
}

“Sender” is a commonly used name for the object that sent the event – and a throwback to my Delphi and Kylix days. Once again, I am certain that experienced jQuerysters will tell me I am FOS and that this is horribly inefficient – right then. I could use the help. But in the mean time, this is how that code works:
  • myBlock is set to the zeroth entry in a wrapped set of all parents of the sender that have the class “menu_menuBlock.” In other words, no matter how deep the sender is in the DOM, that will walk up the hierarchy of parents to find (my) parent with the correct class.
  • allBlocks becomes a wrapped set of all siblings, because of the way I did it: it looks for all elements that have the menu_menuBlock class WITHIN myBlock’s parent node. Note that this is an underused parameter in jQuery IMO: the second parameter locks jQuery to only looking for things that match param 1 within the context of param 2. This can REALLY make things faster, since you’re not looking through the entire DOM for something.
  • idx gets the numeric index position of the “sender block” within it’s parent.
  • The if () statement checks to make sure that this is a valid move. In the case of Move Up, if the sender’s index is 0 then there’s nowhere to move and the function returns without doing anything. In the case of Move Down, if the index is >= the size of the wrapped set then nothing happens.
  • Finally, I put myBlock back into a wrapped jQuery set (so that I can do stuff to it) and call insertBefore or insertAfter, passing the new location where I want it to be.

After all of that, I re-color the blocks Smiley

jQuery still pisses me off a lot. It’s complicated and not nearly as straight forward as I would like. On the other hand, as I get used to thinking it its rhythm, I see more applications for it. Clearly, once I’ve paid the price for downloading it, I might as well use it rather than write scads of new code. It’s a pretty damn great tool and I look forward to using it more in the future. I also *really* get that it will be a keystroke saver, as well as potentially a processor saver in the future. I still believe that there is overuse and people relying on if for the wrong things, but I'll post on that another time.

Good luck with it. Please tell me where I am foolish and inefficient – I’d really like to know the tool better.
« Last Edit: February 21, 2010, 10:17:23 PM by perkiset » Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
kurdt
Lifer
*****
Offline Offline

Posts: 1153


paha arkkitehti


View Profile
« Reply #1 on: February 21, 2010, 11:23:40 PM »

I think one of my big problems when it comes to working with jQuery and UIs is that you have to focus your thinking from raw code perspective to DOM bubbling and user interface stuff. It's completely different way of thinking how to code, at least to me. I think this is one of the biggest reasons why people haven't fully utilized javascripts UI capabilities until now with SproutCore and other similar frameworks. Web has been mostly creating a webpage that needs some sort of interactive functionality. Then it's been built with PHP and webpage has some really basic form type controls to use it. But now the people have started to do even more with javascript in the browser. The problem is that each browser has a little bit different way of doing stuff and this is where jQuery just kicks balls. To me jQuery is the only way of doing javascript because I can trust I only have to do it once and then it will works on all of the browsers.

jQuery also makes it possible to do complex user interfaces because it has almost all elements you would ever need to control multiple windows and flow of information. I could say that I view jQuery has PHP of Javascript - It might not be as fast as the native code but it's so fast to develop with and speed gets better with every version that the upsides really overpower the downsides.

For me the most utilized call in jQuery is $.ajax for sure. I think CSS3 will remove some of the benefits from using jQuery but it will be just a faster way to get those effects.
« Last Edit: February 21, 2010, 11:25:22 PM by kurdt » Logged

I met god and he had nothing to say to me.
herbacious
Journeyman
***
Offline Offline

Posts: 51


View Profile
« Reply #2 on: March 23, 2010, 01:13:02 AM »

got to love jquery Smiley

I like the terse programming style, powerful selectors eg $('#divid').click(function(){ /*do something*/ }); style.
Logged
Kovacs
Rookie
**
Offline Offline

Posts: 30



View Profile
« Reply #3 on: June 24, 2010, 02:43:54 PM »

+1 for jquery.  Lately I've been using jquery + fancybox for dropping full page iframes over the top of my regular content with some success.
Logged

No links in signatures please
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #4 on: June 24, 2010, 03:18:27 PM »

"regular" as in spam content? Is that holding rank for you?

Haven't used fancy box. What about it makes you happy?
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
Kovacs
Rookie
**
Offline Offline

Posts: 30



View Profile
« Reply #5 on: June 24, 2010, 04:02:55 PM »

I've been using it for both "legit" ads over the content on clean looking autoblogs (ie. you can see the real content dimmed underneath the overlay div on top, the top ad has a close button and the ad doesn't take up the full screen) and for hardcore splogs with generated content, where the background of the top div is a solid opaque colour that hides the "real" content, there's no close button on the top div, and to a javascript-enabled surfer, the top div appears to be all the content that there is to see.  The only problem with the latter method is that I have yet to find a way to shorten the scroll bars to the length of the top div - if you have a long page of real content underneath, then you will have a whole bunch of blank space underneath the FPA on top.  I'm sure I just have to look a bit harder.

If you're using this technique on a legit blog then jquery makes it super easy to check for and / or set a cookie so you only show the popup on someone's first visit.  Tons and tons of blogs do this.  If you search for "$competitive_niche blog" (eg. internet marketing blog, real estate blog were two examples I just checked) you will see at least one and sometimes several sites using some variation of this.  I think it's great from a marketing perspective: it's mildly annoying but it's like punching the surfer in the face with your offer.  He HAS to interact with the ad (which is always going to be your very best ad - you have no space or editorial restrictions...) before he can navigate to your content.  A simple target="_parent" on your affiliate links in the ad that you show and away you go.  There are so many legit people using some kind of js overlay that I don't feel it has any effect on rankings and it is almost certainly better than using any kind of js redirect.  The url of your overlay ad iframe doesn't exist on the html page and there are multiple things you can do to obfuscate / encode / eval your javascript.  It would be difficult to differentiate in an automated fashion what is a spammy overlay and what is part of the ajax content of a typical web 2.0 page.

I checked out several plug and play alternatives and fancy box appeared to be the most polished and is also used for warning pages on a few high volume tube sites, so it's somewhat proven.  What set fancy box apart from the rest was that it correctly recentered and resized the overlay div if the surfer resized the window.  It's super easy to use and the provided example file shows you how to do everything you might want to.

I also think using jquery especially helps you blend in with the crowd to some degree.  It seems to be THE js library out there right now, so much so that G even offers their own hotlinkable cache of it.  It seems natural that G would expect sites with jquery in the head section to contain content that is displayed via ajax style interfaces that deserves to be indexed.  There are all sorts of possibilities.

« Last Edit: June 24, 2010, 04:07:35 PM by Kovacs » Logged

No links in signatures please
serialnoob
Journeyman
***
Offline Offline

Posts: 88


View Profile
« Reply #6 on: August 10, 2010, 04:42:20 AM »

As always,  Applause

I thought I would just mention that I was naturally tempted to click on the triangle rather than the text title in your first example.

I actually got into this "whole ajax situation" playing with scriptaculous and php. That is when jquery appeared if I remember it right. It seems that scriptaculous's move to ruby was a big mistake in favor of jquery. Let alone that jquery was already easier to grasp!

It looks like jquery took over in only a few months. Amazing!

I wonder what the future looks like for node.js/jquery for instance
« Last Edit: August 10, 2010, 04:47:00 AM by serialnoob » Logged

Success consists of going from failure to failure without loss of enthusiasm - Winston Churchill
arms
Expert
****
Offline Offline

Posts: 235



View Profile
« Reply #7 on: August 10, 2010, 11:01:44 AM »

i haven't done anything in js without jquery for a while now. it's just too easy and clean.
it really gave me a new apreciation for javascript - along with the book "javascript the good parts".

as far as seo, my guess woul be it lends some legitamacy to sneaky js tricks. a jquery include is a strong signal to google that your site is a rich ui or ajax or whatever and make things like display:none completely normal and acceptable.

also, i asume googlebot can parse js and even jquery, but in my completely unscientific and unverified oppinion jquery makes it very difficult for googlebot to derive meaning from what you are doing. just one example, before jquery and ajax, display:none on a huge section of text meant one or two things - now it means 20.
Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #8 on: August 10, 2010, 11:16:22 AM »

Attention n00bs, golden nuggets in that last post.
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
arms
Expert
****
Offline Offline

Posts: 235



View Profile
« Reply #9 on: August 10, 2010, 11:46:48 AM »

 Smooch missed you perk.

i can't recommend enough "javascript the good parts" for anyone who has to use javascript regularly and would like to move away from hacking things together in js to programming in js.

you can write beatiful code in js but dealig with the dom is ugly and jquery fixes that. and it does it without forcing you to code in a way that is suited for purely oo languages like java but by taking advantage of javascript's strengths like first class functions.
Logged
serialnoob
Journeyman
***
Offline Offline

Posts: 88


View Profile
« Reply #10 on: August 10, 2010, 03:43:49 PM »

Attention n00bs, golden nuggets in that last post.

Perplexed, and English(ly) challenged, I thought http://www.urbandictionary.com/define.php?term=Golden%20Nugget  Undecided  ROFLMAO
Logged

Success consists of going from failure to failure without loss of enthusiasm - Winston Churchill
isthisthingon
Global Moderator
Lifer
*****
Offline Offline

Posts: 2879



View Profile
« Reply #11 on: August 10, 2010, 06:11:40 PM »

Attention n00bs, golden nuggets in that last post.

Perplexed, and English(ly) challenged, I thought http://www.urbandictionary.com/define.php?term=Golden%20Nugget  Undecided  ROFLMAO

 ROFLMAO ROFLMAO  Oh shat that was funny.

Arms is right.  After reading Javascript the good garts, I immediately bought and have already read Java the good parts and also PHP the good parts.  I'm looking forward to many other "the good parts" books because they're a great idea, perfect bathroom material (see Golden Nugget) and not too expensive.  Also, though I'm a total jQuery noob, I found the book jQuery: from novice to ninja to be a great read as well 
Logged

I would love to change the world, but they won't give me the source code.
isthisthingon
Global Moderator
Lifer
*****
Offline Offline

Posts: 2879



View Profile
« Reply #12 on: August 10, 2010, 06:27:47 PM »

I mentioned this thread to my girlfriend.  She replied with this:

Logged

I would love to change the world, but they won't give me the source code.
serialnoob
Journeyman
***
Offline Offline

Posts: 88


View Profile
« Reply #13 on: August 10, 2010, 06:38:46 PM »

I mentioned this thread to my girlfriend.  She replied with this:

Progress report:

I (did not) shoot the Sheriff.

I guess No. 3 is out now
Logged

Success consists of going from failure to failure without loss of enthusiasm - Winston Churchill
isthisthingon
Global Moderator
Lifer
*****
Offline Offline

Posts: 2879



View Profile
« Reply #14 on: August 10, 2010, 06:47:32 PM »

 ROFLMAO  Crap, #2 is still in...
Logged

I would love to change the world, but they won't give me the source code.
Pages: [1] 2
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!