DEV Community

Cover image for Learning JS frameworks with me(Part 1) 😎: JQuery
Shaman Shetty
Shaman Shetty

Posted on

Learning JS frameworks with me(Part 1) 😎: JQuery

Introduction

I gotta admit. When I first started working with JavaScript, I found the native DOM API frustrating. Selecting elements felt 'त्रास'(troublesome), event handling was inconsistent across browsers, and animations required writing dozens of lines of code. Then I discovered jQuery, and it felt like someone had handed me a superpower.

"Write less, do more" wasn't just jQuery's tagline—it was a revolutionary promise that transformed how an entire generation of developers (myself included) approached frontend development. Despite being created back in 2006, jQuery's influence is so profound that its patterns are still visible in modern frameworks today.

As I continue my journey through JavaScript frameworks, I'm taking you along for the ride. Today, we're exploring jQuery—the framework that democratized dynamic web development and paved the way for everything that followed.

The Rise and Reign of jQuery

Before diving into code, let's understand why jQuery became the dominant force in frontend development for nearly a decade.

In the mid-2000s, web development was a nightmare of browser inconsistencies. I remember building my first interactive websites and maintaining separate codebases for Internet Explorer, Firefox, and the emerging Chrome browser. Each had its own quirks, bugs, and implementation differences.

jQuery emerged as a solution to a very real problem: write once, run everywhere. Its creator, John Resig, built a sleek abstraction layer that normalized browser differences behind a consistent, intuitive API.

The result? jQuery adoption exploded. At its peak, jQuery powered over 70% of the top 10 million websites on the internet. Even today, despite the rise of modern frameworks like React and Vue, jQuery remains on approximately 77% of all websites using JavaScript libraries.

Why jQuery Still Matters in 2025

You might be wondering: "With all these modern frameworks, why should I bother learning jQuery?"

Great question! Here's why I believe understanding jQuery remains valuable:

  1. Legacy Codebase Maintenance: Countless websites and applications still run on jQuery. During my first dev job, I inherited a 50,000-line jQuery codebase that powered a critical business application.

  2. Conceptual Foundation: jQuery introduced patterns that influenced React, Vue, and other modern frameworks. Understanding where these ideas originated gives you deeper insight into why modern frameworks work the way they do.

  3. Lightweight Solution: Sometimes a full framework is overkill. I still reach for jQuery when building simple websites that need a touch of interactivity without the overhead of a larger framework.

  4. WordPress Integration: If you work with WordPress (powering ~40% of the web), jQuery comes bundled with it and is deeply integrated into its ecosystem.

  5. Job Market Reality: Browse job listings and you'll still see jQuery mentioned frequently, especially for roles maintaining established systems.

Setting Up Your First jQuery Project

Let's get our hands dirty with some actual code. I'll walk you through setting up a project using the same basic structure we used in our vanilla JS exploration.

Step 1: Create Your Project Structure

jquery-project/
├── index.html
├── css/
│   └── style.css
└── js/
    └── main.js
Enter fullscreen mode Exit fullscreen mode

Step 2: Set Up Your HTML File

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery Task List</title>
    <link rel="stylesheet" href="css/style.css">
    <!-- jQuery from CDN (always place before your own scripts) -->
    <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</head>
<body>
    <header>
        <h1>My jQuery Task App</h1>
    </header>

    <main>
        <section class="todo-app">
            <h2>Task List</h2>
            <form id="task-form">
                <input type="text" id="task-input" placeholder="Add a new task..." required>
                <button type="submit">Add Task</button>
            </form>
            <ul id="task-list"></ul>
        </section>
    </main>

    <script src="js/main.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Step 3: Use The Same CSS

For this project, we'll use the exact same CSS from our vanilla JS project. If you haven't read that post yet, you might want to check it out to understand the styling we're applying to our task app.

Step 4: The jQuery Magic

Now here's where things get interesting. Remember all that vanilla JavaScript code we wrote for our task manager? Let's rewrite it using jQuery and see the difference:

// js/main.js
$(document).ready(function() {
    // Get DOM elements with jQuery
    const $taskForm = $('#task-form');
    const $taskInput = $('#task-input');
    const $taskList = $('#task-list');

    // Load tasks from localStorage
    let tasks = JSON.parse(localStorage.getItem('tasks')) || [];

    // Render initial tasks
    renderTasks();

    // Add task event
    $taskForm.on('submit', function(e) {
        e.preventDefault();

        const taskText = $taskInput.val().trim();
        if (taskText === '') return;

        // Create new task object
        const task = {
            id: Date.now(),
            text: taskText,
            completed: false
        };

        // Add to tasks array
        tasks.push(task);

        // Save to localStorage
        saveTasksToStorage();

        // Render tasks
        renderTasks();

        // Clear input
        $taskInput.val('').focus();
    });

    // Event delegation for task list (click for complete or delete)
    $taskList.on('click', '.delete-btn', function() {
        // Get task ID from parent li's data attribute
        const taskId = parseInt($(this).parent().data('id'));
        tasks = tasks.filter(task => task.id !== taskId);
        saveTasksToStorage();
        renderTasks();
    });

    $taskList.on('click', 'span', function() {
        // Get task ID from parent li's data attribute
        const taskId = parseInt($(this).parent().data('id'));
        tasks = tasks.map(task => {
            if (task.id === taskId) {
                return { ...task, completed: !task.completed };
            }
            return task;
        });
        saveTasksToStorage();
        renderTasks();
    });

    // Save tasks to localStorage
    function saveTasksToStorage() {
        localStorage.setItem('tasks', JSON.stringify(tasks));
    }

    // Render tasks to DOM with jQuery
    function renderTasks() {
        $taskList.empty();

        tasks.forEach(task => {
            // Create elements with jQuery
            const $li = $('<li>').attr('data-id', task.id);
            const $span = $('<span>').text(task.text);
            const $deleteBtn = $('<button>').text('Delete').addClass('delete-btn');

            if (task.completed) {
                $span.addClass('completed');
            }

            // Append elements to list item using jQuery chaining
            $li.append($span).append($deleteBtn);

            // Add with animation
            $li.hide().appendTo($taskList).fadeIn(300);
        });
    }
});
Enter fullscreen mode Exit fullscreen mode

Take a moment and compare this to the vanilla JavaScript version (refer to my vanilla JS blog post for the original code). Notice the differences?

The jQuery Difference: Less Code, Same Functionality

If you're looking at both versions side by side, you'll immediately notice how much cleaner the jQuery code looks. Let's break down the key differences:

1. Selecting Elements

Vanilla JS:

const taskForm = document.getElementById('task-form');
const taskInput = document.getElementById('task-input');
const taskList = document.getElementById('task-list');
Enter fullscreen mode Exit fullscreen mode

jQuery:

const $taskForm = $('#task-form');
const $taskInput = $('#task-input');
const $taskList = $('#task-list');
Enter fullscreen mode Exit fullscreen mode

This might seem like a small difference, but jQuery's selector engine was revolutionary for its time. It used CSS-style selectors years before document.querySelector() became available, and it normalized behavior across browsers.

Note: The $ prefix on variable names isn't required, but it's a common convention to indicate a jQuery object. I picked up this habit early and it's saved me countless debugging hours.

2. Event Handling

Vanilla JS:

taskForm.addEventListener('submit', (e) => {
    e.preventDefault();
    // Rest of the code...
});
Enter fullscreen mode Exit fullscreen mode

jQuery:

$taskForm.on('submit', function(e) {
    e.preventDefault();
    // Rest of the code...
});
Enter fullscreen mode Exit fullscreen mode

jQuery's .on() method unified the inconsistent event APIs across browsers. Remember when IE used attachEvent while other browsers used addEventListener? jQuery saved us from those headaches.

3. DOM Manipulation

Vanilla JS:

const li = document.createElement('li');
li.setAttribute('data-id', task.id);

const span = document.createElement('span');
span.textContent = task.text;
// ...and so on
Enter fullscreen mode Exit fullscreen mode

jQuery:

const $li = $('<li>').attr('data-id', task.id);
const $span = $('<span>').text(task.text);
// Much cleaner!
Enter fullscreen mode Exit fullscreen mode

This is where jQuery truly shines. Creating and manipulating DOM elements is drastically simplified, and we can chain methods together for even more concise code.

4. Animation

The vanilla JS version had no animations. Adding them would require dozens of lines of code for smooth transitions. With jQuery, we can add animations with a single method call:

$li.hide().appendTo($taskList).fadeIn(300);
Enter fullscreen mode Exit fullscreen mode

This line:

  1. Creates a hidden list item
  2. Appends it to the task list
  3. Fades it in over 300 milliseconds

Achieving this effect in vanilla JS would require setting up CSS transitions or keyframes, adding classes at precise times, and handling animation completion events.

The jQuery Essentials: What Makes It Different?

Now that we've seen the practical differences, let's explore the key concepts that made jQuery revolutionary:

1. The Dollar Sign ($) Function

The most recognizable part of jQuery is the $ function (also available as jQuery). This versatile function serves as:

  • A selector engine (similar to document.querySelector)
  • A DOM ready handler (when passed a function)
  • A DOM element creator (when passed HTML)
// As a selector
$(".my-class"); // Select all elements with class "my-class"

// As a DOM ready handler
$(function() { /* code runs when DOM is ready */ });

// As an element creator
$("<div>New content</div>"); // Create a new div element
Enter fullscreen mode Exit fullscreen mode

This unified API made jQuery incredibly intuitive. I remember the first time I used it—everything just felt like it worked the way it should.

2. Chaining Methods

One of jQuery's most powerful patterns is method chaining. Each method returns the jQuery object, allowing you to chain multiple operations:

$("#element")
    .addClass("highlight")
    .text("New content")
    .fadeIn(400)
    .delay(2000)
    .fadeOut(400);
Enter fullscreen mode Exit fullscreen mode

In vanilla JS, this would require separate statements for each operation. The chaining pattern is so elegant that it influenced countless libraries and frameworks that followed.

3. Implicit Iteration

jQuery automatically iterates over collections, applying operations to each element:

// Changes all paragraphs without an explicit loop
$("p").addClass("highlighted");
Enter fullscreen mode Exit fullscreen mode

This seemingly small feature saved developers from writing countless for loops.

jQuery Techniques That Changed How We Write JavaScript

Let's explore some techniques that showcase jQuery's strengths:

1. Event Delegation

jQuery made event delegation easy, allowing you to handle events for elements that don't even exist yet:

// Our task app uses this pattern
$taskList.on('click', '.delete-btn', function() {
    // This works even for buttons added after this code runs
    // ...
});
Enter fullscreen mode Exit fullscreen mode

This pattern was a game-changer for dynamic interfaces. Before this, you had to rebind event handlers whenever you added new elements.

2. The Improved Template Literal Approach

Remember the template literal technique from our vanilla JS blog? jQuery made this pattern even more powerful:

function renderTasksWithTemplate() {
    $taskList.html(tasks.map(task => `
        <li data-id="${task.id}">
            <span class="${task.completed ? 'completed' : ''}">${task.text}</span>
            <button class="delete-btn">Delete</button>
        </li>
    `).join(''));

    // Now we need to rebind events since we replaced the HTML
    $taskList.find('.delete-btn').on('click', function() {
        // Handle delete
    });
}
Enter fullscreen mode Exit fullscreen mode

While this approach isn't used in our main example (we used DOM methods instead), it shows how jQuery made working with HTML strings more powerful.

3. AJAX Made Simple

While not demonstrated in our task app, jQuery's AJAX capabilities were revolutionary for their time:

$.ajax({
    url: "/api/tasks",
    method: "GET",
    dataType: "json"
}).done(function(data) {
    tasks = data;
    renderTasks();
}).fail(function(xhr, status, error) {
    console.error("Error loading tasks:", error);
});

// Or with the simpler shorthand
$.getJSON("/api/tasks", function(data) {
    tasks = data;
    renderTasks();
});
Enter fullscreen mode Exit fullscreen mode

Before jQuery, making AJAX requests required working with the clunky XMLHttpRequest object directly and handling browser inconsistencies yourself.

Enhancing Our Task App with jQuery-Specific Features

Let's add some jQuery-specific enhancements to our task app that would be more difficult in vanilla JS:

// Add these to the existing code

// Add sortable functionality
function makeSortable() {
    // This would actually require jQuery UI in a real app,
    // but here's a simplified concept:
    let draggedItem = null;

    $taskList.on('mousedown', 'li', function() {
        $(this).addClass('dragging');
        draggedItem = $(this);
    });

    $taskList.on('mouseup', function() {
        $('.dragging').removeClass('dragging');
    });
}

