Showing posts with label manipulation. Show all posts

jQuery: Add table row count column

In this post you will learn how to add a table column with a row count in it. If you are looking for "how to add a new table row", please refer to previous post.

Recently, a user on the jQuery mailing list asked how she could automatically add a table row counter into her table. She wanted to add a new column to her table and display the row number, so that her users could refer to row numbers while communicating. The user had the following HTML table markup:

<table class="transactions">
  <tr>
    <td>Order 1</td>
    <td>$10.99</td>
  </tr>
  <tr>
    <td>Order 2</td>
    <td>$4.50</td>
  </tr>
</table>

For cases like this, where you can be sure that there would be no table cell rowspans and there are only trs and tds. Then, jQuery code to add a counter is straightforward.

$('.transactions tr td:first-child').each(function(i){
  $(this).before('<td>'+(i+1)+'</td>');
});

Here, we are selecting first child td tags of all tr tags in a table with a transactions class. Then, we are iterating through them and passing a zero based index to the loop. While looping though the first row cells, we are adding new column just using .before('<td>'+(i+1)+'</td>') method. The resulting table would have the following markup:

<table class="transactions">
  <tr>
    <td>1</td>
    <td>Order 1</td>
    <td>$10.99</td>
  </tr>
  <tr>
    <td>2</td>
    <td>Order 2</td>
    <td>$4.50</td>
  </tr>
</table>

However, for cases when tables have header rows and footer, the above script may not behave as expected. That is why we have to take into the consideration table headers and footers. So the code snippet above will become:

$(".transactions").each(function(){
  $('th:first-child, thead td:first-child', this).each(function(){
    var tag = $(this).prop('tagName');
    $(this).before('<'+tag+'>#</'+tag+'>');
  });
  $('td:first-child', this).each(function(i){
    $(this).before('<td>'+(i+1)+'</td>');
  });
});

This code takes into the account the table headers and adds "#" header column for the counter. Still, this code is not as universal as it could have been. Let’s take into the account the possibility of row spans and multi line header rows and rewrite the code into the jQuery plugin with options.

So, here is the final code:

(function($){
  $.fn.extend({
    tableAddCounter: function(options) {
      
      // set up default options 
      var defaults = { 
        title:  '#',
        start:  1,
        id:     false, 
        class:  false,
      };

      // Overwrite default options with user provided
      var options = $.extend({}, defaults, options);

      return $(this).each(function(){
        // Make sure this is a table tag
        if($(this).is('table')){

          // Add column title unless set to 'false'
          if(!options.title) options.title = '';
          $('th:first-child, thead td:first-child', this).each(function(){
            var tagName = $(this).prop('tagName');
            $(this).before('<'+tagName+' rowspan="'+$('thead tr').length+'" class="'+options.class+'" id="'+options.id+'">'+options.title+'</'+tagName+'>');
          });
        
          // Add counter starting counter from 'start'
          $('tbody td:first-child', this).each(function(i){
            $(this).before('<td>' + (options.start + i) + '</td>');
          });
        
        }
      });
    }
  });
})(jQuery);

Plugin features

  • Can set custom settings as a hash parameter to the plugin:
    • title - counter column header text
    • start - the number to start the counter
    • id - CSS "id" to add to all the counter tds
    • class - CSS "class" to add to all the counter tds
  • It takes into consideration table header's row and column spans.
  • Gracefully degrade for browsers that do not support javascript.
  • Keeps your HTML mark up clean.
  • Make your tabular data more readable.

Example code

// Add row count with default settings
$('.myTables').tableAddCounter(); 

// Provide your settings for 
// column name, css class and start counter from 26
var options = { 
  name: "Count", 
  class: "counter",
  start: 26
};
$('.myTables').tableAddCounter(options);

Here is the original table (to the left) and new table (to the right) with row columns automatically added.

tableAddCounter jQuery plugin screenshot

jQuery: Get / set attribute values

