How to change images at runtime in jQuery - javascript

I need to change the images on every click using jQuery, lets say while the page loads for the first time it will be img1 and when i click on img1 it will be img2 and again if i click on img2 it will b img 1, and this should go on...
code:
<div>
<span class="myimage">
<img class="img1"src="8A7FA0A1FFEC5443785B9B29AF7629.jpg" alt="" />
<img class="img2"src="abcd.jpg" alt="" />
</span>
<div>
<span>
Hello
</span>
<ul class="myul">
<li>one</li>
<li>Two</li>
</ul>
</div>
<span class="myimage">
<img class="img1"src="8A7FA0A1FFEC5443785B9B29AF7629.jpg" alt="" />
<img class="img2"src="abcd.jpg" alt="" />
</span>
<div>
<span>
r u there
</span>
<ul class="myul">
<li>three</li>
<li>four</li>
</ul>
</div>
</div>
jQuery:
$(document).ready(function() {
$(".myul").hide();
$(".myimage").click(function() {
if ($(".img2").is(":hidden")) {
$(this).next("div").find(".myul").slideToggle(600);
$(".img1").hide();
$(".img2").show();
}
else {
$(this).next("div").find(".myul").slideToggle(600);
$(".img2").hide();
$(".img1").show();
}
});
});
but the probelm is as the class is same both the sections are taking same image.when i am clicking on the first section, only the image for the first section should be changed, how to do taht..any suggestions

You can add the context into your selectors.
For example $(".img1") becomes $(".img1", this)
$(document).ready(function() {
$(".myul").hide();
$(".myimage").click(function() {
if ($(".img2", this).is(":hidden")) {
$(this).next("div").find(".myul").slideToggle(600);
$(".img1", this).hide();
$(".img2", this).show();
}
else {
$(this).next("div").find(".myul").slideToggle(600);
$(".img2", this).hide();
$(".img1", this).show();
}
});
});

