Thứ Tư, 11 tháng 6, 2014

What Is jQuery? [Using jQuery]

jQuery,  created by John Resig, responds to the common frustrations and  limitations that developers might havewitJavaScript. JavaScript code  is cumbersome to write and  verbose, and  it can be difficult to target the
specific HTML or CSS elements you wish to manipulate. jQuery  gives you a way to find these elements
quickly and  easily within your document. The technical name for targeting an object is DOM traversal. DOM stands for Document Object Model. The model provides a tree-like way to access page elements
through their tags and  other elements through JavaScript, as shown in Figure  18-1.

When  writing JavaScript code,  you usually have to spend time  dealing with browser and  operating system
incompatibilities. jQuery handles this for you. Also, there aren’t many high-level functions within JavaScript.
Commotasksuch as animating partof a page,  dragging things around, or having sortable elements don’t exist.jQuery ovecomes these limitations as well. Like Drupal, jQuery has a small and  efficient codebase, weighing
in at just under 30 kilobytes. At the heart of jQuery is an extensible framework that JavaScript developers can hoo into,  and  hundreds of jQuery plug-ins are already available at http://plugins.jquery.com/.


Figure 18-1. The DOM representation of http://jquery.com, using the
Mozilla DOM Inspector tool, which installs with the Firefox browser

The Old Way

Lets first do a quick  review of the pure JavaScript way of DOM traversal. The following code  shows how Drupal usedto find elements within a page (in this case, the legend element within all collapsible fieldsets) before jQuery came along:

var  fieldsets  = document.getElementsByTagName('fieldset'); var  legend,  fieldset;
for  (var  i = 0;  fieldset  = fieldsets[i];  i++)  {
if (!hasClass(fieldset,  'collapsible'))  { continue;}
legend  = fieldset.getElementsByTagName('legend'); if (legend.length  == 0)  {
continue;}legend  = legend[0];...}

And heres the updated code  within Drupal after jQuery entered the scene:
jQuery('fieldset.collapsible  > legend:not(.collapse-processed)',  context).each(function()
{... });

As you can see, jQuery  lives up to its tagline of “Write Less, Do More.”  jQuery takes the common, repetitive tasks of manipulating the DOM using  JavaScript and  encapsulates them behinconcise and intuitive syntax. The end  result is
code  that’s short, smart, and  easy to read.

How jQuery Works

jQuery  is a tool for finding things in a structured document. Elements from the document can be selected by using CSS
selectors ojQuery’s own custom selectors (a jQuery  plug-in supports the use of XPath selectors as well).
The use of CSS selectors foDOM traversal is helpful to the developer, because most developers are already familiar
with CSS syntax. jQuery has full support oCSS 1 to 3. Lets go through some very basic  examples of jQuery syntax
before we dive into using  jQuery  with Drupal.

Using a CSS ID Selector

Let’s do a quick review of basic CSS syntax. Suppose the HTML you want  to manipulate is the following:
<p id="intro">Welcome to  the  World of  Widgets.</p>
If you want  to set the background color of the paragraph to blue, you use CSS to target this specific paragraph in
your style sheet using the #intro CSS ID selector. According to the HTML specification, IDs must be unique within a
given document, swe are assured that no other element has this ID. Withithe style sheet that will be applied to your document, the following entry will make your paragraph blue:
#intro {
background-color: blue;}
Note that there are essentially two tasks here:  find the element that has the  #intro ID, and  set the background color
of thaelement to blue. Here’s how you can select  your paragraph and  turn the background color to blue using
jQuery: jQuery("#intro").css("background-color", "blue");
You could even add  a little jQuery pizzazz, and  slowly fade in the paragraph text:
jQuery("#intro").css("background-color", "blue").fadeIn("slow")

Using a CSS Class Selector

