Skip to main content

Course Progress

Loading...

Refactor Your JavaScript Code Using jQuery

Duration: 60 minutes
Module 1: Modern JavaScript & jQuery

Learning Objectives

  • Understand JavaScript fundamentals
  • Add interactivity to web pages
  • Manipulate page elements dynamically
  • Handle user interactions

Assignment Overview

In this assignment, you will refactor your existing JavaScript code to use jQuery. This task will help you understand the advantages of using a JavaScript library like jQuery for DOM manipulation, event handling, and AJAX operations. You'll learn how to write more concise code while maintaining the same functionality, and gain an understanding of how jQuery can simplify common web development tasks.

George Polya's 4-Step Problem Solving Method

Step 1: Understand the Problem

We need to refactor our existing JavaScript code to use jQuery. This involves:

  • Understanding what jQuery is and its benefits
  • Identifying the key areas where jQuery can simplify our code
  • Ensuring that the refactored code maintains the same functionality
  • Following jQuery best practices

The goal is not to change what our code does, but to change how it achieves the same results using jQuery's more concise syntax and powerful methods.

Step 2: Devise a Plan

  1. Set up jQuery in our project
  2. Refactor the following key areas:
    • DOM selection and manipulation
    • Event binding
    • CSS manipulation
    • Basic animations and effects
    • AJAX operations (if applicable)
  3. Organize code using jQuery's document ready function
  4. Test all functionality to ensure it works the same as before
  5. Use jQuery's chainable methods to write more concise code

Step 3: Execute the Plan

Let's walk through the refactoring process step by step:

Solution: Refactoring with jQuery

Step 1: Set Up jQuery

First, we need to include the jQuery library in our HTML file, either by downloading it or using a CDN:

<!-- Add this in the head section of your HTML file -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

<!-- Alternatively, download jQuery and reference it locally -->
<!-- <script src="js/jquery.min.js"></script> -->

Next, we'll structure our JavaScript file to use jQuery's document ready function:

// Standard document ready function
$(document).ready(function() {
    // All jQuery code goes here
});

// Shorthand version
$(function() {
    // All jQuery code goes here
});

This ensures our jQuery code runs after the DOM is fully loaded, similar to DOMContentLoaded in vanilla JavaScript.

Step 2: Refactoring Examples

Let's look at common JavaScript operations and how to refactor them with jQuery:

1. DOM Selection and Manipulation

Vanilla JavaScript:

// Selecting elements
const heading = document.getElementById('main-heading');
const paragraphs = document.getElementsByClassName('paragraph');
const buttons = document.querySelectorAll('.btn');

// Creating elements
const newDiv = document.createElement('div');
newDiv.className = 'container';
newDiv.textContent = 'Hello, World!';
document.body.appendChild(newDiv);

// Modifying content
heading.textContent = 'New Heading';
heading.innerHTML = 'New <em>Heading</em>';

// Getting/setting attributes
const link = document.getElementById('my-link');
const href = link.getAttribute('href');
link.setAttribute('target', '_blank');

jQuery:

// Selecting elements
const heading = $('#main-heading');
const paragraphs = $('.paragraph');
const buttons = $('.btn');

// Creating elements
$('<div>', {
    'class': 'container',
    'text': 'Hello, World!'
}).appendTo('body');

// Modifying content
$('#main-heading').text('New Heading');
$('#main-heading').html('New <em>Heading</em>');

// Getting/setting attributes
const link = $('#my-link');
const href = link.attr('href');
link.attr('target', '_blank');

2. Event Handling

Vanilla JavaScript:

// Click event
document.getElementById('my-button').addEventListener('click', function(e) {
    console.log('Button clicked!');
    e.preventDefault();
});

// Multiple elements
const buttons = document.querySelectorAll('.btn');
buttons.forEach(button => {
    button.addEventListener('click', handleClick);
});

function handleClick(e) {
    console.log('Button clicked:', this.textContent);
}

// Removing event listener
document.getElementById('my-button').removeEventListener('click', handleClick);

jQuery:

// Click event
$('#my-button').on('click', function(e) {
    console.log('Button clicked!');
    e.preventDefault();
});

// Multiple elements (no loop needed)
$('.btn').on('click', function() {
    console.log('Button clicked:', $(this).text());
});

