Skip to content

Cutting down jQuery trees

kdaisho edited this page Dec 30, 2017 · 9 revisions

Overall

Hi, I've been working on removing jQuery out of my sites and I guess the work is done at this point. Thinking I should keep notes for future me because I know I will forget the details. One of the reason I want to replace jQuery with vanilla is JavaScript is now good enough to be used everywhere without fallbacks since notorious downloaders called IE keeps unselected by all internet users across countries. Good good.

Here's outcome. Take a look at the two files to compare, one is written using jQuery and the other is written only in vanilla JavaScript.

File Size

  • jQuery: 5.0KB
  • Vanilla: 5.6KB

Vanilla gets larger file size as I had to write more but it's not really a lot.

Saved 93KB as a whole

My portfolio site used to be using jQuery1.11.3 from CDN and it's files size was, even it's minified, 93.71KB*. This is huge as a single JS file for a website like mine which has minimal interactions. Now my JS files are jQuery free so I can remove the hyperlink safely. Bye bye jQuery.

*mathiasbynens.be

jQuery

$(document).ready(function() {

    $(window).on("load resize scroll", function(e) { // bind windows load, resize and scroll together
        var $window = $(window);
        var windowsize = $window.width();
        var scrl_amount = $(window).scrollTop();

        if(windowsize < 768 ) { // contract header when screen is mobile
            $('#site_logo').addClass('mini-logo');
            $('#alt_logo').addClass('mini-alt-logo');
        }
        else if(windowsize > 767 ) { // expand header when screen is desktop
            $('#site_logo').removeClass('mini-logo');
            $('#alt_logo').removeClass('mini-alt-logo');
        }

        if((scrl_amount > 199) || (windowsize < 768)) { // contract header when scroll 
            $('#site_logo').addClass('mini-logo');
            $('#alt_logo').addClass('mini-alt-logo');
        }
        else if((scrl_amount < 200) && (windowsize > 767)) {
            $('#site_logo').removeClass('mini-logo');
            $('#alt_logo').removeClass('mini-alt-logo');
        }

    });


    $('#main-menu').click(function() { // open nav menu
        $('.nav').addClass('show-menu');
    });

    $('.close-nav').click(function() {
        $('.nav').removeClass('show-menu');
    });

    /* ==== MY WORK section ==== */
    $('.wrap-thumb').click(function() {
        var pos = $(this).data('pos');
        $('#img_holder').html('<img src="images/'+ bigsrc[pos].url +'" data-id="'+ bigsrc[pos].id +'">');
        $('#desc_holder').html('<h4>' + bigsrc[pos].title + '</h4><p>' + bigsrc[pos].desc
            + '</p>');
        $('#img_holder, #desc_holder, #modal_bg, #close_btn, #prev, #next').fadeIn();

        if(pos == 18 || pos == 12 || pos == 8) {
            $('#desc_holder').append('<a href="' + bigsrc[pos].link + '" target="_blank">visit website</a>');
        }
        if(pos == (bigsrc.length-1)) {
            $('#next').data('pos',(pos-1));
            $('#prev').data('pos',0);
        }
        else if(pos == 0) {
            $('#next').data('pos',(bigsrc.length-1));
            $('#prev').data('pos',(pos+1));
        }
        else {
            $('#next').data('pos',(pos-1));
            $('#prev').data('pos',(pos+1));
        }
    });

    $('.arrow').click(function() {
        var pos = $(this).data("pos");
        $('#img_holder').html('<img src="images/'+ bigsrc[pos].url +'" data-id="'+ bigsrc[pos].id +'">');
        $('#desc_holder').html('<h4>' + bigsrc[pos].title + '</h4><p>' + bigsrc[pos].desc
            + '</p>');
        $('#img_holder, #desc_holder, #modal_bg, #close_btn, #prev, #next').fadeIn();

        if(pos == 18 || pos == 12 || pos == 8) {
            $('#desc_holder').append('<a href="' + bigsrc[pos].link + '" target="_blank">visit website</a>');
        }
        if(pos == (bigsrc.length-1)) {
            $('#next').data('pos',(pos-1));
            $('#prev').data('pos',0);
        } else if(pos == 0) {
            $('#next').data('pos',(bigsrc.length-1));
            $('#prev').data('pos',(pos+1));
        } else {
            $('#next').data('pos',(pos-1));
            $('#prev').data('pos',(pos+1));
        }
    });

    $('#modal_bg, #close_btn').click(function() {
        $('#img_holder, #desc_holder, #close_btn, #modal_bg, #prev, #next').fadeOut();
    });

    $('.link').click(function(e) {
        e.preventDefault(); // disable the hyperlink
        var href = $(this).attr('href');
        href = href.replace('#','');
        var togo = $('a[class="' + href + '"]');
        $('html,body').animate({
            scrollTop:togo.offset().top
        },300)
    });

    /* ==== form validation ==== */
    $('#submit').click(function() {
        var error = false;
        var user = $('#user').val();
        var email = $('#email').val();
        var message = $('#message').val();

        if(user.length < 2) {
            $('#user').val('','');
            $('#user').attr('placeholder','please enter a valid name');
            error = true;
        };

        function validateEmail(em) {
            var filter = /^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]/; // allows any email without extension (e.g. .ca)
            if(filter.test(email)) {
                return true;
            }
            else {
                return false;
            }
        }

        if(validateEmail(email) == false) {
            $('#email').val('','');
            $('#email').attr('placeholder','please enter a valid email');
            error = true;
        };

        if(error == false) {
            $('#user').css('border','none');
            $('#user').attr('placeholder','');
            $('#email').css('border','none');
            $('#email').attr('placeholder','');
        };

        /* === send to php === */
        if(error == false) {
            $.ajax({
                url:'igetEmail.php',
                type:'POST',
                data:{
                    Name:user,
                    email:email,
                    question:message
                },
                success:function(response){
                    $('#form').html(response);
                }
            });
        }
    });
});