You can use selectors to find DOM elements relative to the element that the event was originally fired on.
For example, in this case you can find the children of the span you have attached the 'click' event to:
$(".myimage").click(function() {
if ($(this).children(".img2").is(":hidden")) {
// do something
}

Related

JQuery change picture upon selection

I have list of options:
<li class="">
<img src="/1.img" />
<img src="/2.img" />
Option 1
</li>
<li class="">
<img src="/1.img" />
<img src="/2.img" />
Option 2
</li>
By default - 1.img visible.
If user select for example Option 1, i want 1.img to hide(); and 2.img to show(); But just for Option 1.
For example this code:
$("#selection li").click(function(){
$('.not-checked').hide(); // to hide image
$('.checked').show(); // to show image
}
Change picture in every li. How can i change picture only on selected li ?
To only target the children of the <li> element you're clicking on, you can make use of jQuery's .find() method. You want to find the img elements, and in order to target specific <img> elements, you can use the :nth-of-type pseudo-class:
$("#selection li").click(function() {
$(this).find('img:nth-of-type(1)').hide(); // to hide image
$(this).find('img:nth-of-type(2)').show(); // to show image
});
img:nth-of-type(2) {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="selection">
<li class="">
<img src="http://via.placeholder.com/50/ff00000/ff00000" />
<img src="http://via.placeholder.com/50/0000ff/0000ff" /> Option 1
</li>
<li class="">
<img src="http://via.placeholder.com/50/ff00000/ff00000" />
<img src="http://via.placeholder.com/50/0000ff/0000ff" /> Option 2
</li>
</div>
Or you could simply use a 'data-' attribute on all the elements and compare them in jquery.
<div id="selection">
<li class="" data-option="1">
<img src="/1.img" data-option="1">
<img src="/2.img" data-option="2">
Option 1
</li>
<li class="" data-option="2">
<img src="/1.img" data-option="1">
<img src="/2.img" data-option="2">
Option 2
</li> </div>
And from your script
$("#selection li").click(function() {
//first hide all images
$(this).find("img").hide();
//then show only the ones with the right data-option
$(this).find("img[data-option="+$(this).data('option')+"]").show()
});
Btw, you do not always have to use data- it's just a jQuery convention of giving attributes to a tag.
You can use jQuery toggle() to achieve it.
$("li").click(function() {
$(this).find("img").toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="">
<img src="http://via.placeholder.com/50/ff00000/ff00000" />
<img style="display:none" src="http://via.placeholder.com/50/0000ff/0000ff" />
Option 1
</li>
<li class="">
<img src="http://via.placeholder.com/50/ff00000/ff00000" />
<img style="display:none" src="http://via.placeholder.com/50/0000ff/0000ff" />
Option 2
</li>
Explanation: $(this) will keep you in the clicked <li>; find("img") will target all of the images inside; toggle() will change the display for any targeted img;

Simple: Remove <li> with classname, then add this classname to next (or current) <li>

I have a list of images in a slider like so:
<ul>
<li class="dd">one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
There is a button to delete the <li> with the class "dd", so I have this function going on:
function delete(){
$('li.dd').remove();
}
So now that that particulat <li> is deleted, I want the class "dd" to be added to either the <li> I am currently on. I tried adding this:
function delete(){
$('li.dd').remove();
$('li').addClass(' dd')
}
but as you can see, all it does is add the class to all existing <li>s, meaning if I choose to click the delete button again, the entire list is deleted.
I have a pen going on of exactly what I have:
http://codepen.io/anon/pen/gpNwGp
Thank you in advance!
Because you're adding class to all the elements, all the lis will be removed on next click. You can add the class to only first li using following methods.
You can use :first pseudo-selector to select first element.
function delete() {
$('li.dd').remove();
$('li:first').addClass('dd');
// ^^^^^^
}
You can also use first() to get first element
function delete() {
$('li.dd').remove();
$('li').first().addClass('dd');
// ^^^^^^^^
}
You can check updated codepen Demo.
You can use jQuery methods to make it much cleaner
function toggleSlide(direction) {
var $visible = $('.slider > li:visible').hide();
var $ft = $visible[direction ? 'next' : 'prev']();
if (!$ft.length) {
$ft = $('.slider > li')[direction ? 'first' : 'last']();
}
$ft.show();
setIndex();
}
function getVisible() {
return $('.slider > li:visible').index() + 1;
}
function goToEdge(where) {
$('.slider > li:visible').hide();
$('.slider > li')[where ? 'last' : 'first']().show();
setIndex();
}
function addSlide() {
$('ul.slider').append('<li class="hideable"><img src="http://placehold.it/700x100" alt="Sunset" /></li>');
}
function deleteSlide() {
var $visible = $('.slider > li:visible');
toggleSlide(true);
$visible.remove();
}
function setIndex() {
$('#slideNumber').text(getVisible())
}
setIndex();
.hideable {
display: none;
}
img {
width: 640px;
height: 480px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="slider" style="list-style-type:none; margin-left:-2em;">
<li class="hideable dd" style="display: block;">
<img src="http://placehold.it/100x100" alt="hinterground" />
</li>
<li class="hideable">
<img src="http://placehold.it/200x100" alt="Berries" />
</li>
<li class="hideable">
<img src="http://placehold.it/300x100" alt="Cheetah" />
</li>
<li class="hideable">
<img src="http://placehold.it/400x100" alt="Fence" />
</li>
<li class="hideable">
<img src="http://placehold.it/500x100" alt="Paper" />
</li>
<li class="hideable">
<img src="http://placehold.it/600x100" alt="Sunset" />
</li>
<!-- ... and so on -->
</ul>
<!-- Buttons to go back and forth between slides. -->
<form>
<input type="button" id="firstButton" value="First" onclick="goToEdge(false)" />
<input type="button" value="Back" onclick="toggleSlide(false)" />
<input type="button" value="Forward" onclick="toggleSlide(true)" />
<input type="button" id="lastButton" value="Last" onclick="goToEdge(true)" />
<input type="button" value="Add Slide" onclick="addSlide()" />
<input type="button" value="Delete Slide" onclick="deleteSlide()" />
<p>Slide
<!-- you can change "Slide" to Page, Item, etc. --> <span id="slideNumber">
</span>
</p>
</form>
save the next element first to add you class:
function delete(which) {
var next_li = $('li.dd').next();
$('li.dd').remove();
next_li.addClass("dd");
}
i think this might helps you.
good luck.
remember ! do not use .first() because it gives the first li dd class. not the one that is in line.

How do I hijack just one specific link within an LI and not ALL links?

I have a menu that in each li, it will have multiple <a> tags. The main one being the name of the item. When that one is clicked, I want a Dropdown event to happen. But on the items within the <li> I want those clicks to function normally.
My HTML looks like this:
<li class="tree-item-name">Aunts & Uncles
<span class = "bootstrap-styles">
<ul>
<li>
<img alt="Default" class="img-circle" height="48" src="/assets/default.jpg" width="48" />
Jackie Lynn <a data-confirm="Are you sure?" data-method="delete" href="/family_trees/3" rel="nofollow"><i class="fa fa-thumbs-o-down"></i></a>
</li>
</ul>
</span>
</li>
The JS looks like this:
jQuery(document).ready(function(){
jQuery('LI.tree-item-name').click(function(){
if (jQuery(this).hasClass('opened')) {
jQuery(this).find('UL').slideUp();
jQuery(this).removeClass('opened');
} else {
jQuery(this).find('UL').slideDown();
jQuery(this).addClass('opened');
}
return false;
});
});
But right now, when you click on either the img tag or Jackie Lynn....neither work - because both are being hijacked by the JS.
How do I set this up so only li.tree-item-name is affected?
You need to stop event propagation and target only lis which has a ul inside it
jQuery(function($) {
$('LI.tree-item-name').has('ul').click(function() {
if ($(this).hasClass('opened')) {
$(this).find('UL').slideUp();
$(this).removeClass('opened');
} else {
$(this).find('UL').slideDown();
$(this).addClass('opened');
}
return false;
});
$('LI.tree-item-name li').click(function(e) {
e.stopPropagation();
})
});
.tree-item-name ul {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li class="tree-item-name">
Aunts & Uncles
<span class="bootstrap-styles">
<ul>
<li>
<img alt="Default" class="img-circle" height="48" src="/assets/default.jpg" width="48" />
Jackie Lynn <a data-confirm="Are you sure?" data-method="delete" href="/family_trees/3" rel="nofollow"><i class="fa fa-thumbs-o-down"></i></a>
</li>
</ul>
</span>
</li>
</ul>
Give your a tag (Aunts & Uncles) a class, and use that class as the jQuery click event trigger.
jsFiddle Demo
<li class="tree-item-name"><a class="rels" href="#">Aunts & Uncles</a>
<span class = "bootstrap-styles">
<ul>
<li>
<img alt="Default" class="img-circle" height="48" src="http://placekitten.com/g/48/48" width="48" />
Jackie Lynn <a data-confirm="Are you sure?" data-method="delete" href="/family_trees/3" rel="nofollow"><i class="fa fa-thumbs-o-down"></i></a>
</li>
</ul>
</span>
</li>
jQuery('.rels').click(function(){
if (jQuery(this).parent().hasClass('opened')) {
jQuery(this).parent().find('UL').slideUp();
jQuery(this).parent().removeClass('opened');
} else {
jQuery(this).parent().find('UL').slideDown();
jQuery(this).parent().addClass('opened');
}
return false;
});
That's because you are using (this) which takes care of the link you click on but then select the entire unordered list.
You need to put the url's on separate list item for it to work the way you have it.

Target parent next div

I´m trying to target a <div> which is the next <li> of the parent <div> of the function show_projectinfo(). I've tried .next(), .closest(), etc... with no luck, any ideas?
The function is that if I click on a.more_info then the li.slider img is hidden... I don´t know if it is out of scope completely... This is a div that is repeated so I can´t just use the IDs.
markup:
<li class="info">
<a id="previous-slider"> < </a>
<span>01/15</span>
<a id="next-slider" href="javascript:void(0)"> > </a>
<a class="more_info" href="javascript:void(0)" onclick="show_projectinfo()">Info</a>
</li>
<li class="slider">
<img src="img/horizontal.jpg" alt="horizontal" width="624" height="429">
</li>
this is the script:
function show_projectinfo(){
$(this).closest('.slider img').hide();
$('.info_content').fadeIn();
}
The basic problem is that you are calling the method from onclick instead of binding it with jquery.
In the way you use it, the this refers to the window and not the element that was clicked.
function show_projectinfo(e){
e.preventDefault();
$(this).parent().next().find('img').hide();
$('.info_content').fadeIn();
}
$(function(){
$('.more_info').click(show_projectinfo);
});
and remove the onclick attribute from the html
If you have (although you shouldn't) to use the onclick attribute then pass it the this as an argument
function show_projectinfo(element){
$( element ).parent().next().find('img').hide();
$('.info_content').fadeIn();
}
and
<a class="more_info" href="javascript:void(0)" onclick="show_projectinfo(this)">Info</a>
Try:
$(this).parent().next() // parent() should be the <li> then next() will get your next <li>
$('.more_info').click(function(e){
e.preventDefault();
$(this).parent().next().find('img').hide();
$('.info_content').fadeIn();
});
Instead of .closest use .parent and .next, then select the img with .find.
Check out this jsFiddle:
$("a.more_info").bind("click", function(e){
e.preventDefault();
$(this).parent("li").next("li.slider").find("img").hide();
$('.info_content').fadeIn();
return false;
});
$('li').click( function (){
var nextLi = $(this).closest('div').next().children('li:first-child').attr('id');
console.log(nextLi);
});
Considering below markup:
<div id='div1'>
<li id='1'>1</li>
<li id='2'>2</li>
<li id='3'>3</li>
</div>
<div id='div2'>
<li id='4'>4</li>
<li id='5'>5</li>
<li id='6'>6</li>
</div>
You can see my live jsFiddle for more details.

duplicate functions, how may I combine them?

I have a function that remains pretty much constant except for the changing class names. I was hoping to make the code a little less text heavy. How may I go about making it just a small function instead of repeating it n times. My concern is also about removing the active class for the last li that was clicked. I've provided only 2 instances here, but this code is repeated n number of times.Any ideas would be much appreciated.
$('a.app1-preview').click(function() {
//remove last active classes
$(".app2").removeClass('active');
$(".app2-preview").removeClass('active');
//Add active class for this
$(this).parent().addClass('active');
$(this).addClass('active');
$('.app-preview-2').fadeOut("slow", function () {
$('.app-preview-1').fadeIn("slow");
});
});
$('a.app2-preview').click(function() {
//remove last active classes
$(".app1").removeClass('active');
$(".app1-preview").removeClass('active');
//Add active class for this
$(this).parent().addClass('active');
$(this).addClass('active');
$('.app-preview-1').fadeOut("slow", function () {
$('.app-preview-2').fadeIn("slow");
});
});
HTML code:
<div class="app-container">
<ul class="apps">
<li class="app1">
<a title href="#" class="app1-preview blocklink">
<span>ANOTHER<br /> APP</span>
</a>
</li>
<li class="app2">
<a title href="#" class="app2-preview blocklink">
<span>SECOND<br /> APP</span>
</a>
</li>
</div>
Try to exploit the fact that you have .active class. ;) Preview - http://jsfiddle.net/evSqF/1/
js:
<script>
$('a.blocklink').click(function() {
var self = $(this);
$('.active').fadeOut('slow', function(){
$(this).removeClass('active');
self.fadeIn('slow');
self.addClass('active');
});
});
</script>
html:
<div class="app-container">
<ul class="apps">
<li class="app1">
<a title href="#" class="app1-preview blocklink">
<span>ANOTHER<br /> APP</span>
</a>
<div class="app-preview active">App1 preview</div>
</li>
<li class="app2">
<a title href="#" class="app2-preview blocklink">
<span>SECOND<br /> APP</span>
</a>
<div class="app-preview">App2 preview</div>
</li>
</ul>
</div>
Edit: After I got some caffeine, I noticed the problems with the setup. I've created a demo at JSFiddle. The markup will display a "header" for an app which will display the child description when clicked on, and hide the descriptions of other sibling's descriptions.
In this case, you can show the current element, and hide the siblings, which would be a cleaner solution as it scales as you at more app elements.
$(".app").click(function() {
var $self = $(this);
var $apps = $self.closest(".apps");
var $selfSiblings = $apps.children(".app").not($self);
$self.addClass(".active");
$self.find(".app-preview").addClass("active");
$selfSiblings.removeClass(".active");
$selfSiblings.find(".app-preview").removeClass("active").fadeOut("slow", function() {
$self.find(".app-preview").fadeIn("slow");
});
});​
I would also recommend rewriting your HTML as such:
<div class="app-container">
<ul class="apps">
<li class="app">
App 1<br />
<a title href="#" class="app-preview blocklink">
<span>PREVIEW 1</span>
</a>
</li>
<li class="app">
App 2<br />
<a title href="#" class="app-preview blocklink">
<span>PREVIEW 2</span>
</a>
</li>
<li class="app">
App 3<br />
<a title href="#" class="app-preview blocklink">
<span>PREVIEW 3</span>
</a>
</li>
</div>​
Write a function to make the functions for you:
function makeHandler(deactivate, fadeOut, fadeIn) {
return function() {
//remove last active classes
$(deactivate).removeClass('active');
//Add active class for this
$(this).parent().addClass('active');
$(this).addClass('active');
$(fadeOut).fadeOut("slow", function () {
$(fadeIn).fadeIn("slow");
});
});
Then:
$('a.app1-preview').click(makeHandler('.app2, .app2-preview', '.app-preview-2', '.app-preview-1'));
$('a.app2-preview').click(makeHandler('.app1, .app1-preview', '.app-preview-1', '.app-preview-2'));
You could probably simplify things further by re-thinking the naming conventions you've got.
I would suggest to define a single function:
function single(index_main, index_aux) {
// Does all your magic
}
$('a.app1-preview').click(function() {
single("1", "2");
});
$('a.app2-preview').click(function() {
single("2", "1");
});
And that does the trick.
I made a jsfiddle example for you. Have a look at it here, it uses as much code that you wrote as possible, so nothing that should surprise you will be there :)
http://jsfiddle.net/2ZPxx/
Basically I ended up with this HTML:
<div class="app-container">
<ul class="apps">
<li class="app1">
<a title href="#" class="app1-preview blocklink" id="app1">
<span>ANOTHER<br /> APP</span>
</a>
</li>
<li class="app2">
<a title href="#" class="app2-preview blocklink" id="app2">
<span>SECOND<br /> APP</span>
</a>
</li>
</div>
<div class="app-preview-app1 app-preview">App1 preview</div>
<div class="app-preview-app2 app-preview">App2 preview</div>
And this javascript:
$('.apps li a').click(function() {
var id = $(this).attr('id');
$('.apps li').removeClass('active');
//Add active class for this
$(this).parent().addClass('active');
$(this).addClass('active');
$('.app-preview').fadeOut("slow", function () {
$('.app-preview-'+id).fadeIn("slow");
});
});

Categories