// Event delegation (for dynamic elements)
$('.container').on('click', '.btn', function() {
    console.log('Dynamically created button clicked:', $(this).text());
});

// Removing event listener
$('#my-button').off('click', handleClick);

3. Manipulating CSS

Vanilla JavaScript:

// Adding/removing classes
const element = document.getElementById('my-element');
element.classList.add('active');
element.classList.remove('inactive');
element.classList.toggle('visible');
const hasClass = element.classList.contains('active');

// Inline styles
element.style.color = 'red';
element.style.backgroundColor = '#f0f0f0';
element.style.fontSize = '16px';

jQuery:

// Adding/removing classes
const element = $('#my-element');
element.addClass('active');
element.removeClass('inactive');
element.toggleClass('visible');
const hasClass = element.hasClass('active');

// Inline styles
element.css('color', 'red');
element.css({
    'background-color': '#f0f0f0',
    'font-size': '16px'
});

4. Basic Animations and Effects

Vanilla JavaScript:

// Show/hide with vanilla JS (requires CSS transitions or custom code)
const element = document.getElementById('my-element');

// Show
element.style.opacity = '1';
element.style.display = 'block';

// Hide
element.style.opacity = '0';
setTimeout(() => {
    element.style.display = 'none';
}, 500);

// Custom animation with vanilla JS
let pos = 0;
const box = document.getElementById('my-box');
const id = setInterval(frame, 10);

function frame() {
    if (pos === 300) {
        clearInterval(id);
    } else {
        pos++;
        box.style.top = pos + 'px';
        box.style.left = pos + 'px';
    }
}

jQuery:

// Show/hide with jQuery
const element = $('#my-element');

// Show
element.fadeIn(500);     // or .slideDown()
element.show();          // Immediate

// Hide
element.fadeOut(500);    // or .slideUp()
element.hide();          // Immediate

// Toggle
element.toggle();        // Show or hide
element.fadeToggle(500); // Fade in or out

// Custom animation with jQuery
$('#my-box').animate({
    top: '300px',
    left: '300px'
}, 500, 'swing', function() {
    console.log('Animation complete!');
});

5. AJAX Operations

Vanilla JavaScript:

// Fetch API (modern vanilla JS)
fetch('https://api.example.com/data')
    .then(response => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json();
    })
    .then(data => {
        console.log('Data:', data);
        // Process data
    })
    .catch(error => {
        console.error('Error:', error);
    });

// XMLHttpRequest (older vanilla JS)
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.onload = function() {
    if (xhr.status === 200) {
        const data = JSON.parse(xhr.responseText);
        console.log('Data:', data);
        // Process data
    } else {
        console.error('Request failed with status:', xhr.status);
    }
};
xhr.onerror = function() {
    console.error('Request failed');
};
xhr.send();

jQuery:

// jQuery AJAX
$.ajax({
    url: 'https://api.example.com/data',
    method: 'GET',
    dataType: 'json',
    success: function(data) {
        console.log('Data:', data);
        // Process data
    },
    error: function(jqXHR, textStatus, errorThrown) {
        console.error('Error:', textStatus, errorThrown);
    }
});

// Shorthand methods
$.get('https://api.example.com/data', function(data) {
    console.log('Data:', data);
});

$.getJSON('https://api.example.com/data', function(data) {
    console.log('Data:', data);
});

Step 3: Complete Refactoring Example

Let's look at a concrete example of refactoring a form validation script:

Original Vanilla JavaScript