This post describes how to get & set element’s attributes. Using jQuery you can get/set any attributes like id, class, style, name, title, etc. on any tag (<div>, <span>, <p>, etc.). This can be done using jQuery's .attr() and .prop() methods. If you are using jQuery version earlier than 1.6, then you have .attr() only.

The two methods are named accordingly to work with element's attributes and properties. The distinguish between them two was introduced in jQuery 1.6. For versions prior to 1.6 you don't need to worry about the difference and use .attr() in all cases. However, if you are working with newer versions of the library, you need to understand the difference between the two. You can read more about the difference between attributes and properties here and here. But before you dive into the details, let's see some examples.

Consider we have the following HTML tags on our page with corresponding attributes:

<div class="myContainer" id="wrapper">
  Some content 
  <a id="siteLink" title="Google" href="">link</a>
  <input type="checkbox" id="mycheckbox" checked="checked" />
</div>

In order to get container's id and the link's title attributes, we would use the following jQuery code:

// Get the ID of the selected div
var divID = $("div.myContainer").attr("id"); // "SiteLink"

// Get title attribute of a link
var linkTitle = $("#siteLink").attr("title"); // "Google"

// Get checkbox's "checked" state
$("#mycheckbox").prop("checked"); // returns boolean "true"
$("#mycheckbox").attr("checked"); // returns string "checked"

To set element’s attributes, you need to add it's value as the second parameter to the function.

// Add title to a link
$("a#siteLink").attr("title", "This is a link");

// Set table cell's collspan attribute
$("td.myDoubleCell").attr("colspan", 2);

// Mark checkbox as checked
$("#mycheckbox").prop("checked", true);

Additional notes

Here are some additional notes related to setting and getting attributes with jQuery that you should know:

  1. In most cases you use would want to use .prop() method. It is programmer friendly. It returns values of the right types which makes your code more readable and easy to understand, whereas .attr() always return string value. For example: .prop("checked") above returned boolean, style properties would return object with style properties that you can work on, etc.

  2. If jQuery selection returns more than one element, .attr()/.prop() functions would change only the first element’s attribute. If you need to change them all, you will have to do it in .each() loop.

    // Assume we have many links on our page
    $('a').prop('target', '_blank'); // Set target of the first link only
    
    // Setting the target of all links in the loop
    $('a').each(function(){
      $(this).prop('target', '_blank');
    });
  3. Finally, you are not limited to W3 Consortium defined set of HTML attributes. You can also set your own attributes with their own values.

    //This code adds myAttr attribute with the value of 10
    $("#container").attr("myAttr", "10");
    
    // Read the value
    $("#container").attr("myAttr");

Dynamically change <title> using jQuery

In this post I will show how to dynamically change document's title using JavaScript and jQuery. Browsing the web (and StackOverflow) I saw a lot of posts that say you can't do it using jQuery. Actually, there is a jQuery syntax that is basically a wrapper for javascript code (see below).

Note: just to clarify, by document title we mean the text that is displayed in the browser window or a tab.

The best way to change the document title is to use native javascript api document.title.

document.title = "New text set by JavasSript";

The equivalent jQuery code of js code above.

$(document).prop('title', 'New text set by jQuery');

Example

Let's say we need to change the tab title text when a user clicks on a button. Here is a jQuery code to do just that:

<html>
<head>
  <title>Initial page title</title>
  <script src="path-to/jquery.js"></script>
  <script>
    $(document).ready(function(){
      $('#clickme').click(function(){
        document.title = $(this).val();
        // jQuery syntax alternative
        // $("title").text( $(this).val() );
      });
    });
  </script>
</head>
<body>
  <input type="button" id="clickme" name="clickme" value="Click me!" />
</body>
</html>

To conclude, you are better off using document.title, because it is cross-browser and has performs better.

Alternative jQuery syntax has been tested in all major browsers.

Dynamically create iframe with jQuery

