jQuery

Get the text node of an element

var h1_text = $('h1').contents().filter(function() { return this.nodeType === Node.TEXT_NODE; }).text();
<h1>Lorem ipsum <span>dolor sit amet</span><h1>

// console.log(h1_text) -> "Lorem ipsum"

Automatically add line breaks in SVG text

Add line breaks in SVG text with jQuery, based on a separator. In the example below the separator is plain text <br>.

<div class="svg-container">
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text>
      <tspan x="0" y="0" style="font-family: Helvetica; font-size: 8px;">Lorem ipsum <br> dolor sit amet</tspan>
    </text>
  </svg>
</div>
$('.svg-container').each(function() {
  // line breaks
  $(this).find('text').each(function() {
    if (/<br>/i.test($(this).text())) {
      var tspan = $(this).find('tspan:first-child');
      var tspanX = tspan.attr('x');
      var tspanY = tspan.attr('y');
      var tspanStyle = tspan.attr('style');
      
      tspan.hide();
      
      var lines = $(this).text().split('<br>');
      var lineHeight = parseFloat(tspan.css('fontSize'));
      for (var i = 0; i < lines.length; ++i) {
        $(this).append('<tspan x="'+ tspanX +'" y="'+ (parseFloat(tspanY) + (lineHeight * i)) +'" style="'+ tspanStyle +'">'+ $.trim(lines[i]) +'</tspan>');
      }
    }
  });

  // refresh svg
  $(this).html($(this).html());
});

If in view

Check if an element is in view using only JQuery.
A sort of poor man’s Waypoints.

Demo with sections.

$(window).on('load scroll', function() {
  $('.element').each(function() {
    if ( $(this).offset().top <= ($(window).scrollTop() + $(window).height()/2)) {
     // in view (in the upper half of the screen)
    } else {
     // not in view
    }
  });
});

Using fullPage.js to make a vertical split-screen parallax

fullPage.js, as its author states, is a jQuery plugin which allows you to “create full screen pages fast and simple”.

How about using it to make a split-screen parallax fast and simple ?

First the required HTML structure:

<div id="splitscreen">
  <div class="section">
    <div class="column column-left">Left Side</div>
    <div class="column column-right">Right Side</div>
  </div>
</div>

Then init the fullPage.js, and customize the settings to your taste.

$(document).ready(function() {
  $('#splitscreen').fullpage({
    navigation: false,
    scrollingSpeed: 1000,
  });
});

Now the CSS for the split-screen:

#splitscreen > .section .column-left {
  float: left;
  width: 50%;
  color: #000;
  background: #fff;
}

#splitscreen > .section .column-right {
  float: right;
  width: 50%;
  color: #fff;
  background: #000;
}

#splitscreen > .section .column-left {
  transition: all 1s ease 0s;
  transform: translateY(100%);
  backface-visibility: hidden;
}

#splitscreen > .section .column-right {
  transition: all 1s ease 0s;
  transform: translateY(-100%);
  backface-visibility: hidden;
}

#splitscreen > .section.active {
  z-index: 1;
}

#splitscreen > .section.active .column-left {
  transform: translateY(0);
}

#splitscreen > .section.active .column-right {
  transform: translateY(0);
}

#splitscreen > .section.active~.section .column-left {
  transform: translateY(-100%);
}

#splitscreen > .section.active~.section .column-right {
  transform: translateY(100%);
}

/* prevent fullpage from "scrolling" the page */
#splitscreen {
  transform: translate3d(0px, 0px, 0px) !important;
}

#splitscreen > .section {
  position: absolute;
  top: 0;
  left: 0;
}

Split screen parallax demo.

fullPage.js – always scroll from top within sections

Scroll long sections always from top.
This works only for section without slides.
Tested with fullPage 2.8.9.

$('#fullpage').fullpage({
  scrollOverflow: true,
  onLeave: function(index, nextIndex, direction){
    $('.fp-scrollable').each(function() {
      var iScrollInstance = $(this).data('iscrollInstance');
      iScrollInstance.scrollTo(0,0, 2000);
    });
  }
});

Simple HTML5 placeholders fallback for IE9 and older