// Wait for DOM to load
document.addEventListener('DOMContentLoaded', function() {
    const contactForm = document.getElementById('contact-form');
    const nameInput = document.getElementById('name');
    const emailInput = document.getElementById('email');
    const messageInput = document.getElementById('message');
    const submitButton = document.getElementById('submit-btn');
    
    // Validation functions
    function validateName() {
        const nameValue = nameInput.value.trim();
        const nameError = document.getElementById('name-error');
        
        if (nameValue === '') {
            nameError.textContent = 'Name is required';
            nameInput.classList.add('invalid');
            return false;
        } else if (nameValue.length < 2) {
            nameError.textContent = 'Name must be at least 2 characters';
            nameInput.classList.add('invalid');
            return false;
        } else {
            nameError.textContent = '';
            nameInput.classList.remove('invalid');
            nameInput.classList.add('valid');
            return true;
        }
    }
    
    function validateEmail() {
        const emailValue = emailInput.value.trim();
        const emailError = document.getElementById('email-error');
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        
        if (emailValue === '') {
            emailError.textContent = 'Email is required';
            emailInput.classList.add('invalid');
            return false;
        } else if (!emailRegex.test(emailValue)) {
            emailError.textContent = 'Please enter a valid email';
            emailInput.classList.add('invalid');
            return false;
        } else {
            emailError.textContent = '';
            emailInput.classList.remove('invalid');
            emailInput.classList.add('valid');
            return true;
        }
    }
    
    function validateMessage() {
        const messageValue = messageInput.value.trim();
        const messageError = document.getElementById('message-error');
        
        if (messageValue === '') {
            messageError.textContent = 'Message is required';
            messageInput.classList.add('invalid');
            return false;
        } else if (messageValue.length < 10) {
            messageError.textContent = 'Message must be at least 10 characters';
            messageInput.classList.add('invalid');
            return false;
        } else {
            messageError.textContent = '';
            messageInput.classList.remove('invalid');
            messageInput.classList.add('valid');
            return true;
        }
    }
    
    // Add event listeners
    nameInput.addEventListener('blur', validateName);
    emailInput.addEventListener('blur', validateEmail);
    messageInput.addEventListener('blur', validateMessage);
    
    // Live validation as user types
    nameInput.addEventListener('input', function() {
        if (nameInput.classList.contains('invalid')) {
            validateName();
        }
    });
    
    emailInput.addEventListener('input', function() {
        if (emailInput.classList.contains('invalid')) {
            validateEmail();
        }
    });
    
    messageInput.addEventListener('input', function() {
        if (messageInput.classList.contains('invalid')) {
            validateMessage();
        }
    });
    
    // Form submission
    contactForm.addEventListener('submit', function(e) {
        e.preventDefault();
        
        const isNameValid = validateName();
        const isEmailValid = validateEmail();
        const isMessageValid = validateMessage();
        
        if (isNameValid && isEmailValid && isMessageValid) {
            // Show loading state
            submitButton.textContent = 'Sending...';
            submitButton.disabled = true;
            
            // Simulate form submission (AJAX call would go here)
            setTimeout(function() {
                contactForm.reset();
                
                // Remove validation classes
                nameInput.classList.remove('valid');
                emailInput.classList.remove('valid');
                messageInput.classList.remove('valid');
                
                // Show success message
                const formResult = document.getElementById('form-result');
                formResult.innerHTML = `
                    <div class="success-message">
                        <h3>Message Sent Successfully!</h3>
                        <p>Thank you for contacting us. We'll get back to you soon!</p>
                    </div>
                `;
                formResult.style.display = 'block';
                
                // Reset button
                submitButton.textContent = 'Send Message';
                submitButton.disabled = false;
                
                // Hide success message after 5 seconds
                setTimeout(function() {
                    formResult.style.display = 'none';
                }, 5000);
                
            }, 1500); // Simulate network delay
        }
    });
});

Refactored with jQuery