This article explains and shows how to dynamically create an iframe in your HTML document’s DOM using jQuery and/or JavaScript. It also gives you an example code. This post is not extensive explanation of how to manage and work with iframes using jQuery. This post simply shows you how to dynamically create iframes using jQuery and JavaScript and serves as a note.

Creating iframe is similar to creating any DOM element. All you need to do is to use jQuery factory like this:

// Create an iframe element
$(‘<iframe />’);

// You can also create it with attributes set
$('<iframe id="myFrame" name="myFrame">');

// Finnaly attach it into the DOM
$('<iframe id="myFrame" name="myFrame">').appendTo('body');

Don’t forget that the iframe source is just an iframe’s attribute. So you can set that just like any other attribute.

// Setting iframe's source
$('<iframe />').attr('src', 'http://www.google.com'); 

UPDATE:

As BinaryKitten point’s out below, with jQuery 1.4 you can do it using the following syntax:

// Set attributes as a second parameter
$('<iframe />', {
    name: 'myFrame',
    id:   'myFrame',
    ...
}).appendTo('body');

diggthis.js + jQuery .wrap() is not working, causing Firefox to freeze and Safari to crush

I came across a forum post where user was experiencing problems while using Digg this (diggthis.js) button code with jQuery’s .wrap() method. According to him Mozilla Firefox (FF) is freezing and Apple Safari is crushing when he tries to wrap the div that contains diggthis.js file with another new div like so:

<div class="rounded"> 
  <script type="text/javascript"> 
    digg_url = "myURL.com"; 
  </script> 
  <script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script>
</div>

And the jQuery code is:

$(document).ready(function(){ 
    $("div.rounded").wrap('<div></div>'); 
});

This code seems to crush those browsers. Another way to do this is to remove the div that contains the script (.rounded), then create a new <div> and then insert the removed div (.rounded) back into the newly created div like this:

$(document).ready(function(){ 
    $("div.rounded").remove().wrap('<div></div>').appendTo("#somewhere"); 
});

Remove n’th table column - jQuery plugin

My usual short Friday post. Today I would like to share with you a new utility I wrote to work with HTML tables. We already have jQuery functions to add table row, remove table row (on user click), add table row number plugin and now here is jQuery code to remove table column.

jQuery utility to remove table’s n’th column:

$.fn.removeCol = function(col){
    // Make sure col has value
    if(!col){ col = 1; }
    $('tr td:nth-child('+col+'), tr th:nth-child('+col+')', this).remove();
    return this;
};

Just add this code to your javascript file and use it in your jQuery code like this:

// Remove all table's second columns
$('table').removeCol(2);

// Remove table's first column (default)
$('table').removeCol();

The function takes column number to delete as an argument and removes that column. If you don’t supply any column number it removes the first table column by default.

Remove table row on user click

This post is about removing a table row on user click. I needed this functionality for a project of mine. Online application had a table with data that user can dynamically add and remove. With progressive enhancement I also need to add a functionality to one of the tables that enables users to delete table rows when that table row is clicked.

jQuery code to delete clicked table row came out to be surprisingly short, only 3 lines of code.

// Select all table cells to bind a click event
$('table td').click(function(){
    $(this).parent().remove();
});

Here, we are first selecting all table cells to bind our click event. On user click to any table cell click event fires. In the click event we are removing <td>’s parent, which is <tr>, thus removing whole row.

By popular user demand I’m including an example that lets deleting a table row on delete image click. Here is our HTML table:

<table>
  <tr>
    <td>row 1, cell 1</td>
    <td><img class="delete" src="del.gif" /></td>
  </tr>
  <tr>
    <td>row 2, cell 1</td>
    <td><img class="delete" src="del.gif" /></td>
  </tr>
</table>

Here is jQuery code to delete a row on delete image click:

$('table td img.delete').click(function(){
    $(this).parent().parent().remove();
});

See demos here.

Bonus: Also delete a table row from database

The code above is enough if you don’t need to also delete a record from your database table. In my case I had to set up a server side code to do that. With one extra AJAX call to my server side script the functionality was ready.

