Preface
Goal: Switching to jQuery or Cash, for cleaner javascript.
The Javascript Evolution
Before jQuery
, there is mootools
that has more capability,
but jQuery
become more popular then mootools
.
Both have been a great thing in the past,
until come modern web framework,
such as Angular
, Vue
, React
and Svelte
,
then jQuery
become obsolete.
This article just a historical overview at a glance,
how jQuery
solve plain javascript
issue.
You should know how jQuery
works,
but do not invest too much time on jQuery
.
There is however this inscredibly small Cash
library,
but beware of its limitation.
Examples
For tutorial purpose we need two jQuery
layouts:
-
Simple layout, to explain
jQuery
. -
Enhanced layout, as real live
jQuery
example.
And then we continue with brief example of Cash
-
Simple layout.
-
Enhanced layout.
Simple jQuery Tabs : Structure
Document: HTML Head
We can reuse previous tailwind
stylesheet.
<title>Simple Tabs - jQuery</title>
<link rel="stylesheet" type="text/css"
href="../css/03-tailwind-simple.css">
<script src="../js/vendors/jquery.min.js"></script>
<script src="../js/custom/jquery-simple.js"></script>
Document: HTML Body: Tab Headers
The same as unobtrusive plain javascript.
Document: HTML Body: Tab Content
The same as unobtrusive plain javascript.
Simple Tabs: Javascript
The code logic is exactly the same with plain javascript, but with different syntax.
Javascript: DOM Event
This simply by wrapping the codes,
inside an event called $(document).ready()
.
$(document).ready(function() {
// code here …
});
Javascript: Getting Element from Event
The jQuery
has $(this)
.
we can use it as below:
tabHeaders.on('click', 'div', function (event) {
const targetName = $(this)[0].dataset.target;
const colorClass = $(this)[0].dataset.color;
// ..
});
Javascript: Initialization
Trigger Default Tab
Selecting default tab can be done by trigger the click event
with element containing active
class.
$(document).ready(function() {
const tabHeaders = $('.tab-headers').first();
// .. code here
// Tab Headers: Trigger Default
$('.tab-headers .active').first().click();
});
Javascript: Handling Headers Event
Method Chaining
The capability to chain series of command is the most powerfull feature in jQuery
era.
// Set all to default setting
tabHeaders.children('div').each(function(i, el) {
$(this)
.removeClass('active')
.removeClass(el.dataset.color)
.addClass('bg-gray-700');
});
// Except the chosen one
$(this)
.addClass('active')
.removeClass('bg-gray-700')
.addClass(colorClass);
This is basically the same as:
// Set all to default setting
tabHeaders.children('div').each(function(i, el) {
$(this).removeClass('active')
$(this).removeClass(el.dataset.color)
$(this).addClass('bg-gray-700');
});
// Except the chosen one
$(this).addClass('active')
$(this).removeClass('bg-gray-700')
$(this).addClass(colorClass);
Now you can see how jQuery
,
solve the code length of plain javascript.
Javascript: Managing Contents
By selecting the id
of the content,
we can toggle the visibility.
const tabContents = $('.tab-contents').first();
// Showing the content
tabContents.children('div').each(function() {
$(this).hide();
});
$('#'+targetName)
.show()
.addClass(colorClass);
Javascript: Complete
As a summary, the complete javascript is here below:
$(document).ready(function() {
const tabHeaders = $('.tab-headers').first();
const tabContents = $('.tab-contents').first();
// Tab Headers: All Click Events
tabHeaders.on('click', 'div', function (event) {
const targetName = $(this)[0].dataset.target;
const colorClass = $(this)[0].dataset.color;
// Set all to default setting
tabHeaders.children('div').each(function(i, el) {
$(this)
.removeClass('active')
.removeClass(el.dataset.color)
.addClass('bg-gray-700');
});
// Except the chosen one
$(this)
.addClass('active')
.removeClass('bg-gray-700')
.addClass(colorClass);
// Showing the content
tabContents.children('div').each(function() {
$(this).hide();
});
$('#'+targetName)
.show()
.addClass(colorClass);
});
// Tab Headers: Trigger Default
$('.tab-headers .active').first().click();
});
Preview
It is the same as previous plain javascript.
Each time you click the left tab, the color on the right will be changed.
Enhanced jQuery Tabs: Structure
How about real live component?
Document: HTML Head
We can add the javascript at the beginning. We still can reuse previous stylesheet.
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tabs - jQuery</title>
<link rel="stylesheet" type="text/css" href="../css/04-tailwind-enhanced.css">
<link rel="stylesheet" type="text/css" href="../css/02-border-radius.css">
<script src="../js/vendors/jquery.min.js"></script>
<script src="../js/custom/jquery-enhanced.js"></script>
Document: HTML Body: Tab Headers
We have the third level div
.
The html
is the same as unobtrusive plain javascript.
With additional tab-spacer
.
Document: HTML Body: Tab Content
We also have the third level div
here.
The html
is the same as unobtrusive plain javascript.
Enhanced Tabs: Javascript
This is also an enhancement of the previous script. With some additional event, to mimic the mouse hover.
Javascript: Managing Headers
Managing third level div
can be done adding bg-white
class.
// Set all to default setting
tabHeaders.children('div').each(function(i, el) {
// …
$(this).children(":first").removeClass('bg-white');
});
// Except the chosen one
// …
$(this).children(":first").addClass('bg-white');
Javascript: Managing Contents
It is exactly the same with the simple tabs layout. No code is changed here.
Preview
Javascript: Mimic Hover
We can utilize this event:
-
onmouseenter
: add classis-hovered
, and -
onmouseleave
: remove classis-hovered
.
Both can be implemented as below:
// Tab Headers: All Click Events
tabHeaders.on('mouseenter', 'div', function (event) {
const targetName = $(this)[0].dataset.target;
$('#'+targetName).children(":first").addClass('is-hovered');
});
// Tab Headers: All Click Events
tabHeaders.on('mouseleave', 'div', function (event) {
const targetName = $(this)[0].dataset.target;
$('#'+targetName).children(":first").removeClass('is-hovered');
});
While the tailwind
stylesheet has been previously written as:
.tab-headers div.active div:hover { @apply bg-gray-300; }
.tab-contents div div.is-hovered { @apply bg-gray-300; }
Preview
Now whenever the mouse hovering the active
tabs,
we can see something as below:
Javascript: Complete Code
As a summary, the complete code presented as below:
$(document).ready(function() {
const tabHeaders = $('.tab-headers').first();
const tabContents = $('.tab-contents').first();
// Tab Headers: All Click Events
tabHeaders.on('click', 'div', function (event) {
const targetName = $(this)[0].dataset.target;
const colorClass = $(this)[0].dataset.color;
// Set all to default setting
tabHeaders.children('div').each(function(i, el) {
$(this)
.removeClass('active')
.removeClass(el.dataset.color)
.addClass('bg-gray-700')
.children(":first").removeClass('bg-white');
});
// Except the chosen one
$(this)
.addClass('active')
.removeClass('bg-gray-700')
.addClass(colorClass)
.children(":first").addClass('bg-white');
// Showing the content
tabContents.children('div').each(function() {
$(this).hide();
});
$('#'+targetName)
.show()
.addClass(colorClass);
});
// Tab Headers: All Click Events
tabHeaders.on('mouseenter', 'div', function (event) {
const targetName = $(this)[0].dataset.target;
$('#'+targetName).children(":first").addClass('is-hovered');
});
// Tab Headers: All Click Events
tabHeaders.on('mouseleave', 'div', function (event) {
const targetName = $(this)[0].dataset.target;
$('#'+targetName).children(":first").removeClass('is-hovered');
});
// Tab Headers: Trigger Default
$('.tab-headers .active').first().click();
});
Simple Cash Tabs : Javascript
There are, trade offs.
With the same HTML
structure,
we can achieve similar things with Cash
.
But beware that not all Query
feature is,
available in Cash
library.
Sometimes we have to mix with plain javascript. And we should also be more creative with the DOM.
$(document).ready(function() {
// Tab Headers: All Click Events
$('.tab-headers > div').on('click', function (event) {
const targetName = $(this)[0].dataset.target;
const colorClass = $(this)[0].dataset.color;
// Set all to default setting
$('.tab-headers > div').each(function(el, i) {
$(this)
.removeClass('active')
.removeClass(el.dataset.color)
.addClass('bg-gray-700');
});
// Except the chosen one
$(this)
.addClass('active')
.removeClass('bg-gray-700')
.addClass(colorClass);
// Showing the content
$('.tab-contents > div').each(function(el, i) {
el.style.display = 'none';
});
sel = $('#'+targetName);
sel[0].style.display = 'block';
sel.addClass(colorClass);
});
// Tab Headers: Trigger Default
const tabHeaders = $('.tab-headers').first();
$('.active', tabHeaders)[0].click();
});
This works for small projects.
Enhanced Cash Tabs : Javascript
The same applied with enhanced tabs.
$(document).ready(function() {
//const tabContents = $('.tab-contents').first();
// Tab Headers: All Click Events
$('.tab-headers > div').on('click', function (event) {
const targetName = $(this)[0].dataset.target;
const colorClass = $(this)[0].dataset.color;
// Set all to default setting
$('.tab-headers > div').each(function(el, i) {
$(this)
.removeClass('active')
.removeClass(el.dataset.color)
.addClass('bg-gray-700')
$(el.firstElementChild).removeClass('bg-white');
});
// Except the chosen one
$(this)
.addClass('active')
.removeClass('bg-gray-700')
.addClass(colorClass)
$($(this)[0].firstElementChild).addClass('bg-white');
// Showing the content
$('.tab-contents > div').each(function(el, i) {
el.style.display = 'none';
});
sel = $('#'+targetName);
sel[0].style.display = 'block';
sel.addClass(colorClass);
});
// Tab Headers: All Click Events
$('.tab-headers > div').on('mouseenter', function (event) {
const targetName = $(this)[0].dataset.target;
$($('#'+targetName)[0].firstElementChild).addClass('is-hovered');
});
// Tab Headers: All Click Events
$('.tab-headers > div').on('mouseleave', function (event) {
const targetName = $(this)[0].dataset.target;
$($('#'+targetName)[0].firstElementChild).removeClass('is-hovered');
});
// Tab Headers: Trigger Default
const tabHeaders = $('.tab-headers').first();
$('.active', tabHeaders)[0].click();
});
Some of this Cash
trick, can also be applied to jQuery
.
There are many ways to do stuff, with jQuery
.
After all, it is all about creativity.
Conclusion
The issue with this good jQuery
era is we have to code the logic. Instead of writing program, we can just declare what-to-do in configuration fashioned. This simplicity is an achievement of the modern web framework. We are going to start with Alpine.js
.
What’s Next?
Consider continue reading [ Tabs - JS - Alpine.js (inline) ].