// jQuery document ready
$(function() {
    const $contactForm = $('#contact-form');
    const $nameInput = $('#name');
    const $emailInput = $('#email');
    const $messageInput = $('#message');
    const $submitButton = $('#submit-btn');
    const $formResult = $('#form-result');
    
    // Validation functions
    function validateName() {
        const nameValue = $nameInput.val().trim();
        const $nameError = $('#name-error');
        
        if (nameValue === '') {
            $nameError.text('Name is required');
            $nameInput.addClass('invalid').removeClass('valid');
            return false;
        } else if (nameValue.length < 2) {
            $nameError.text('Name must be at least 2 characters');
            $nameInput.addClass('invalid').removeClass('valid');
            return false;
        } else {
            $nameError.text('');
            $nameInput.removeClass('invalid').addClass('valid');
            return true;
        }
    }
    
    function validateEmail() {
        const emailValue = $emailInput.val().trim();
        const $emailError = $('#email-error');
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        
        if (emailValue === '') {
            $emailError.text('Email is required');
            $emailInput.addClass('invalid').removeClass('valid');
            return false;
        } else if (!emailRegex.test(emailValue)) {
            $emailError.text('Please enter a valid email');
            $emailInput.addClass('invalid').removeClass('valid');
            return false;
        } else {
            $emailError.text('');
            $emailInput.removeClass('invalid').addClass('valid');
            return true;
        }
    }
    
    function validateMessage() {
        const messageValue = $messageInput.val().trim();
        const $messageError = $('#message-error');
        
        if (messageValue === '') {
            $messageError.text('Message is required');
            $messageInput.addClass('invalid').removeClass('valid');
            return false;
        } else if (messageValue.length < 10) {
            $messageError.text('Message must be at least 10 characters');
            $messageInput.addClass('invalid').removeClass('valid');
            return false;
        } else {
            $messageError.text('');
            $messageInput.removeClass('invalid').addClass('valid');
            return true;
        }
    }
    
    // Add event listeners
    $nameInput.on('blur', validateName);
    $emailInput.on('blur', validateEmail);
    $messageInput.on('blur', validateMessage);
    
    // Live validation as user types
    $nameInput.on('input', function() {
        if ($(this).hasClass('invalid')) {
            validateName();
        }
    });
    
    $emailInput.on('input', function() {
        if ($(this).hasClass('invalid')) {
            validateEmail();
        }
    });
    
    $messageInput.on('input', function() {
        if ($(this).hasClass('invalid')) {
            validateMessage();
        }
    });
    
    // Form submission
    $contactForm.on('submit', function(e) {
        e.preventDefault();
        
        const isNameValid = validateName();
        const isEmailValid = validateEmail();
        const isMessageValid = validateMessage();
        
        if (isNameValid && isEmailValid && isMessageValid) {
            // Show loading state
            $submitButton.text('Sending...').prop('disabled', true);
            
            // Simulate form submission (AJAX call would go here)
            setTimeout(function() {
                $contactForm.trigger('reset');
                
                // Remove validation classes
                $nameInput.removeClass('valid');
                $emailInput.removeClass('valid');
                $messageInput.removeClass('valid');
                
                // Show success message
                $formResult.html(`
                    <div class="success-message">
                        <h3>Message Sent Successfully!</h3>
                        <p>Thank you for contacting us. We'll get back to you soon!</p>
                    </div>
                `).fadeIn();
                
                // Reset button
                $submitButton.text('Send Message').prop('disabled', false);
                
                // Hide success message after 5 seconds
                setTimeout(function() {
                    $formResult.fadeOut();
                }, 5000);
                
            }, 1500); // Simulate network delay
        }
    });
});

Key Improvements:

  • Used $ prefix for jQuery objects (common convention)
  • Simplified DOM selection with jQuery selectors
  • Used jQuery's chaining for adding/removing multiple classes
  • Replaced textContent with text() method
  • Used prop() for property manipulation
  • Added fadeIn() and fadeOut() effects for smoother UX
  • Used trigger('reset') instead of reset()
  • Overall: more concise code with the same functionality

Step 4: Look Back and Review

Our refactoring has successfully converted vanilla JavaScript to jQuery while maintaining the same functionality. The key benefits of our refactored code include:

  • Shorter, more concise code that is easier to read and maintain
  • Better cross-browser compatibility through jQuery's abstraction
  • Simplified DOM manipulation and event handling
  • Smooth animations and effects with minimal code
  • Chainable methods for more efficient coding

jQuery shines particularly in reducing the amount of code needed for DOM traversal, event handling, and animations. While modern vanilla JavaScript has improved significantly, jQuery still offers convenience and cross-browser compatibility that can be valuable for certain projects.

Understanding jQuery

What is jQuery?

jQuery DOM Manipulation Event Handling AJAX Effects/Animations Utilities Selection Traversal Manipulation Event Binding Event Delegation Event Helpers AJAX Requests JSON Parsing AJAX Events Basic Effects Custom Animations Queue Management Array Helpers Feature Detection Data Storage

jQuery Library Architecture and Components

jQuery is a fast, small, and feature-rich JavaScript library designed to simplify HTML DOM traversal and manipulation, event handling, animations, and AJAX. It was created by John Resig and released in 2006, and quickly became one of the most popular JavaScript libraries due to its simplicity and utility.

Core principles of jQuery include:

  • Simplicity: "Write less, do more" is jQuery's motto
  • Cross-browser compatibility: Works consistently across different browsers
  • Extensibility: Easy to extend with plugins
  • CSS3 support: Implements CSS3 selectors even in older browsers
  • Chainable methods: Most methods return the jQuery object, allowing method chaining