$('table td').click(function(){
  $.get('deleteRow.php', {id: $(this).parent().attr('id')},
    function(){
        $(this).parent().remove();
  });
});

In the jQuery code above, instead of removing table row straight away we are making an AJAX call to our server side code that also removes that row from our database and then on AJAX call completion we removing table row.

Remove the bottom table row using jQuery

I have posted a small jQuery code a while ago which adds a table row at the bottom of any given table. The code takes into the consideration tbody tag and also can be used as a jQuery plugin.

Recently I was asked to write a jQuery or JavaScript code that removes the last/bottom row from the given table. The jQuery code I wrote was surprisingly small.

jQuery code to remove bottom/last table row

// Simple bottom row removal
$('#myTable tr:last').remove();

// Removing n'th (ex. 3rd) row from the table
$('#myTable tr:eq(2)').remove();

Improved jQuery code

We can improve our simple bottom row removal code to take into the consideration the possible <tbody> and <tfoot> HTML tags that can be found in tables.

// Improved code that takes into the consideration
// the <tbody> tag
$('#myTable').each(function(){
    if($('tbody', this).length > 0){
        $('tbody tr:last', this).remove();
    }else {
        $('tr:last', this).remove();
    }
});

// Improved code that for n'th row removal
// In this example we are removing 3rd row
$('#myTable').each(function(){
    if($('tbody', this).length > 0){
        $('tbody tr:eq(2)', this).remove();
    }else {
        $('tr:eq(2)', this).remove();
    }
});

Bonus JavaScript function

You can also turn the code above into the jQuery plugin or JavaScript function. Here is a JavaScript function to remove the bottom table row (you can amend the code to make it remove n’th row).

/*
    Remove the last/bottom table row
*/
function removeTableRow(jQtable){
    jQtable.each(function(){
        if($('tbody', this).length > 0){
            $('tbody tr:last', this).remove();
        }else {
            $('tr:last', this).remove();
        }
    });
}

// Here is how to use it
removeTableRow($('table'));
Also the above javascript function can easily be rewritten as a jQuery plugin. Read this post to learn how to create jQuery plugins.

jQuery image swap or How to replace an image with another one using jQuery

Swapping one image with another is probably one of the most used javascript techniques. Also Dreamweaver made “image replacement” even easier for non HTML/Javascript programmers by including this feature out of the box. One thing about Dreamweaver’s image swapping javascript is that it’s not the most beautiful javascript code. Well, as always with anything javascript related, jQuery is to the rescue.

jQuery makes dynamic image swapping a peace of cake. All you need to do to replace your image with another one is to replace its src attribute. The browser will take care of the rest.

Here is an example:

$("#myImage").attr("src", "path/to/newImage.jpg");

In the code above we are:

  1. Selecting an image to be replaced;
  2. Changing its src attribute to the new replacer image’s URL.

TIP:
To avoid page jumping and improve user experience it is a good idea to preload your images before you swap them.

Dynamically creating input box/checkbox/radio button... does not work in Internet Explorer (IE)

While working on some project, trying to create a checkbox and radio button dynamically using jQuery I came across a problem. Mozilla Firefox, Opera and Safari were creating and rendering my new checkboxes just fine, but Internet Explorer (IE6, IE7) did not create them. I spend half a day trying to figure out what is wrong with my jQuery or JavaScript code. Some hours later, I remember, I came across a post saying that IE can not create a general DOM input form element and then assign it a type (checkbox, radio, text, password, etc) attribute.

What you need to do when you are creating a new checkbox or radio button set with jQuery is to define the type attribute while creating like so:

$('<input type="checkbox" />');
// Create and then set any other attributes
$('<input type="checkbox" />').attr('id', 'newBox');

Problem:

Can not create a new input form fields using jQuery or newly created checkboxes and radio buttons are not displayed/created.

Solution:

To solve the problem you need to create an input field with type attribute already defined.

Convert javascript objects into arrays for better performance