I hoped I will never hear about IE9 and its lack of support for the placeholder attribute, … I had high hopes.

I’ve boiled a simple fallback, late in the evening and in a rush, using IE conditional comments for browser detection.

<!--[if IE 8 ]>    <html class="ie8 lt-ie10"> <![endif]-->
<!--[if IE 9 ]>    <html class="ie9 lt-ie10"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html><!--<![endif]-->
$(document).ready(function() {

	// HTML5 placeholders fallback for IE9 and older
	if ($('html').hasClass('lt-ie10')) {

		// add the placeholder text as value
		$('textarea, input:text').each(function() {
			$(this).attr('value', $(this).attr('placeholder'));
		});

		// clear form fields on focus
		$('textarea, input:text').on('focus click', function(){
			if (this.value == this.defaultValue) {
			this.value = '';
			}
		}).on('blur', function(){
			if (this.value == '') {
			this.value = this.defaultValue;
			}
		});
	}

});

Random start cycle

function randomBox(randomItem) {

  randomItem = $(randomItem);

  var random = Math.floor(Math.random() * randomItem.length);

  randomItem.eq(random % randomItem.length).addClass('active');

  function startRand() {

    var current = randomItem.parent().find('.active');

    if ( current.is(':last-child') ) {
      current.removeClass('active');
      current.siblings(':first-child').addClass('active');
    } else {
      current.removeClass('active');
      current.next().addClass('active');
    }

    setTimeout(function(){startRand()}, 2500);
  }

  startRand();
}

randomBox('.list > .item');

Prevent inner elements trigger an event on the parent

Method 1
Stop propagation on inner elements before attaching an event on the parent.

$('#parent a').on('click', function(event){
  //stop the event bubbling up to the parent
  event.stopPropagation();
});

$('#parent').on('click', function(event){
  //attach event on the parent
  alert('Parent element clicked!');	
});

Method 2
Check if the event target matches the designated target.

$('#parent').on('click', function(event) {
  if(event.target == event.currentTarget) {
    alert('Parent element clicked!');
  } else {
    alert('Child element clicked!');
  }
});

Method 2.1
Check if the tag name of the event target matches a certain element.

$('#parent').on('click', function(event){
  if(event.target.tagName.toLowerCase() === 'a'){
    alert('Child anchor element clicked!');
  } else {
    alert('Parent element clicked!');
  }
});

Hide popup when clicking outside

//show popup when clicking the trigger
$('#trigger').on('click touch', function(){
  $('#tooltip').show();
});			

//hide it when clicking anywhere else except the popup and the trigger
$(document).on('click touch', function(event) {
  if (!$(event.target).parents().addBack().is('#trigger')) {
    $('#tooltip').hide();
  }
});

// Stop propagation to prevent hiding "#tooltip" when clicking on it
$('#tooltip').on('click touch', function(event) {
  event.stopPropagation();
});

Demo

Prevent bxSlider stop auto

Prevent bxSlider stop auto slides transition, when navigating through slides.

$(document).ready(function(){
	var slider = $('#slideshow').bxSlider({
		auto: true,
		stopAuto: false,
		startSlide: 0
	});
	
	$(document).on('click','.bx-pager-link',function() {
	    slider.stopAuto();
	    slider.startAuto();
	});
});

Slide out hamburger menu

It is known that the slide out menus ( or hamburger menus ) are the best way of making a menu usable for mobile.

This method uses jQuery in order to clone the markup of the desktop version menu, and make it slide out. Check out the demo.

<body>
	<div id="container">
		<div id="header">
			<div id="navigation">
				<ul>
					<li>
						<a href="#">Lorem Ipsum</a>
					</li>
					<li>
						<a href="#">Lorem Ipsum</a>
					</li>
				</ul>
			</div>
			<span id="toggle-menu">Menu</span>
		</div>
	</div>
</body>
$('#navigation').clone().prependTo('body').addClass('mobile-navigation').removeAttr('id');
$('div.mobile-navigation').prepend('<span class="close">Close</span>');