jQuery vs. Vanilla JavaScript

Feature jQuery Vanilla JavaScript
Size ~30KB minified & gzipped (additional file to download) No additional library needed
Browser Compatibility Excellent, handles cross-browser issues Modern browsers have good compatibility, but may require polyfills for older browsers
DOM Selection Simple, consistent syntax: $('#id') Multiple methods: getElementById, querySelector, etc.
Chaining Built-in method chaining: $('div').hide().addClass('hidden') Requires more code or custom implementation
Animations Simple built-in methods: fadeIn(), slideDown() Requires more code using CSS transitions or Web Animations API
AJAX Simple, concise: $.ajax(), $.getJSON() Fetch API is powerful but more verbose
Performance Generally slower due to abstraction layer Typically faster, especially for simple operations
Learning Curve Easy to learn, consistent API Steeper learning curve, more verbosity
Modern Web Development Less commonly used in new projects Preferred in modern frameworks and applications

When to Use jQuery Today:

  • Projects that need to support older browsers (IE9, etc.)
  • Simple websites where you don't need a full framework
  • When you need to quickly add interactivity without much code
  • When working with legacy code that already uses jQuery
  • When using jQuery plugins that provide specific functionality

When to Use Vanilla JavaScript:

  • Modern web applications that target newer browsers
  • Performance-critical applications
  • When working with modern frameworks (React, Vue, Angular)
  • When file size and load performance are critical
  • When you want to avoid external dependencies

jQuery Best Practices

1. Cache jQuery Objects

Store jQuery objects in variables when you plan to reuse them:

// Poor practice - repeatedly querying the DOM
$('#myElement').addClass('active');
$('#myElement').text('Updated content');
$('#myElement').on('click', handleClick);

// Better practice - cache the jQuery object
const $myElement = $('#myElement');
$myElement.addClass('active');
$myElement.text('Updated content');
$myElement.on('click', handleClick);

// Even better with chaining
const $myElement = $('#myElement');
$myElement
    .addClass('active')
    .text('Updated content')
    .on('click', handleClick);

Caching jQuery objects improves performance by avoiding repeated DOM queries.

2. Use Proper Selectors

Use efficient selectors to improve performance:

// Poor performance (traverses entire DOM)
$('.my-class');

// Better performance (searches only within context)
$('.my-class', $('#container'));
// or
$('#container').find('.my-class');

// Best performance (ID selectors are the fastest)
$('#specific-element');

Selector performance (from fastest to slowest): ID > Element > Class > Pseudo-selectors

3. Use Event Delegation

Bind events to a parent element instead of individual elements:

// Poor practice - binds to each element individually
$('.button').on('click', handleClick); // Need to rebind for dynamically added elements

// Better practice - event delegation
$('#container').on('click', '.button', handleClick);

Event delegation is more efficient and automatically works for dynamically added elements.

4. Optimize DOM Manipulation

Minimize DOM manipulation, especially in loops:

// Poor practice - manipulates DOM in each iteration
for (let i = 0; i < 100; i++) {
    $('#list').append('<li>Item ' + i + '</li>');
}

// Better practice - build string first, then append once
let items = '';
for (let i = 0; i < 100; i++) {
    items += '<li>Item ' + i + '</li>';
}
$('#list').append(items);

Or use document fragments for complex manipulations:

// Creating many elements efficiently
const $fragment = $(document.createDocumentFragment());
for (let i = 0; i < 100; i++) {
    $fragment.append($('<li>').text('Item ' + i));
}
$('#list').append($fragment);

5. Use Method Chaining

Take advantage of jQuery's chainable methods:

// Without chaining
$('#element').addClass('active');
$('#element').css('color', 'red');
$('#element').text('Updated');
$('#element').on('click', handleClick);

// With chaining
$('#element')
    .addClass('active')
    .css('color', 'red')
    .text('Updated')
    .on('click', handleClick);

Chaining makes code more concise and slightly more efficient.

6. Use forEach Alternative

Use jQuery's each() method to iterate over elements:

// Using jQuery each
$('.items').each(function(index, element) {
    // `this` refers to the DOM element
    // `element` is the same as `this`
    const $element = $(this);
    $element.text('Item ' + index);
});

The each() method provides a convenient way to iterate over jQuery collections.

7. Prefer Shorthand Methods

Use jQuery's shorthand methods when available:

// Long form
$('#element').on('click', handleClick);

// Shorthand
$('#element').click(handleClick);

// Long form AJAX
$.ajax({
    url: 'data.json',
    method: 'GET',
    dataType: 'json',
    success: handleSuccess,
    error: handleError
});

// Shorthand AJAX
$.getJSON('data.json', handleSuccess);

Shorthand methods are more concise and still provide the same functionality for common use cases.

8. Use noConflict When Necessary

If you're using multiple libraries that use the $ symbol, use noConflict:

// Give up $ to another library
const $j = jQuery.noConflict();

// Now use $j instead of $
$j(document).ready(function() {
    $j('#element').text('Updated with jQuery');
});

// Or use an immediately invoked function expression (IIFE)
jQuery.noConflict();
(function($) {
    // $ is still available inside this function
    $(document).ready(function() {
        $('#element').text('Updated with jQuery');
    });
})(jQuery);

This helps prevent conflicts between jQuery and other libraries that use the $ variable.

Working with jQuery Plugins

What are jQuery Plugins?

jQuery plugins are extensions that add new functionality to the jQuery library. Plugins allow developers to use specialized features without having to write complex code from scratch.

Common types of jQuery plugins include:

  • UI components (sliders, modals, tabs)
  • Form enhancements (validation, masks, autocomplete)
  • Animation effects
  • Data visualization
  • Image galleries
  • Social media integrations

Using jQuery Plugins

To use a jQuery plugin:

  1. Include jQuery in your page
  2. Include the plugin's JavaScript file after jQuery
  3. Include any required CSS files
  4. Initialize the plugin on your elements
<!-- Include jQuery and plugin files -->
<script src="jquery.min.js"></script>
<script src="jquery.somePlugin.js"></script>
<link rel="stylesheet" href="jquery.somePlugin.css">

<!-- HTML markup -->
<div id="my-element"></div>

<script>
    // Initialize plugin with default options
    $('#my-element').somePlugin();
    
    // Or with custom options
    $('#my-element').somePlugin({
        option1: 'value1',
        option2: 'value2'
    });
</script>

Example: Using jQuery UI Datepicker

<!-- Include jQuery and jQuery UI -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">

<!-- HTML markup -->
<input type="text" id="datepicker" placeholder="Select a date">

<script>
    $(function() {
        // Basic initialization
        $('#datepicker').datepicker();
        
        // With options
        $('#datepicker').datepicker({
            dateFormat: 'yy-mm-dd',
            showAnim: 'slideDown',
            minDate: 0, // Disable past dates
            onSelect: function(dateText) {
                console.log('Selected date:', dateText);
            }
        });
    });
</script>

Transitioning from jQuery to Modern JavaScript

2006 2010 2015 2019 2023 jQuery Released jQuery UI & Mobile jQuery Dominance ES6 Released Modern JS Features Modern Frameworks React, Vue, Angular jQuery Usage Declining Modern JS Preferred jQuery and Modern JavaScript Timeline jQuery Era Modern JavaScript Era

Modern JavaScript Equivalents

Modern JavaScript (ES6+) has introduced features that provide similar functionality to jQuery:

1. DOM Selection

jQuery:

const $element = $('#myElement');
const $elements = $('.my-class');
const $childElements = $('#parent').find('.child');

Modern JavaScript:

const element = document.getElementById('myElement');
const elements = document.querySelectorAll('.my-class');
const childElements = document.querySelector('#parent').querySelectorAll('.child');

2. DOM Manipulation

jQuery:

$element.text('New text');
$element.html('<span>New HTML</span>');
$element.addClass('active').removeClass('inactive');
$element.css('color', 'red');

Modern JavaScript:

element.textContent = 'New text';
element.innerHTML = '<span>New HTML</span>';
element.classList.add('active');
element.classList.remove('inactive');
element.style.color = 'red';

3. Event Handling

jQuery:

$element.on('click', function() {
    console.log('Clicked!');
});

$('#parent').on('click', '.child', function() {
    console.log('Child clicked!');
});

Modern JavaScript:

element.addEventListener('click', function() {
    console.log('Clicked!');
});

// Event delegation
document.querySelector('#parent').addEventListener('click', function(e) {
    if (e.target.matches('.child')) {
        console.log('Child clicked!');
    }
});

4. AJAX

jQuery:

$.ajax({
    url: 'api/data',
    method: 'GET',
    dataType: 'json',
    success: function(data) {
        console.log('Data received:', data);
    },
    error: function(xhr, status, error) {
        console.error('Error:', error);
    }
});

Modern JavaScript:

fetch('api/data')
    .then(response => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json();
    })
    .then(data => {
        console.log('Data received:', data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

5. Looping Through Elements

jQuery:

$('.items').each(function(index, element) {
    console.log(index, $(this).text());
});

Modern JavaScript:

document.querySelectorAll('.items').forEach((element, index) => {
    console.log(index, element.textContent);
});

6. Animation

jQuery:

$element.fadeIn(500);
$element.slideUp(300);
$element.animate({
    opacity: 0.5,
    left: '50px',
    height: '100px'
}, 500);

Modern JavaScript:

// Using CSS transitions
element.style.transition = 'opacity 0.5s, transform 0.5s';
element.style.opacity = '1';

// Using Web Animations API
element.animate([
    { opacity: 0, transform: 'translateY(20px)' },
    { opacity: 1, transform: 'translateY(0)' }
], {
    duration: 500,
    easing: 'ease-out',
    fill: 'forwards'
});

Gradual Transition Strategy

If you're working on a large project that uses jQuery, you can gradually transition to modern JavaScript:

  1. Use jQuery and vanilla JS side by side:
    // Existing jQuery code
    $('.existing-feature').on('click', handleExistingFeature);
    
    // New feature using vanilla JS
    document.querySelector('.new-feature').addEventListener('click', handleNewFeature);
  2. Refactor one component at a time:
    • Start with smaller, self-contained components
    • Write tests before refactoring if possible
    • Update one feature at a time
  3. Replace jQuery plugins with modern alternatives:
    • jQuery UI → Modern CSS and vanilla JS
    • jQuery validation → HTML5 validation + custom validation
    • jQuery animation → CSS animations or Web Animations API
  4. Consider modern build tools and frameworks:
    • For larger applications, consider transitioning to a framework like React, Vue, or Angular
    • Use bundlers like Webpack or Vite to manage dependencies
    • Implement modern JS practices: modules, arrow functions, async/await

Further Learning Resources

Homework Assignment

Primary Task: Refactor Your JavaScript Code Using jQuery

For this assignment, you will refactor the JavaScript code in your profile page to use jQuery:

Requirements:

  1. Add jQuery to your project (via CDN or local file)
  2. Refactor the following areas of your JavaScript code:
    • DOM selection and manipulation
    • Event handling
    • CSS/class manipulation
    • Animations and effects (if applicable)
    • Form validation (if applicable)
  3. Ensure your refactored code maintains the same functionality as the original
  4. Organize your code using jQuery's document ready function
  5. Use jQuery's chainable methods where appropriate
  6. Add appropriate comments explaining the refactoring

Additional Requirements:

  • Add at least one new feature using a jQuery plugin (optional but recommended)
  • Follow jQuery best practices (caching objects, using event delegation, etc.)
  • Test your refactored code thoroughly in different browsers
  • Document your refactoring process and the benefits it provided

Submission Guidelines

  • Submit both your original JavaScript files and the refactored jQuery versions
  • Include a README.md file that explains:
    • What parts of your code you refactored
    • Any challenges you encountered
    • Benefits you observed from using jQuery
    • Any jQuery plugins you used and why
  • Submit your complete project (HTML, CSS, JS, and jQuery files)

Grading Criteria

  • Proper jQuery Implementation (40%): Correct use of jQuery methods and selectors
  • Code Quality (25%): Clean, well-organized, and well-commented code following best practices
  • Functionality (20%): Refactored code works the same as (or better than) the original
  • Documentation (10%): Clear explanation of refactoring process and decisions
  • Creativity and Extra Features (5%): Creative use of jQuery or plugins for additional features

Bonus Challenges (Optional)

  • Advanced Plugin Integration: Add a more complex jQuery plugin (e.g., Isotope, FullCalendar)
  • Custom jQuery Plugin: Create your own simple jQuery plugin for a specific feature
  • AJAX Implementation: Add AJAX functionality to a form or content area
  • Hybrid Approach: Demonstrate a clean integration of jQuery and modern vanilla JavaScript
  • Performance Optimization: Analyze and optimize your jQuery code for performance