jQuery Howto blog has many posts on your javascript  and jQuery code performance. If you have read the last performance post named “5 easy tips on how to improve code performance with huge data sets in jQuery” then you probably got an idea that it’s better to work with arrays for better javascript performance.

The only problem is that jQuery returns an object not an array when you select elements. Consider you have an object with lots of entries and you have to perform some manipulations that are available in javascript array such as reverse, sort, join, etc. Using built in methods is much faster then those you might write yourself. So the best thing would be converting your objects to arrays and jQuery provides utility method that does exactly this – jQuery.makeArray(obj).

// From jQuery Documentation
var arr = jQuery.makeArray(document.getElementsByTagName("div"));
arr.reverse(); // use an Array method on list of dom elements
$(arr).appendTo(document.body);

Preload images with jQuery

Web2.0 came with AJAX and AJAX came with its own requirements and standards for web application developers. Now web applications are more like desktop applications with a lot of options, dialogs and more. If you have developed AJAX application with different user controls you surely loaded resources such images, other javascript files on demand. This helps you keep your application lightweight and makes its load time faster.

jQuery makes creation and loading DOM elements (in our case images) very easy. If you need to preload an image you can use this jQuery script here:

// Create an image element
var image1 = $('<img />').attr('src', 'imageURL.jpg');

First jQuery creates a image DOM element and setting the src attribute of the image element would tell the user browser to load that image. Thus preloading the image.

Next you should insert your DOM element into the DOM tree using one of the many jQuery DOM manipulation methods.

Here are some examples of how you could insert preloaded image into your website:

var image1 = $('<img />').attr('src', 'imageURL.jpg');

// Insert preloaded image into the DOM tree
$('.profile').append(image1);
// OR
image1.appendTo('.profile');

But the best way is to use a callback function, so it inserts the preloaded image into the application when it has completed loading. To achieve this simply use .load() jQuery event.

// Insert preloaded image after it finishes loading
$('<img />')
    .attr('src', 'imageURL.jpg')
    .load(function(){
        $('.profile').append( $(this) );
        // Your other custom code
    });

Similar how to’s:

Add table row using jQuery and JavaScript

I noticed that there are a lot of developers who need to dynamically add a new table row to the bottom of their tables. I wrote a little javascript function that takes your jQuery selection of tables and dynamically adds a table row at the bottom of them.

jQuery add table row function definition:

/*
    Add a new table row to the bottom of the table
*/

function addTableRow(jQtable){
    jQtable.each(function(){
        var $table = $(this);
        // Number of td's in the last table row
        var n = $('tr:last td', this).length;
        var tds = '<tr>';
        for(var i = 0; i < n; i++){
            tds += '<td>&nbsp;</td>';
        }
        tds += '</tr>';
        if($('tbody', this).length > 0){
            $('tbody', this).append(tds);
        }else {
            $(this).append(tds);
        }
    });
}

jQuery add table row function usage example:

addTableRow($('#myTable'));
addTableRow($('.myTables'));

Font cleartype problems with fadeIn() and fadeOut() in Internet Explorer 7 (IE7)

Have you ever noticed whenever you use jQuery's fadeIn() and fadeOut() functions your text will become edgy. Mozilla and other seem to be rendering fine (not sure about IE6). Anyway, to solve this problem you need to remove the filter attribute from the DOM element that you have faded in/out.

For example:

// This causes this text glich
$("#message").fadeIn();

// This will fix it
document.getElementById("#message").style.removeAttribute("filter");

Screenshots:

SS-20090216194727

SS-20090216194422 

You need to remove the filter attribute after fadeIn() function has completed its job. In other words, as a function callback. Otherwise, fadeIn()/fadeOut() functions would change the opacity of the element, which in turn would cause the filter attribute to be attached yet again. So, remove the attribute in function callback like this:

$('#message').fadeIn(function(){
    this.style.removeAttribute("filter");
});

5 easy tips on how to improve code performance with huge data sets in jQuery