$('#toggle-menu').bind('click touch', function(){
	if( $('div.mobile-navigation').hasClass('open') ){
		$('div.mobile-navigation').animate({width: "0px"}, 300).removeClass('open');
		$('#container').animate({left: "0px"}, 300);
	} else {
		$('div.mobile-navigation').animate({width: "210px"}, 300).addClass('open');
		$('#container').animate({left: "-210px"}, 300);
	}
});

$('div.mobile-navigation span.close').bind('click touch', function(){
	$('div.mobile-navigation').animate({width: "0px"}, 300).removeClass('open');
	$('#container').animate({left: "0px"}, 300);
});
#container {
  position: relative;
  width: 100%;
}

.mobile-navigation {
  width: 0;
  height: 100%;
  overflow: hidden;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 200;
}

Check out demo.

Rudimentary text expander

There are jQuery plugins, like TextExpander, which work well with portions of text wrapped inside a single element (like a ‘<p>’ tag), but when it comes to collapse block elements, the animation is not so smooth.

Here is a very rudimentary (but working) solution for truncating sections of text paragraphs and adding a ‘read more’ button.

<div class="expandable">
    <div class="inner">
        <p>Some text ...</p>
        <p>Some text ...</p>
    </div>
</div>
.expandable .inner {
    overflow: hidden;
}
$('div.expandable > div.inner').each(function(){
	var expadable_height = $(this).height();
	var visible_lines = 42; //the height of the minimum visible lines of text in px
	$(this).css('height', visible_lines); 
	$(this).parent('div.expandable').append('<span class="see-more">See More</span>');
	
	var toggle = 0;
	$(this).siblings('.see-more').click(function(){
		if( toggle == 1 ){
			$(this).siblings('div.inner').animate({height: visible_lines}, 500);
			$(this).text('See More');
			toggle = 0;
		} else {
			$(this).siblings('div.inner').animate({height: expadable_height}, 500);
			$(this).text('See Less');
			toggle = 1;
		}
	});
});

Demo

Check if page scroll is at bottom

May seem odd to check if the page scroll is at bottom, but can be useful if you need to hide something or show something else, as in a back to top button for example.

$('#back-to-top').hide();
$(window).scroll(function(){
    if ( document.body.scrollHeight - $(this).scrollTop()  <= $(this).height() ){
        $('#back-to-top').show();
    } else {
        $('#back-to-top').hide();
    }
});

Quick and simple jQuery accordion

A simple jQuery snippet for those times when you don’t need an entire plugin, but just something quick, and on the spot.

<ul class="accordion">
	<li>
		<div class="heading">Lorem ipsum dolor</div>
		<div class="content">
			Lorem ipsum dolor sit amet...
		</div>
	</li>
</ul>
//accordion
$('.accordion .content').hide();

$('.accordion .heading').click(function(){
	$(this).siblings('.content').slideToggle('fast');
	$(this).parent().toggleClass('active');
	$(this).parent().siblings().children('.content:visible').slideUp('fast');
	$(this).parent().siblings().children('.content:visible').parent().removeClass('active');
});

See demo here.

jQuery toggle functions

The toggle() method was deprecated in jQuery 1.8 and removed in 1.9.
In jQuery 1.9 the toggle() method does not toggle between two or more functions on a click event, it just toggles the visibility of an element.

Here is a quick way of replacing it:

var toggle = 0;
$('#toggle-btn').on('click', function(event) {
	event.preventDefault();
	if ( toggle == 1 ){
		// not clicked
		$(this).removeClass('clicked');
		toggle = 0;
	} else {
		// clicked
		$(this).addClass('clicked');
		toggle = 1;
	}
});

or just using a class,

$('#toggle-btn').on('click', function(event) {
	event.preventDefault();
	if ( $(this).hasClass('active') ) {
		$(this).removeClass('active');
	} else {
		$(this).addClass('active');
	}
});

See demo here.

BxSlider slides counter

Update! Scroll to updated code.

Add a slides counter ( current/total ) to bxSlider carousels, using bxSlider callbacks and methods.
You just have to add an html element ( ex. ‘<div id=”slide-counter”></div>’ ), where to show the numbers, and the code below will do the rest.