Here’s a similar example using  a CSS class selector instead of using  a CSS ID as we did in the preceding section. The HTML would be as follows:
<p class="intro">Welcome  to  the  World of  Widgets.</p>
<p class="intro">Widgets are   available in many sizes.</p>
Our CSS would look like this:
.intro  {background-color: blue;}
The following would also work, and  is a slightly more specific rule:
p.intro {background-color: blue;}
Here’s how the CSS translates to jQuery  code: jQuery(".intro").css("background color", "blue").fadeIn("slow");
or jQuery("p.intro").css("background-color", "blue").fadeIn("slow");
In the first of the preceding examples, you’re asking  jQuery  to find any HTML element that has the intro class, while in the second example you ask for any paragraph tag with an intro class. Note that the last example will be slightly
faster  because there’s less HTML for jQuery to search through, given the example’s restriction to just the paragraph
tags using p.introNow that youve had  a taste of how jQuery works, let’s see it in action within Drupal.

jQuery Within Drupal

Using jQuery within Drupal is easy because jQuery is preinstalled and  is automatically made available when JavaScript isadded. In Drupal, JavaScript files are added via the drupal_add_js() function or in the theme’s .info file.In this section, youll investigate some basic  jQuery  functionality within Drupal.

Your First jQuery Code

Let’s get set up to play with jQuery.

1.       Log into your Drupal site as user 1 (the administrative account).

2.       On the Modules page,  enable the PHP filter module.

3.       Create a new node of type Basic Page, but on the node creation form,  be sure to select  “PHP code” under the “Input formats” section, as shown in Figure  18-2. Enter  Testing jQuery as the title, and  add the following to the
body section of the form:
<?php
drupal_add_js('jQuery(document).ready(function () { jQuery("p").hide(); jQuery("p").fadeIn("slow");
});', 'inline');?>
<p id="one">Paragraph one</p>
<p>Paragraph two</p>
<p>Paragraph three</p>
4.       Click Submit, and  reload the page.  The three paragraphs you created will slowly fade in. Cool, eh? Refresh the
page to see it again. Let’s study this example a little more.


Figure 18-2. Experimenting with jQuery using the PHP filter

The jQuery  code  is contained in a file, misc/jquery.js. This file is not loaded for every page within Drupal. Instead, anytime drupal_add_js() call is made, jquery.js is loaded. Two parameters are passed into
drupal_add_js(). The first parameter is the JavaScript code  you wish to have executed, and the second
parameter (inline) tells Drupal to write the cod inside a pair of
<script></script> tags within the document’s <head> element.
Let’s look at the JavaScript jQuery  code  in more detail.
<?php
drupal_add_js('jQuery(document).ready(function () jQuery("p").hide(); jQuery("p").fadeIn("slow");});',
'inline');
?>

The jQuery(document).ready function needs a little more explanation. When  the browser is rendering a page,  it gets toa point where it has received the HTML and  fully parsed the DOM structure of the page.  The next step  is to render
that DOM,which includes loading additional local—and possibly even remotefiles. If you try to execute JavaScript code
before the DOM habeen generated, the code may throw errors and  not run  because the objects it wants to manipulate are not there yet. JavaScript programmers used to get around this by using  some variation of the following code  snippet:window.onload  = function(){ ... }