Sitting on jQuery's support mailing list I noticed that developers use jQuery with huge data sets and their code becomes very slow. Examples would be generating very long tables with a lot of rows using AJAX to get JSON data. Or iterating through a long (very long) list of data, etc.

So I compiled a list of 5 easy tips on how to improve your code performance while working with huge data sets in jQuery.

  1. Use JavaScript native for() loop instead of jQuery's $.each() helper function.

    Native browser functions are always faster then any other helper functions that were built to add an abstraction layer. In case you are looping through an object that you have received as JSON, I highly recommend you rewrite your JSON to contain an array rather than an object.

  2. Do NOT append an element to the DOM in your loop.

    This one is probably one of the most important tips that will significantly improve your code performance. It is so important that I will repeat myself. Do not append a new element to the DOM in your loop statement. Instead store it in a variable as text and append it to the DOM after your loop finishes like this:

    // DO NOT DO THIS 
    for (var i=0; i<=rows.length; i++)  
    { 
        $('#myTable').append('<tr><td>'+rows[i]+'</td></tr>'); 
    } 
    
    // INSTEAD DO THIS 
    var tmp = ''; 
    for (var i=0; i<=rows.length; i++)  
    { 
        tmp += '<tr><td>'+rows[i]+'</td></tr>'; 
    } 
    $('#myTable').append(tmp);

  3. If you have a lot of elements to be inserted into the DOM, surround them with a parent element for better performance.

    When you have a lot of elements to insert into the DOM tree it takes time to add them all. Somehow adding one element with 1000 children is faster than adding 1000 children separately. You can search this site for performance tests that prove it.
    So, to improve our previous example's performance let's cover <tr>'s with <tbody> tag like this:

    var tmp = '<tbody>';
    for (var i=0; i<=rows.length; i++)
    {
        tmp += '<tr><td>'+rows[i]+'</td></tr>';
    }
    tmp += '</tbody>';
    $('#myTable').append(tmp);

  4. Don't use string concatenation, instead use array's join() method for a very long strings.

    var tmp = [];
    tmp[0] = '<tbody>';
    for (var i=1; i<=rows.length; i++)
    {
        tmp[i] = '<tr><td>'+rows[i-1]+'</td></tr>';
    }
    tmp[tmp.length] = '</tbody>';
    $('#myTable').append(tmp.join(''));

  5. And the last but not least use setTimeout() function for your long list looping and concatenation functions.

    This will make sure that page does not freeze while it loops through the long list of data and lets users to work with your page meanwhile.

    It was well mentioned in comments that setTimeout() function should be used to split your code processing into little chunks so your browser does not freeze up like this:

    function myFunk(data){ 
         
        // do processing 
         
        if(!has_finished) 
            setTimeout("myFunk()", 100); 
    }

How to get full html string including the selected element itself with jQuery's $.html()

Sometimes you need to get the selected element's html as well when using .html() function. To make it more clear what I mean, consider you have this HTML markup:

<div id="top">
  <div id="inner">
    Some content
  </div>
  More content
</div>

And you need to get not only <div id="inner">Some con... but <div id="top"><div id="inner">Some con...

Here is the code to get jQuery selector's HTML including its own:

var html = $('<div>').append($('#top').clone()).remove().html();

Here we are:

  1. Cloning selected div
  2. Creating a new div DOM object and appending created clone of the div
  3. Then getting the contents of wrapped div (which would give us all HTML)
  4. Finally removing the created DOM object, so it does not clutter our DOM tree.

This is a little trick you can use to select self HTML with jQuery's .html() function. But if you can you should surround your markup with some dummy div and avoid this workaround all together. This would be much faster since jQuery would not need to do all the DOM manipulations.

jQuery: How to disable form element, link, etc.

In this post you will learn how to disable and enable different HTML elements (input, textarea, links, etc.) using jQuery. First, let's categorize the diffent types of elements that can be disabled using jQuery. We can categorize them into 3 general categories. Method of disabling items in each category is different.

