JavaScript – Sorin Coza http://localhost/sorincoza.com/blog-wp Just another web blog. Tue, 30 Aug 2016 10:46:43 +0000 en-US hourly 1 https://wordpress.org/?v=4.4.4 Create a “long-press” click event http://localhost/sorincoza.com/blog-wp/create-a-long-press-click-event/ Sun, 20 Mar 2016 15:54:29 +0000 http://localhost/sorincoza.com/blog-wp/?p=90 I needed an event for a “long press” with the mouse, or a “long touch” event on the mobile devices. This one does the following:

  • depends on jQuery
  • prevents the “click” event from firing, in case the “longpress” event occurs
  • “longpress” does not fire if the mouse leaves the element during pressing
  • the following examples attaches to all elements specified by the selector
(function( selector ){
	var $ = ( typeof jQuery !== 'undefined' )  ?  jQuery  :  false;
	if( !$ ) return;


	var isLongClick = false,
		isMouseIn = false,
		pressTimer,
		pressDelay = 1000; // ms

	$(selector)
		.on( 'mousedown touchstart', function(e){
			var $this = $(this);

			pressTimer = window.setTimeout(function() {
				if( typeof e.button !== 'undefined'  &&  e.button !== 0 ) return;  // prevent trigger on right-click
				if( isMouseIn ){  
					isLongClick = true;
					$this.trigger( 'longpress' );
					e.preventDefault();
					e.stopPropagation();
					e.stopImmediatePropagation();
				}
			}, pressDelay);

		} )
		.on( 'mouseup touchend', function(e){
			clearTimeout(pressTimer);
		} )
		.on( 'click', function(e){
			if( isLongClick ){
				isLongClick = false; // reset this flag (it has done its part)
				e.preventDefault();
				e.stopPropagation();
    			e.stopImmediatePropagation();
    			return false;
			}
		} )
		.on( 'mouseover touchstart', function(e){
			isMouseIn = true;
		} )
		.on( 'mouseout touchleave touchcancel', function(e){
			isMouseIn = false;
		} )
	;
})( '.btn' );
]]>
Do you really need jQuery? http://localhost/sorincoza.com/blog-wp/do-you-really-need-jquery/ Sat, 12 Sep 2015 16:49:46 +0000 http://sorincoza.com/blog/?p=5 jQuery has become so popular that it is often confused with JavaScript itself. Many times when searching for a JavaScript answer on the internet, you bump into a jQuery solution, which fails to mention that it is jQuery. It is just assumed that everyone in the Universe is using jQuery!

So there is no wonder that so many sites use it. But the problem is when it is used for just a couple of simple operations (like hiding an element, or changing some of its style). The whole thing may go down something like this: the developer (or site owner) needs to toggle the visibility of an element. He/she searches online for an answer. The answer appears to be simple:

$( '#myButtonID' ).on( 'click', function(){
    $( '#myElementID' ).toggle();
});

So simple, right? It just so happens that jQuery has exactly the function that is needed. But now jQuery has to be included into the page, so this has to be included before the other script:

<script src="/path/to/jquery.min.js"></script>

And the above script has to be loaded first, and is no negligible size: the latest version is more than 80KB. But size is not the biggest issue here. The biggest issue is that it is 80KB of JavaScript code, which has to be parsed, and nothing else can execute until the jQuery file parsing is done. It is said to be a blocking resource, because it blocks everything else while it is loading.

These things add up and can noticeably increase the site loading time. This is bad, because everybody knows by now that the bounce rate of any website increases as the loading time increases. So, is it worth losing visitors just to get a HTML element to toggle? I would say no. That’s why I want to mention some ideas to these simple tasks:

1. Use document.getElementById() whenever you can

This JavaScript function is the mother of all. It is fast and works in most browsers, even ancient ones like Internet Explorer 5.5. So, instead of jQuery statement $( '#myID' ), use the pure JavaScript version of it: document.getElementById( 'myID' ). Read some documentation on Mozilla website: MDN.

2. When the above is not possible, use document.querySelector()

This is a general purpose function, that lets you select elements exactly like you do in jQuery when the selector is more complicated than just an ID. The function will return the first element that matches your selector. So, for example, something like $( '#myID .myClass' ) can be easily replaced by document.querySelector( '#myID .myClass' ).

This function works in Internet Explorer 8 and up. Documentation here.

3. Use the good old onclick, and his friends

OK, I know this should not be encouraged, since modern browsers have addEventListener() now, but that is not supported by some Internet Explorer versions, which are still in use among web-surfers. So if you don’t want (or don’t know how) to work around this issue, then the best thing is to just use onclick. It is guaranteed to work in all browsers, because even new browsers have to provide backward compatibility for this feature – they can’t just throw it away, since many websites still use it.

So, instead of writing $( element ).on( 'click', callbackFunction ), you can very safely use element.onclick = callbackFunction

Putting it all together

So now that we have replacements for jQuery functions, let’s try to “translate” the example from the beginning of the article. To do this, we have to emulate the .toggle() function. We can do it in pure JavaScript, but it is a bit more complicated than the second option – which is to use a CSS class to hide the element. Sure, this means you’ll have to write a few lines of CSS code, but the advantage is that it will be faster, and you can do more stuff with your element – like making it disappear in a cloud of smoke (which is not easy to do with jQuery!).

I always prefer the CSS way in such situations. After all, it was built to style DOM elements, whereas JavaScript and jQuery are not so efficient at this kind of tasks. So what we will do is add a class named hidden to our element whenever we want to hide it. Here it goes:

// get the element to be hidden and store it in this variable:
var myElement = document.getElementById( 'myElementID' );

document.getElementById( 'myButtonID' ).onclick = function(){
    
    // check if the element is hidden, and act accordingly:
    if ( myElement.className.indexOf( 'hidden' ) > -1 ){
        myElement.className = myElement.className.replace( ' hidden', '' );  // remove "hidden"
    }else{
        myElement.className += ' hidden';  // add "hidden"
    }
};

That wasn’t so bad, was it? And the best thing is that you can put anything you want in that hidden class!

]]>