issue is with clone, splice, remove, append jquery function - javascript

There are multiple images in HTML.
<ul class="ice-navigator">
<li>
<a href="javascript:void(0);" class="thumb" id = "26">
<img src="images/123.png" alt="Title #0" width="75" height="75"/>
</a>
</li>
<li>
<a href="javascript:void(0);" class="thumb" id = "28">
<img src="images/456.png" alt="Title #0" width="75" height="75"/>
</a>
</li>
.
.
.
</ul>
I want to show only 5 images at a time, so i am using this code "onload" to hide image if it is more than 5.
stPt = 0, elToShow = 5; //showing 5 elements
$ul = $('ul.ice-navigator');
$li = $('ul.ice-navigator li'); //get the list of li's
$copy_li = [];
copy_lgt = $li.length - elToShow;
for (var i = elToShow; i < $li.length; i++)
{
var tmp;
tmp = $li.eq(i);
$copy_li.push(tmp.clone());
tmp.remove();
}
To show prev and next, i am using this code.
$('.ice-next').click (function ()
{
$li = $('ul.ice-navigator li'); //get the list of li's
$copy_li.splice(copy_lgt, 0, $li.eq(0).clone() ); //move the 1st element clone to the last position in copy_li
$li.eq(0).remove(); //kill the 1st element in the UL
$ul.append($copy_li.shift()); //add to the last
});
$('.ice-previous').click (function ()
{
$li = $('ul.ice-navigator li'); //get the list of li's
$copy_li.splice(0, 0, $li.eq(elToShow-1).clone()); //move the 1st element clone to the last position in copy_li
$li.eq(elToShow-1).remove();//kill the 1st element in the UL
$ul.prepend($copy_li.pop());//add to the last
});
Everything works fine, except this:
There is one click event associated with thumb class.
jQuery(document).ready(function($) {
$(".thumb").click(function(){
alert ("Reaching here");
)};
)}:
This is working in beginning. but once we have used
$('.ice-previous').click (function () or $('.ice-next').click (function ()
then
$(".thumb").click(function(){ is not working.
I mean now click on image will not print Reaching here.
What is causing this issue??

Because you are removing and re-attaching DOM elements, you need to delegate your events on those elements like this:
$('.ice-navigator').on('click', '.thumb', function() {
alert('Reaching here');
});
More info: http://api.jquery.com/on/

Related

JQuery how to add only the clicked image css class with nth-child?

How to add class="active" to the clicked thumbnail image?
HTML :
<ul class="product-thumbnail">
<li>
<img class="thumbnail" src="Nile_1_16_0095.jpg">
</li>
<li>
<img class="thumbnail" src="Nile_1_16_0096.jpg">
</li>
<li>
<img class="thumbnail" src="Nile_1_16_0097.jpg">
</li>
</ul>
JS :
$(".thumbnail").click(function () {
var index = $(this).parent().index();
$('ul > li:nth-child(' + index + ')').attr('class', 'active');
});
This will change all img classes to active. Instead I want only the clicked img to get the class active. How can I achieve that?
Instead of .attr('class', 'active'); you should use .addClass('active'); and you don't need index you could add class directly to the parent :
$(".thumbnail").click(function () {
//remove class 'active' from all the lis
$(this).parent().siblings().removeClass('active');
//Add class 'active' to the clicked one
$(this).parent().addClass('active');
});
Hope this helps.
Looking at your code you want to add the class at the li level rather than at the img level.
try
$(".thumbnail").click(function () {
$(this).parent().addClass( 'active'); //go to the parent of the current element and add class active
});
Instead i want only the clicked img to get the class "active"
if you want to add class at img level, then try this code
$(".thumbnail").click(function () {
$(this).addClass( 'active');
});
Might be easier to understand:
var selector = $('.product-thumbnail img.thumbnail');
// select img tag with thumbnail class who are descendants of class product-thumbnail
selector.click(function(){
selector.removeClass('active'); // remove class from all selector
$(this).addClass('active'); // add class to clicked
});
I don't understand why this is not working for you. This is how it should be done. i.e,
$(".thumbnail").click(function () {
var index = $(this).parent().index();
$('ul > li:nth-child(' + index + ')').attr('class', 'active');
});
will work fine.The only issue is that the index that you get in the index var needs to be incremented by 1 to select the right element.
Change:
var index = $(this).parent().index();
to:
var index = $(this).parent().index() + 1;

javascript function onclick with new elements

I work on a website, and I have a js problem.
I resume the situation:
I made a dynamic form with some tabs in.
I can switch tabs with a js click function
When I click on the "+" tab , it creates a new tab ( new <li> on the <ul>, and new <div> on main div )
But when I want to go on the new tab freshly created, the click function don't answer.
I put a console.log on the first line of the click function, and no log output.
the click function works well with static content, but with fresh content don't work.
How can I make it works with dynamic content ?
http://jsfiddle.net/npx2mes2/
http://jsfiddle.net/npx2mes2/1/
$("#tabs_menu_n1").on('click', 'a', function(e)
the problem was on registering the event, you should attach it to parent first, and then on every child.
change the line $(".tabs_menu_n1 a").click(function(e) { to $(document).on('click', ".tabs_menu_n1 a", function (e) {
Demo
Explanation.
when the elements are being added to DOM dynamically you must register the for the events every time the element is added. So instead of doing this process every time simply register events like below, therefore you don't want to register the events fro dynamically created elements
$(document).on('click', ".selector", function (e) {));
Now i can add elements with selector class dynamically and can handle click event on the element without registering the click event every time i add the element.
Note: You can use parent selector in place of document
A bit simplified sample without jQuery.
But idea same: add click handler to ul and check inside that clicked a tag.
var x = 2;
var original = document.getElementById('H1_n1');
function a(content, href) {
var link = document.createElement("a");
link.textContent = content;
link.setAttribute('href', href);
return link;
}
function li_a(id, content, href) {
var listItem = document.createElement("li");
listItem.setAttribute('id', id);
listItem.appendChild(a(content, href));
return listItem;
}
function div(id, textContent) {
var d = document.createElement("div");
d.setAttribute('class', 'tab_content_n1')
d.setAttribute('id', id)
d.textContent = textContent;
return d;
}
function add_rec() {
var i = x++;
var mdiv = document.getElementById("tab_n1");
mdiv.appendChild(div('H1_n' + i, '\nHello world from n' + i + '.\n'));
pbtn = document.getElementById('pbtn');
var ul = document.getElementById("tabs_menu_n1");
ul.insertBefore(li_a("hn" + i, "H" + i, "#H1_n" + i), pbtn);
}
document.getElementById('tabs_menu_n1').addEventListener('click', function(e) {
var el = e.target;
if (el.nodeName !== 'A') return;
if (el.hash == "#+") add_rec();
else {
e.preventDefault();
var current = document.querySelectorAll("#tabs_menu_n1 .current, #tab_n1 .current");
for (var i = 0, len = current.length; i < len; i++) {
current[i].classList.remove('current');
}
el.classList.add('current');
document.querySelector(el.hash).classList.add('current');
}
}, false);
.tab_content_n1 {
display: none;
}
.tab_content_n1.current {
display: block;
animation: fadeIn 1s;
}
a.current {
color: red;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="tab_space">
<ul id="tabs_menu_n1" class="nav nav-tabs tabs_menu_n1 tab_body">
<li><a class="current" href="#M_n1">mai</a>
</li>
<li>red
</li>
<li id="hn1">hor
</li>
<li id="pbtn">+
</li>
</ul>
</div>
<div id="tab_n1" class="tab_n1">
<div class="tab_content_n1 current" id="M_n1">mai</div>
<div class="tab_content_n1" id="R_n1">red</div>
<div class="tab_content_n1" id="H1_n1">hor</div>
</div>

jQuery effects lost after append html to another DIV,

I have a div inside it has images carousel, and I'd like to append it to another DIV outside. However, I lost carousel on the new div outside. How can I enable carousel for the appended div?
online sample: http://jsfiddle.net/PYQXa/
<div class="inside">
<ul class="slider">
<li>
<img src="http://lorempixel.com/580/250/nature/1"> <!-- random image -->
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/2"> <!-- random image -->
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/3"> <!-- random image -->
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/4"> <!-- random image -->
</li>
</ul>
</div>
<div class="outside">
<!-- append content here -->
</div>
jQuery
var $inside = $('.inside');
$inside.hide();
var appendcontent = $inside.find('.slider').html();
$(appendcontent).appendTo($('.outside'));
// settings
var $slider = $('.slider'); // class or id of carousel slider
var $slide = 'li'; // could also use 'img' if you're not using a ul
var $transition_time = 1000; // 1 second
var $time_between_slides = 2000; // 4 seconds
function slides(){
return $slider.find($slide);
}
slides().fadeOut();
// set active classes
slides().first().addClass('active');
slides().first().fadeIn($transition_time);
// auto scroll
$interval = setInterval(
function(){
var $i = $slider.find($slide + '.active').index();
slides().eq($i).removeClass('active');
slides().eq($i).fadeOut($transition_time);
if (slides().length == $i + 1) $i = -1; // loop to start
slides().eq($i + 1).fadeIn($transition_time);
slides().eq($i + 1).addClass('active');
}
, $transition_time + $time_between_slides
);
it would be working fine if you remove
var $inside = $('.inside');
$inside.hide();
var appendcontent = $inside.find('.slider').html();
$(appendcontent).appendTo($('.outside'));
var appendcontent = $inside.find('.slider').html();
The html() method returns the innerHTML of the jQuery element. In your example, it's a list of <li> nodes. Just replace the line with:
var appendcontent = $inside.find('.slider');
Edit : I've checked the fiddle again, you are appending only the 'li' into the new div. To have it work properly, you should use
$inside.find('.slider');
You were adding the slider class content into the outside class but .. u need to add inside content on outside div otherwise all anim related to slider class will be vanish..
var appendcontent = $inside.find('.slider').html();
var html = $inside.html();
$(html).appendTo($('.outside'));
And the slider need to select like this
var $slider = $('.outside .slider'); // class or id of carousel slider
DEMO
Because the appentcontent doesnt have the class "slider". You shold replace the line
$inside.find('.slider').html();
with
$inside.find('.slider').parent().html();

Using :last-child and :first-child with jQuery

I'm trying to write my first self-built jQuery script, as a super simple gallery.
CSS:
#gallery li{
display:none;
}
#gallery li.current {
display: block;
}
HTML:
<div id="gallery">
<li class="current"><img src="img/1.jpg" /></li>
<li><img src="img/2.jpg" /></li>
<li><img src="img/3.jpg" /></li>
<li><img src="img/4.jpg" /></li>
</div>
<div id="controls">
<span id="left"><</span>
<span id="right">></span>
</div>
JQUERY:
$(function(){
$('#controls #left').click(function(){
var old = $('li.current');
$('li.current').removeClass('current');
if (old = $('#gallery:first-child')){
$('#gallery:last-child').addClass('current');
}else{
$(old).prev('li').addClass('current');
}
});
$('#controls #right').click(function(){
var old = $('li.current');
if (old = $('#gallery:last-child')){
$('#gallery:first-child').addClass('current');
}else{
$('li.current').removeClass('current');
$(old).next('li').addClass('current');
}
});
});
It worked fine until I added the if/else statements to check whether we're looking at the first/last gallery image. I want this statement so that the gallery loops. Can't figure out why it's not working, and debug is giving me nothing.
Can I get a little push in the right direction?
EDIT: using some suggestions below, here's where I'm at:
$(function(){
$('#left').click(function(){
var old = $('li.current');
old.removeClass('current');
if (old == $('#gallery li:first-child')){
$('#gallery li:last-child').addClass('current');
}else{
old.prev('li').addClass('current');
}
});
$('#right').click(function(){
var old = $('li.current');
old.removeClass('current');
if (old == $('#gallery li:last-child')){
$('#gallery li:first-child').addClass('current');
}else{
old.next('li').addClass('current');
}
});
});
Still isn't looping around though (pressing "left" on the first image makes the gallery blank, as does pressing "right" on the last image)
You might want to be using ==:
if (old == $('#gallery:first-child')){
and
if (old == $('#gallery:last-child')){
Although that won't work anyways, as pointed out by Jack, because they are separate jQuery calls that may select the same elements and return similar jQuery objects, but won't work with comparison because they are separate collections of DOM element(s). The correct way is to use .is like I provide below...or to compare with:
if (old[0] == $('#gallery:first-child')[0]){
Indexing them like that retrieves the first item each in the selected sets, which are the actual DOM elements, and can be compared. Probably not preferred, but its not wrong.
Here's an example of proving this is true: http://jsfiddle.net/4adSj/
You're also doing a few weird things. You don't need to use this selector: $('#controls #right') - $('#right') is unique enough thanks to how id should be used.
Also, you store var old = $('li.current'); and then the next line you don't bother using old - you re-get it like $('li.current').
Also, you are nesting <li> elements in a <div>, when they should only be nested in <ul>, <ol>, or <menu>.
One more - the variable old is a jQuery object, so you don't need to be doing $(old) every other time you want to access it after you declared it. Just use old.jQueryMethod().
Finally, the other problem is that your selector for the if statements:
$('#gallery:last-child')
Means find the element that has the id "gallery" and is a last-child. You probably want:
$('#gallery > li:last-child')
Which means find the child element that is the last li child element of the parent element with an id of "gallery".
So here's my suggestion of your final code to use:
$(function(){
$('#left').on("click", function () {
var old = $('li.current');
old.removeClass('current');
if (old.is(':first-child')){
$('#gallery > li:last-child').addClass('current');
} else {
old.prev('li').addClass('current');
}
});
$('#right').on("click", function () {
var old = $('li.current');
old.removeClass('current');
if (old.is(':last-child')){
$('#gallery > li:first-child').addClass('current');
} else {
old.next('li').addClass('current');
}
});
});
You can use .is(':first-child) and .is(':last-child') to find out if something is the first or last child respectively:
$('#controls #left').click(function() {
var old = $('li.current')
.removeClass('current');
if (old.is(':first-child')) {
// search the siblings for the last child
old.siblings(':last-child').addClass('current');
} else {
$(old).prev('li').addClass('current');
}
});
$('#controls #right').click(function() {
var old = $('li.current')
.removeClass('current');
if (old.is(':last-child')) {
old.siblings(':first-child').addClass('current');
} else {
$(old).next('li').addClass('current');
}
});
​
Btw, I would change your HTML to this:
<div id="controls">
<span class="left"><</span>
<span class="right">></span>
</div>
And then use $('#controls .left') and $('#controls .right') to target your clickable elements.
Edit
A fancier approach could be this, food for thought:
// wrap the functionality inside an anonymous function
// localizing the gallery and controls blocks
(function($gallery, $controls) {
var pos = 0;
// this function performs the actual move left and right, based on event data being passed in via evt.data.delta
function move(evt) {
var $items = $gallery.children(), // if the gallery never changes size you should cache this value
max = $items.length;
$items.eq(pos).removeClass('current');
pos = (pos + evt.data.delta) % max; // update the position
$items.eq(pos).addClass('current');
}
// attach the controls
$controls
.on('click', '.left', {
delta: -1 // left decreases the position
}, move)
.on('click', '.right', {
delta: 1 // right increases the position
}, move);
// make sure the first is always selected
$gallery.children().removeClass('current').eq(pos).addClass('current');
}($('#gallery'), $('#controls')));​​​​​​​​​ // immediate invocation
jsBin demo
var c = 0;
var imgN = $('#gallery li').length; // 4
$('#left, #right').click(function(){
c = this.id=='right' ? ++c : --c ;
$('#gallery li').hide().eq( c%imgN ).show();
});
Or even:
var c = 0;
$('#left, #right').click(function(){
$('#gallery li').hide().eq( (this.id=='right'?++c:--c) % 4 ).show();
});
gallery Demo
P.S: instead of .hide() you can use .removeClass('current')
and instead of .show() you can use .addClass('current')

Carousel with image map linked to next image

The long and short of it is I'm trying to use a carousel, and instead of using next and previous buttons to navigate to other images, I want to use image mapping to link to other images. I'm quite stuck, so I appreciate any advice!
My carousel is from this site's tutorial (https://christianheilmann.com/2015/04/08/keeping-it-simple-coding-a-carousel/
). Here's my html code:
<ol class="content">
<li>
<img src="http://lorempixel.com/200/200" alt="mag" usemap="#map" class="img-responsive">
<map name="map">
<area shape=poly coords="500,80,1080,80,1080,550,500,550" href="img2" title="vent1" > <!--where should href link to?? -->
</map>
</li>
<li><img src="http://lorempixel.com/199/200" alt="2"></li>
<li><img src="http://lorempixel.com/200/199" alt="3"></li>
</ol>
My javascript:
carousel = (function(){
// Read necessary elements from the DOM once
var box = document.querySelector('.simbox');
var next = box.querySelector('.next');
var prev = box.querySelector('.prev');
// Define the global counter, the items and the
// current item
var counter = 0;
var items = box.querySelectorAll('.content li');
var amount = items.length;
var current = items[0];
box.classList.add('active');
// navigate through the carousel
function navigate(direction) {
// hide the old current list item
current.classList.remove('current');
// calculate the new position
counter = (counter + direction) % amount;
counter = counter < 0 ? amount - 1 : counter;
// set new current element
// and add CSS class
current = items[counter];
current.classList.add('current');
}
// add event handlers to buttons
next.addEventListener('click', function(ev) {
navigate(1);
});
prev.addEventListener('click', function(ev) {
navigate(-1);
});
// show the first element
// (when direction is 0 counter doesn't change)
navigate(0);})();
You asked "where should href link to?"
you can link it to href="javascript:navigate(1)" that way, when you click on the area, it will fire the navigate(1) function that will cause the carousel go to the next item.

Categories

Resources