If I missed some other element that does not fall under any of those 3 categories please leave a comment. The idea behind any method is very simple though. Usually all you have to do is to change element's attribute. See example below to get an idea.


Here are the three categories that we mentioned:

  1. Form elements - input fields, textarea, buttons, select boxes, radio buttons, etc.
  2. Anchor links - make text links non clickable.
  3. Bound jQuery events - for example bound click event on a <div>.

1. Disable form elements

Consider you have a form and you need to disable some element on it. All you have to do to disable it is to add disabled property to that element (input, textarea, select, button). Let's see an example:

<form action="url" method="post">
  <input type="text" class="input-field" value=".input-field">
  <input type="button" class="button-field" value=".input-field">
  <input type="radio" class="radio-button" value=".input-radio">
  <select class="select-box">
    <option value="1">One</option>
  <select class="select-box">
</form>

jQuery code to disable form elements and enable them back:

// jQuery code to disable
$('.input-field').prop('disabled', true);
$('.button-field').prop('disabled', true);
$('.radio-button').prop('disabled', true);
$('.select-box').prop('disabled', true);

// To enable an element you need to either
// remove the disabled attribute or set it to "false"
// For jQuery versions earlier than 1.6, replace .prop() with .attr()
$('.input-field').prop('disabled', false);
$('.button-field').removeAttr('disabled');
$('.radio-button').prop('disabled', null);
$('.select-box').prop('disabled', false);

Caveats & notes

Setting form element's disabled attirbute causes browsers not to sent that element to the server on form submit. In other words, your server script will not receive that form element's value. The workaround to that problem is to sent readonly attribute instead of disabled. This will make your fields non editable, but browser will still send the data to the server.

2. Disable anchor link (<a href="" ...>)

Now, let's see how to disable a link on your page, so that when user clicks on it browser does not follow it. There 2 methods to do that:

  1. Catch click event and prevent default bahaviour;
  2. Replace link's href property to "#".

I personaly prefer the first method, but you may have different needs. Let's see both methods in action.

<!-- Consider we have this HTML -->
<a href="aboutus.html" class="internal">some internal link<a>
<a href="http://www.google.com" class="external">external link<a>
// Bind "onclick" event
$('.internal').on("click", function(e){
  e.preventDefault();
  return false;
});

// Replace link's "href" attribute
$('.external').prop('href', '#');

Caveats & notes

In the onclick example above we added e.preventDefault() method which would stop event propagation. If you have other events relying on it on parent elements, please remove that method call. Also, when setting link's new href attribute, you can save the initial value with .data() method in order to set it back later.

// Removing e.preventDefault();
$('.internal').on("click", function(e){
  return false;
});

// Recording link's "href" attribute for later use
$('.external').data('original-href', $('.external').attr('href'));
$('.external').prop('href', '#');

// Setting it back
$('.external').prop('href', $('.external').data('original-href'));

3. Unbinding bound jQuery events

Last but not least is unbinding previously bound events. This is probably the easiest of the batch. All you have to do is to use jQuery's .unbind() method. Let's see an example:

<div class="some-elem">
  Click me
</div>
// Bind "click" event
$('.some-elem').on('click', function(){
  alert("Div is clicked!");
});

// Unbind "click" event
$('.some-elem').unbind('click');

Caveats & notes

Unbinding click event will unbind all click events that were bound to that element. So, if you want to unbind only your click event, without affecting others you have 2 options:

  1. Namespace your events;
    // Namespacing events
    $('.some-elem').on('click.my_event', function(){
      alert("Div is clicked!");
    });
    
    // Unbind namespaced event
    $('.some-elem').unbind('click.my_event');
  2. Use function reference when binding and unbinding.
    // User function reference
    var my_func = function(){
      alert("Div is clicked!");
    };
    
    // Bind using function reference
    $('.some-elem').on('click', my_func);
    
    // Unbind namespaced event
    $('.some-elem').unbind('click', my_func);