The difficulty with using window.onload is that it has to wait for the additional files to also load, which is too long of await. Additionally, the window.onload approach allows the assignment of only single function. To circumvent both
problems,jQuery has a simple statement that you can use:
jQuery(document).ready(function(){// Your code  here.});

jQuery(document).ready() is executed just after the DOM is generated. You’ll always want  to wrap jQuery code  in
the preceding statement for the reasons listed  earlier. The function() call defines an anonymous function in JavaScript—in this case,containing the code  you want  to execute. That leaves us with the actual meat of the code,  which ought to be self-explanatory at this point:
// Hide all the  paragraphs.
jQuery("p").hide();
// Fade them into visibility.
jQuery("p").fadeIn("slow");

The preceding code  finds all paragraph tags, hides them, and  then slowly reveals them within the page.  In jQuery  lingo,the fadeIn() part  is referred to as a method. The “p” isn’t preceded by a “.” or #” due to the p being a HTML tag
instead of a CSS class (.”) or ID (#”).

Targeting an Element by ID

Let’s repeat our experiment, but this time target only the first paragraph, which we’ve identified with the ID of one:
<?php
drupal_add_js('jQuery(document).ready(function () { jQuery("#one").hide();
jQuery("#one").fadeIn("slow");});', 'inline');?>
<p id="one">Paragraph one</p>
<p>Paragraph two</p>
<p>Paragraph three</p>

Method Chaining

We can concatenate a series  of jQuery methods because most methods within jQuery return a jQuery object. Let’s chainsome methods together in a single jQuery command:
// Hide all the  p tags, fade  them in  to  visibility, then  slide them up and down.
jQuery("p").hide().fadeIn("slow").slideUp("slow").slideDown("slow");
jQuery  calls are invoked from left to right.  The preceding snippet finds all the paragraph tags, fades them in, and  then uses sliding effect to move  the paragraphs up and  then down. Because each  of these methods returns the jQuery
wrapper object containing the same set it was given (all the p elements), we can manipulate the same set of elements
over and  over again until the final effect is achieved.

Adding or Removing a Class

jQuery can dynamically change the CSS class of an element. Here,  we turn the first paragraph of our example red by
selecting it by ID and  then assigning Drupal’s error class to it:
jQuery("#one").addClass("error");
The counterpart to the addClass() method is the removeClass() method. The following snippet will remove the erroclass we just added:
jQuery("#one").removeClass("error");
And then there’s the toggleClass() method, which adds or removes a class each  time  it is called:
jQuery("#one").toggleClass("error"); // Adds class  "error". jQuery("#one").toggleClass("error");
// Removes class  "error". jQuery("#one").toggleClass("error"); // Adds class "error"  again.

Wrapping Existing Elements

Instead of just adding an error class to the <p id="one"> element, let’s wrap that element in a div so that the red will show up better. The following jQuery snippet will do that:
<?php
drupal_add_js('jQuery(document).ready(function () { jQuery("#one").wrap("<div class=\'error\'></div>");
});', 'inline');?>
<p id="one">Paragraph one</p>
<p>Paragraph two</p>
<p>Paragraph three</p>

Note the escaping of the single quotes, which is necessary because we already have open single quotes inside the drupal_add_js() function. The result of the div wrapping is shown in Figure  18-3.


Figure 18-3. The paragraph with ID “one” is wrapped in a div tag of class “error”.

Changing Values of CSS Elements
jQuery  can be used to assign (or reassign) values  to CSS elements. Let’s set the border surrounding the first paragraph
to solid(see Figure  18-4):
jQuery("#one").wrap("<div class=\'error\'></div>").css("border", "solid");
Notice that the css method is still acting on the p element, not on the div element, because the wrap method returned
the targeted p element after wrapping it.


Figure 18-4. The border property of the target element is changed.

The preceding examples have demonstrated some basic  tasks that barely  scratched the surface of what  jQuery can do.You are urged to learn more at http://jquery.com/ or by picking up a good book on the subject.

Where  to Put JavaScript

In the preceding examples, you have been testing jQuery  by writing JavaScript in a node with the PHP filter enabled.
While this is handy for testing, that’s not a good approach for a production site, where best practices dictate that the
PHP filter be unavailable if at all possible. There are several different options for including JavaScript files in your Drupalsite. For example, you can add  them to your theme, include them from a module, or even include them but give others the option of modifying or overriding your code.

Adding JavaScript via a Theme .info File

The most convenient but least flexible way to include JavaScript files is to include a line in your theme’s .info file. 
Let’s add an effect to your site that emphasizes the logo of your site by making it fade out and then fade in again
when a page is loaded. Place the following JavaScript code  in a file called logofade.js in your current theme. For
example, if you areusing the Bartik theme, it would be at themes/bartik/logofade.js.
// Selects the  theme element  with  the  id  "logo", fades   it out,
// then  fades   it in  slowly.
jQuery(document).ready(function(){ jQuery("#logo").fadeOut("fast").fadeIn("slow");});

The JavaScript file is in place;  now we just have to tell Drupal to load it. Add the following line to your current
theme’s .info file: scripts[] = logofade.jsThe last step  is to make Drupal reread the .info file so that it will see that it
needs to load logofade.js.To do that, go to Appearance, temporarily switch to a different theme, and  then switch back.
This method of adding JavaScript is useful  if the JavaScript will be loaded on every single page of your web site. In
the next section, you’ll see how to add JavaScript only when a module that uses it is enabled.

A Module That Uses jQuery

Lets build  a small module that includes some jQuery functions in a JavaScript file. First, we’ll need a use case. Hmm,
how about some JavaScript code  that controls blocks? Blocks can be helpful in Drupal: they can show  you your login status, tell you who’s new on the site or who’s online, and  provide helpful navigation. But sometimes you just want  tofocus on the content of the page! Wouldn’t it be nice to hide blocks  by default and  show them only if you want  to
see them? The following module does just that, using jQuery  to identify and  hide  the block in the left an right side
bar regions and  providing a helpful button that will bring  the blocks  back. Here’s sites/all/modules/custom/blockaway.info:
name  = Block-Away
description  = Uses  jQuery  to  hide  blocks  until  a  button  is clicked.
package = Pro  Drupal  Development core  = 7.x files[]=blockaway.module

And heres sites/all/modules/custom/blockaway.module:
<?php
/**
*   @file
*   Use  this  module  to  learn  about  jQuery.
*/
/**
*   Implements  hook_init().
*/
function  blockaway_init()  {
drupal_add_js(drupal_get_path('module',  'blockaway')  .'/blockaway.js');}
All the module does  is include the following JavaScript file, which you can put at sites/all/modules/custom/blockaway/
blockaway.js:
/**
*   Hide  blocks  in  sidebars,  then  make  them  visible  at  the  click  of  a  button.
*/
jQuery(document).ready(function()  {
// Get  all  div  elements  of  class  'block'  inside  the  left  sidebar.
// Add  to  that  all  div  elements  of  class  'block'  inside  the
// right  sidebar.    Check  your themes  page.tpl.php  file  to  see what
// selectors  you should  use    the  following  are  for  garland.
var  blocks  = jQuery('#sidebar-first  div.block,  #sidebar-second  div.block');
// Hide  them.
blocks.hide();
// Add  a  button  that,  when  clicked,  will  make  them  reappear.
jQuery('#sidebar-first').prepend('<div  id="collapsibutton">Show  Blocks</div>'); jQuery('#collapsibutton').css({
'width':  '90px', 'border':  'solid', 'border-width':  '1px', 'padding':  '5px','background-color':  '#fff'});

// Add  a  handler  that   runs  once  when the  button  is clicked.
jQuery('#collapsibutton').one('click',  function() {
// Button  clicked! Get rid  of  the  button.
jQuery('#collapsibutton').remove();
// Display   all our  hidden  blocks   using  an effect.
blocks.slideDown("slow");});});
When  you enable the module on the Modules page,  any blocks  you have visible should disappear and  be replaced with a plain
button, as shown in Figure  18-5.


Figure 18-5. A nod being viewed with blockaway.module enabled

After clicking the button, the blocks  should appear using a sliding  effect, becoming visible as showin Figure  18-6.


Figure 18-6. After the Show  Blocks button is clicked, blocks become  visible.

Overridable JavaScript

The code  in blockaway.module is simple and  easy to understand. It just makes sure the blockaway.js file is included.However, if the module were more complicated, it would be friendlier to others to put the drupal_add_js() function call
in a theme function instead of in hook_init(). That way, those who wanted to use your module but customize the
JavaScript code  in some way could do so without touching your module code  at all (see Chapter 9 for how the theme
system works its magic). The code  that follows is a revised version of blockaway.module thatdeclares a theme function using  hook_theme(), moves the drupal_add_js() call into the theme function, and  calls the theme function from hook_init(). The functionality is the same, but savvy developers can now override the blockaway.js file.
<?php
/**
*   @file
*   Use this module to  learn   about  jQuery.
*/
/**
*   Implements hook_init().
*/
function blockaway_init() { theme('blockaway_javascript');
}
/**
*   Implements hook_theme().
*   Register our  theme function.
*/
function blockaway_theme()  { return  array('blockaway_javascript' => array( 'arguments' => array(),),);}

/**
*   Theme  function that   just makes sure  our  JavaScript file
*   gets included.
*/
function  theme_blockaway_javascript() { drupal_add_js(drupal_get_path('module', 'blockaway')  .'/blockaway.js');
}
Let’s go ahead and  see if this approach works. We’re going to override the JavaScript provided by the module with
JavaScript provided by the theme. Copy sites/all/modules/custom/blockaway/ blockaway.js  to your current theme—for example, themes/bartik/blockaway.js. Lets change the JavaScript file slightly so that we’ll know which JavaScript
file is being used. Change the effect from slideDown("slow") to fadeIn(5000); this will fade in the blocks  over a
period of five seconds. Here is the new file:
/**
*   Hide blocks   in  sidebars, then  make them visible at  the  click of  a  button.
*/
jQuery(document).ready(function() {
// Get all div  elements   of  class 'block' inside the  left  sidebar.
// Add  to  that   all div  elements   of  class  'block' inside the
// right sidebar.
var  blocks   = jQuery('#sidebar-first  div.block,  #sidebar-second div.block');
// Hide them.
blocks.hide();
// Add  a  button  that, when clicked, will make them reappear.
jQuery('#sidebar-first').prepend('<div id="collapsibutton">Show Blocks</div>'); jQuery('#collapsibutton').css({
'width': '90px', 'border': 'solid','border-width': '1px', 'padding': '5px', 'background-color': '#fff'});

// Add  a  handler  that   runs  once  when the  button  is clicked.
jQuery('#collapsibutton').one('click',  function() {
// Button  clicked! Get rid  of  the  button.
jQuery('#collapsibutton').remove();
// Display   all our  hidden  blocks   using  an effect.
blocks.fadeIn("5000");});});
The last change we need to make is to tell Drupal to load this new JavaScript file instead of the one  in sites/all/
modules/custom/blockaway.  We do that by overriding the theme function. Add the  following function to the template.php file of your theme (if your theme doesn’t have a template.php file, it’s okay to create one):
/**
*   Override  theme_blockaway_javascript() with  the
*   following function.
*/
function bartik_blockaway_javascript() { drupal_add_js(path_to_theme() . '/blockaway.js');}

Visit the Modules page to rebuild the theme registry so your changes will be recognized. When  you visit a page in yourweb browser, you should see the Show Blocks button, and  clicking it should reveal the blocks  via a gradual fade-in effect instead of the slide effect we were using earlier. Congratulations!
You’ve learned how to use jQuery  in your module, how to write it in a way that is friendly to themers and other developers, and  coincidentally, how to cleanly override or enhance JavaScript files provided by other module developers who have been equally courteous.
Before we leave this example, let me demonstrate how to override a template file. First, remove the bartik_blockaway_javascript() function that you added to the template.php file. Next, in your current theme, create an empty file called blockawayjavascript. tpl.php. For example, if you are using the Bartik theme, create themes/bartik/blockaway-javascript.tpl.php. Don’t put anything inside this file.
Now visit the Modules page. The act of visiting  this page will rebuild the theme registry. Drupal will find the template file and  use it instead of the theme function in your module. The result is that blockaway.js will never be loaded; youveessentially commented out the theme function by creating an empty template file (recall from Chapter 9 that, when
building the theme registry,Drupal will look for a template file and  then for theme functions).
Now, add the following to your blockaway-javascript.tpl.php file:

<?php drupal_add_js(path_to_theme() . '/blockaway.js'); ?>

When  you reload your page,  you should see that the JavaScript file is now loading. Do you see how these techniques
can be useful  for substituting your own enhanced JavaScript file in a third-party module or for preventing some
JavaScript from loading?

Không có nhận xét nào:

Đăng nhận xét