Vanilla

"use strict";

document.addEventListener("DOMContentLoaded", function() {

	var windowsize,
	scrl_amount,
	site_logo,
	alt_logo,
	main_menu = document.getElementById("main-menu"),
	nav = document.getElementById("nav"),
	close_nav = document.getElementById("close-nav");


	//* Add the same listener for multiple different events on the same element
	//* Trying to make the same function as element.on("load, resize, scroll", function(){...}); in jQuery
	function addListenerMulti(el, s, fn) {
		var events = s.split(" ");
		for (var i = 0, len = events.length; i < len; i++) {
			el.addEventListener(events[i], fn, false);
		}
	}

	addListenerMulti(window, "load resize scroll", function() {
		windowsize = window.innerWidth;
		scrl_amount = window.pageYOffset;
		site_logo = document.getElementById("site_logo");
		alt_logo = document.getElementById("alt_logo");

		if (site_logo && alt_logo && windowsize && scrl_amount) {
			if (scrl_amount >= 199 || windowsize <= 767) {
				site_logo.className = "site-logo logo-display mini-logo";
				alt_logo.className = "site-logo logo-hide mini-alt-logo";
			}
			else {
				site_logo.className = "site-logo logo-display";
				alt_logo.className = "site-logo logo-hide";
			}
		}
	});

	main_menu.addEventListener("click", function() {
		nav.style.right = 0;
	});

	close_nav.addEventListener("click", function() {
		nav.style.right = "-320px";
	});

	/* ==== MY WORK section ==== */
	var thumbs_parent = document.getElementById("wrap-thumbs"),
	gal_holder = document.getElementById("gal_holder"),
	img_holder = document.getElementById("img_holder"),
	desc_holder = document.getElementById("desc_holder"),
	modal_bg = document.getElementById("modal_bg"),
	close_btn = document.getElementById("close_btn"),
	prev = document.getElementById("prev"),
	next = document.getElementById("next");


	thumbs_parent.addEventListener("click", displayBox, false);

	next.addEventListener("click", function() {
		var pos = document.getElementById("data_img").getAttribute("data-id");
		nextBox(pos);
	}, false);

	prev.addEventListener("click", function() {
		var pos = document.getElementById("data_img").getAttribute("data-id");
		prevBox(pos);
	}, false);

	function injectEl(pos) {
		img_holder.innerHTML = '<img id="data_img" src="images/'+ bigsrc[pos].url +'" data-id="'+ bigsrc[pos].id +'">';
		desc_holder.innerHTML = '<h4>' + bigsrc[pos].title + '</h4><p>' + bigsrc[pos].desc + '</p>';

		if (pos == 18 || pos == 12 || pos == 8) {
			var anchor = document.createElement("a");
			anchor.href = bigsrc[pos].link;
			anchor.setAttribute("target", "_blank");
			anchor.innerHTML = "visit website";
			desc_holder.appendChild(anchor);
		}
	}

	function displayBox(event) {
		//Prevent the parent element being clickable
		if (event.target !== event.currentTarget) {
			var pos = event.target.getAttribute("data-pos");
			injectEl(pos);

			gal_holder.className = "is-active";
			modal_bg.className = "is-active";
		}
		event.stopPropagation();
	}

	function nextBox(pos) {
		if (pos == 0) {
			pos = bigsrc.length - 1;
		}
		else {
			pos--;
		}
		injectEl(pos);
	}

	function prevBox(pos) {
		if (pos == bigsrc.length - 1) {
			pos = 0;
		}
		else {
			pos++;
		}
		injectEl(pos);
	}

	/* --- IIFE to avoid polluting global namespace --- */
	(function closeModal() {
		var arr = [modal_bg, close_btn];
		for (var i = 0, len = arr.length; i < len; i++) {
			arr[i].addEventListener("click", function() {
				gal_holder.className = "";
				modal_bg.className = "";
			//location.hash = "#" + "goto-about";
			}, false);
		}
	}());

	//Get nav-buttons and destination anchor elements then convert them into an array
	var links = document.getElementsByClassName("link"),
	dest_links = document.getElementsByClassName("dest-link");
	links = [].slice.call(links);
	dest_links = [].slice.call(dest_links);

	function clickListener(link, i) {
		link.addEventListener("click", function() {
			dest_links[i].scrollIntoView({behavior: "smooth"});
		}, false);
	}

	for (var i = 0, len = links.length; i < len; i++) {
		clickListener(links[i], i);
	}

	/* ==== form validation ==== */
	document.getElementById("submit").addEventListener("click", function() {
		var error = false,
			user = document.getElementById("user"),
			userValue = document.getElementById("user").value,
			email = document.getElementById("email"),
			emailValue = document.getElementById("email").value,
			email = document.getElementById("message"),
			msgValue = document.getElementById("message").value;

		if (userValue.length < 2) {
			user.value = "";
			user.setAttribute("placeholder", "please enter a valid name");
			error = true;
		};

		function validateEmail (em) {
			var filter = /^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]/; // allows any email without extension (e.g. .ca)
			if(filter.test(em)) {
				return true;
			}
			else {
				return false;
			}
		}

		if (validateEmail(emailValue) == false) {
			email.setAttribute("placeholder", "please enter a valid email");
			error = true;
		}

		if (error == false) {
			user.style.border = "none";
			user.setAttribute("placeholder", "");
			email.style.border = "none";
			email.setAttribute("placeholder", "");
		}

		/* === send to php === */
		if(!error) {
			var myUser = {
				Name: userValue,
				email: emailValue,
				question: msgValue
			};

			var str_json = JSON.stringify(myUser);

			var request = new XMLHttpRequest();
			request.open("POST", "igetEmail.php", true);
			request.setRequestHeader("Content-type", "application/json");
			request.send(str_json);

			request.onload = function() {
				if (request.readyState != 4 || request.status != 200) {
					return;
				}
				else {
					document.getElementById("form").innerHTML = request.responseText;
				}
			};
		}
	});
});
Clone this wiki locally