function insertCount(slide_curr,slide_count){
	$('#slide-counter').html('<strong>'+ (slide_curr + 1) +'</strong>/'+ slide_count);
};

var slider = $('#slideshow').bxSlider({
	auto: true,
	pager: false,
	onSliderLoad: function (){
		var slide_count = slider.getSlideCount();
		var slide_curr = slider.getCurrentSlide();
		insertCount(slide_curr,slide_count);
	},
	onSlideNext: function (){
		var slide_count = slider.getSlideCount();
		var slide_curr = slider.getCurrentSlide();
		insertCount(slide_curr,slide_count);
	},
	onSlidePrev: function (){
		var slide_count = slider.getSlideCount();
		var slide_curr = slider.getCurrentSlide();
		insertCount(slide_curr,slide_count);
	}
});

Because ‘onSlideNext’ and ‘onSlidePrev’ callbacks are executed only before each “Next” or “Prev” slide transition, if you want to use a ‘pager’ for navigating through slides, you’ll need to use the ‘onSlideAfter’ callback.

function insertCount(slide_curr,slide_count){
	$('#slide-counter').html('<strong>'+ (slide_curr + 1) +'</strong>/'+ slide_count);
};

var slider = $('#slideshow').bxSlider({
	auto: true,
	pager: false,
	onSliderLoad: function (){
		var slide_count = slider.getSlideCount();
		var slide_curr = slider.getCurrentSlide();
		insertCount(slide_curr,slide_count);
	},
	onSlideAfter: function (){
		var slide_count = slider.getSlideCount();
		var slide_curr = slider.getCurrentSlide();
		insertCount(slide_curr,slide_count);
	}
});

Here you can find a demo.


Updated code, and demo with the latest BxSlider version.
The old code with the 4.1.2 bxSlider version, throws an error if the “getSlideCount()” public method is called in a callback fuction.

$('#slide-counter').prepend('<strong class="current-index"></strong>/');

var slider = $('#slideshow').bxSlider({
	auto: true,
	onSliderLoad: function (currentIndex){
		$('#slide-counter .current-index').text(currentIndex + 1);
	},
	onSlideBefore: function ($slideElement, oldIndex, newIndex){
		$('#slide-counter .current-index').text(newIndex + 1);
	}
});

$('#slide-counter').append(slider.getSlideCount());

Updated demo

JQuery Cycle pager with leading zeros

Adding leading zeros to Cycle’s pager can sometimes make a big visual difference. Using the pagerAnchorBuilder this can be achieved very simple:

pagerAnchorBuilder: function(idx, slide) {
	if (idx < 10) {
		return '<li><a href="#">0' + (idx+1) + '</a></li>';
	} else {
		return '<li><a href="#">' + (idx+1) + '</a></li>';
	}

Custom select input

Using some jQuery and CSS you can make a cross-browser custom select (dropdown) box.

<div class="select-wrapper">
    <select>
        <option selected="selected" value="1">Option 1</option>
        <option value="2">Option 2</option>
        <option value="3">Option 3</option>
        <option value="4">Option 4</option>
        <option value="5">Option 5</option>
    </select>
</div>
.select-wrapper {
  position: relative;
  width: 215px;
  height: 30px;
  padding: 0 25px 0 0;
  margin: 0;
  border: 1px solid #0D5995;
  overflow: hidden;
  background: url(select-arrow.png) no-repeat right center transparent;
}

select {
  position: absolute;
  left: 0;
  top: 0;
  opacity : 0;
  width: 240px;
  height: 30px;
  padding: 5px 0;
  border: none;
  background: transparent !important;
  -webkit-appearance: none;
}

.select-wrapper span {
  display: block;
  width: 210px;
  height: 30px;
  line-height: 30px;
  padding: 0 0 0 5px;
}
$(document).ready(function() {
  $('select').after('<span>' + $('option:selected', this).text() + '</span>');
  
  $('select').click(function(event) {
    $(this).siblings('span').remove();
    $(this).after('<span>' + $('option:selected', this).text() + '</span>');
  });
})

See the demo.

jQuery Cycle with carousel thumbs pager

A nice cycle gallery with thumbnail pictures navigation ( like here http://jquery.malsup.com/cycle/pager3.html ), but to use less space, make the thumbnails pager a carousel. ( see a demo here … note, that this is just to prove the concept, not much attention was given to styles ).

If you have “Prev / Next” controls on the cycle slideshow, then you will stumble upon an annoying situation: When you cycle through the slides with the cycle controls, and reach the last visible thumbnail in carousel, you will have to use the carousel controls to go to the current slide’s thumb; to avoid this i used the cycle’s ‘onPrevNextEvent’ callback to navigate through the carousel in the same time you cycle through the slides.

You will need:

1. jQuery

2. Cycle plugin

3. any jquery carousel you want ( i have used jCarousel lite )

Make the markup as you want, and adapt the jQuery code to it.

$('#slideshow').cycle({
    fx: 'scrollHorz',
    speed: 'fast',
    timeout: 0,
    prev: '#prev',
    next: '#next',
    nowrap: 1,
    pager: '#slide-pager ul',
    pagerAnchorBuilder: function(idx, slide) {
        // return selector string for existing anchor
        return '#slide-pager ul li:eq(' + idx + ') a';
    },
    onPrevNextEvent: function(dir, id, el) {
        if (dir === true) {
		if (id >= 3) { //replace '3' with your number of visible elements
			$('#slide-pager_next').click();
		}
        }
        else {
		if (id >= 1) {
			$('#slide-pager_prev').click();
		}
        }
    }
});

$("#slide-pager").jCarouselLite({
    btnNext: "#slide-pager_next",
    btnPrev: "#slide-pager_prev",
    circular: false,
    visible: 3
});

See the demo here.

Add repeating CSS selectors

Have you ever needed a way to style the elements of a set ( lets say 5 ) individually, but the same rules to be applied to other set ( of 5 ) ?

For example:

<div>
     <h4>first</h4>
     <p>lorem ipsum ...</p>
     <h4>second</h4>
     <h4>third</h4>
     <h4>forth</h4>
     <div>lorem ipsum ...</div>
     <h4>fifth</h4>
     <!-- here end our first set -->
     <h4>first</h4>
     <h4>second</h4>
     <h2>lorem ipsum ...</h2>
     <h4>third</h4>
     <span>lorem ipsum ...</span>
     <h4>forth</h4>
     <h4>fifth</h4>
     <!-- here end our 2nd set -->
</div>

and we want that the first h4 in the first set have same styles as the first h4 in the second and so on, of course our h4’s are not grouped, but they are scattered between other elements, and other h4’s can be added in the future.

If we have a way to distinguish our elements from the other then we can make a short script with jQuery to add classes.

For a group of five css classes that will repeat after a number ( for this example we took, n = 5 ), this means that our h4’s from 1 to 5 will have same classes with the h4’s from 6 to 10, and so on; for this we will use something that in math is called ‘modulo’, basically gives us the remaining of the division of two numbers, and as we can get the index of our element we can see which position has in our set ( in this case of 5 ).

$('div h4').each(function(index) {

	if(index%5 == 0){
		$(this).addClass('first');
	} else if(index%5 == 1){
		$(this).addClass('second');
	} else if(index%5 == 2){
		$(this).addClass('third');
	} else if(index%5 == 3){
		$(this).addClass('forth');
	} else if(index%5 == 4){
		$(this).addClass('fifth');
	}
});

the result would be:

<div>
     <h4 class="first">first</h4>
     <p>lorem ipsum ...</p>
     <h4 class="second">second</h4>
     <h4 class="third">third</h4>
     <h4 class="forth">forth</h4>
     <div>lorem ipsum ...</div>
     <h4 class="fifth">fifth</h4>
     <!-- here end our first set -->
     <h4 class="first">first</h4>
     <h4 class="second">second</h4>
     <h2>lorem ipsum ...</h2>
     <h4 class="third">third</h4>
     <span>lorem ipsum ...</span>
     <h4 class="forth">forth</h4>
     <h4 class="fifth">fifth</h4>
     <!-- here end our 2nd set -->
</div>