// Add a task filter
function addTaskFilter() {
    // Add filter UI
    const $filterUI = $(`
        <div class="filter-controls">
            <button class="filter-btn active" data-filter="all">All</button>
            <button class="filter-btn" data-filter="active">Active</button>
            <button class="filter-btn" data-filter="completed">Completed</button>
        </div>
    `);

    $filterUI.insertBefore($taskList);

    // Filter functionality
    $('.filter-controls').on('click', '.filter-btn', function() {
        const filter = $(this).data('filter');

        // Update active button
        $('.filter-btn').removeClass('active');
        $(this).addClass('active');

        // Filter tasks
        if (filter === 'all') {
            $taskList.find('li').show();
        } else if (filter === 'active') {
            $taskList.find('li').show();
            $taskList.find('li:has(span.completed)').hide();
        } else if (filter === 'completed') {
            $taskList.find('li').hide();
            $taskList.find('li:has(span.completed)').show();
        }
    });
}

// Call these functions
addTaskFilter();
makeSortable();
Enter fullscreen mode Exit fullscreen mode

These enhancements leverage jQuery's powerful DOM manipulation and event handling capabilities to add features that would require significantly more code in vanilla JS.

When to Use jQuery in 2025 (And When Not To)

After working with both jQuery and modern frameworks, here's my practical advice on when jQuery still makes sense today:

Use jQuery When:

  • You're maintaining legacy applications built with jQuery
  • Building simple websites that need light interactivity
  • Prototyping quickly without complex state management
  • Working within the WordPress ecosystem
  • You need broad browser support with minimal effort
  • Creating simple plugins or widgets for non-technical users

Consider Alternatives When:

  • Building complex, state-driven single-page applications
  • You need a component-based architecture
  • Performance is critical (especially on mobile)
  • You have complex data management requirements
  • You're building a new, large-scale application
  • Your team is already proficient with modern frameworks

From jQuery to Modern Frameworks: The Evolution

What fascinates me most about jQuery is how it influenced the frameworks that followed. Many patterns we use in React, Vue, and other modern frameworks evolved from jQuery concepts:

  1. Selection → Components: jQuery's selectors evolved into component-based architecture
  2. Manipulation → Virtual DOM: Direct DOM manipulation evolved into Virtual DOM diffing
  3. $.ajax → fetch/axios: jQuery's AJAX simplifications evolved into Promise-based APIs
  4. Plugins → NPM packages: The plugin ecosystem evolved into npm packages

When I started learning React after years of jQuery, the transition felt natural because I could see the conceptual lineage.

The jQuery Ecosystem: Plugins That Extended Its Power

One of jQuery's greatest strengths was its plugin ecosystem. With a simple pattern, developers could extend jQuery's functionality:

// Custom plugin for task completion animations
$.fn.completeTask = function() {
    return this.each(function() {
        $(this)
            .addClass('completed')
            .css({ backgroundColor: '#e9f7ef' })
            .animate({ backgroundColor: 'transparent' }, 800);
    });
};

// Usage
$taskSpan.completeTask();
Enter fullscreen mode Exit fullscreen mode

This extensibility led to thousands of plugins for everything from form validation to complex data grids and image carousels.

Conclusion: jQuery's Enduring Legacy

Working with jQuery feels like visiting an old friend. It may not be as cutting-edge as it once was, but it taught an entire generation of developers (myself included) how to think about web interactivity and DOM manipulation.

The concepts jQuery pioneered—chainable methods, implicit iteration, DOM abstraction, event delegation—are now fundamental patterns in modern web development. Even if you never write a line of jQuery in your career, understanding its approach and philosophy will make you a better developer.

As we continue our journey through JavaScript frameworks, remember that jQuery wasn't just a library—it was a revolution that made dynamic web development accessible to millions of developers worldwide.

In my next post, I'll be exploring React and how it builds upon many of the concepts we've discussed here while taking a completely different approach to building web interfaces. Stay tuned!

What's your experience with jQuery? Did you use it in your early development journey, or are you learning it for the first time? I'd love to hear about your experiences in the comments!

Happy coding!

Top comments (0)