Revert to original image after jquery hover better way? - javascript

to replace images on hover i have used jquery:
<script type='text/javascript'>
$(document).ready(function(){
var blog1 = $(".blogimage1").attr('src');
$(".imghover").hover(function() {
$(this).attr("src","images/imghover.png");
}, function() {
$(this).attr("src",blog1);
});
});
</script>
here is the html:
<a href="blog-inner.html" title="read more">
<img src="images/blogpost4.jpg" alt="blog post title" class="img-responsive imghover blogimage1">
</a>
and it works exactly like i want it to, however i dont know how many blog images there will be so for now i would have to add in blogimage1, blogImage2, etc into the html and do the same with jquery. is there a way i can do this without having to store each original blog image and write the same function a million times?

Try this : You can save previous image in blog1 variable when mouse hover and replace it back when mouse leave.
$(document).ready(function(){
var blog1 = '';
$(".imghover").hover(function() {
//save previous image in variable
blog1 = $(this).attr('src');
$(this).attr("src","images/imghover.png");
}, function() {
$(this).attr("src",blog1);
});
});

Use .data() to store original image path.
Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.
code
$(".imghover").hover(function() {
$(this).data('orgimage', this.src); //Store data
this.src = "images/imghover.png";
}, function() {
this.src = $(this).data('orgimage'); //Retrieve and set original image path
});

Related

Using an attribute value to add custom links for each images in my wordpres gallery

I'm using Elementor Pro for my photography website and i want to set custom links for each image in the gallery. By default, i can only set a global link which is the same for each image so that's not great.
In fact, i want to set a custom link which will redirect the user to the shop page of the specific image.
I found some code online (thanks to elementhow !) and it's really close to what i want, but i still need to change some things. The thing is a have to manually write all the links in an array and it's not convenient (close to 100 files and growing, if i change the order, i have to reorder the links, etc).
Here's the code i currently use :
<style>.e-gallery-item{cursor: pointer;} </style>
<script>
document.addEventListener('DOMContentLoaded', function () {
var filteredImages = document.querySelectorAll('.e-gallery-item');
//Edit the links HERE
var links = [
'https://www.mywebsiteurl.com/product/product-name1/',
'https://www.mywebsiteurl.com/product/product-name2/',
'https://www.mywebsiteurl.com/product/product-name3/',
'https://www.mywebsiteurl.com/product/product-name4/',
];
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function () {
location = links[i];
});
};
for (var i = 0; i < filteredImages.length; i++) {
_loope(i);
}
});
</script>
I would like to use an attribute value in the algorithm to generate the link automatically for each image. I have the process in my mind, but i don't know how to code this...
Here's the code of one image ,i can set what value i want in "alt".
<div class="e-gallery-image elementor-gallery-item__image e-gallery-image-loaded" data-thumbnail="......" data-width="1024" data-height="768" alt="product-name";"></div>
I would like to use the "alt" attribute to create a unique url for each file, with this format :
'https://www......com/product/product-name/'
"product-name' will take the value of the "alt" attribute of each image.
I tried to change this part of the code (replace "links[i]" by trying to get the attribute value using filteredImages[i].getAttributes) but without success...
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function () {
location = links[i];
});
};
Can someone give me some tips about how to do that ? I spend 2 years without coding so i'm a bit rusty...
I think this does what you'd like it to, as you have already done you can cycle through each image link using a class.
You can get the value of alt using the .attr() function and then replace the href value of the link.
DEMO
// Cycle through each image using common class
$(".e-gallery-image").each( function() {
// Get value of 'alt' for clicked item
alt = $(this).attr("alt");
// Update href value
$(this).attr("href", "https://www.mywebsiteurl.com/product/" + alt );
});
// Prove that its worked
$(".e-gallery-image").click( function() {
// Confirm all is correct
console.log($(this).attr("href"));
// Assign url to window
location.href = $(this).attr("href");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="e-gallery-image" href="test.com" alt="product1">Product 1</div>
<div class="e-gallery-image" href="test.com" alt="product2">Product 2</div>
<div class="e-gallery-image" href="test.com" alt="product3">Product 3</div>
<div class="e-gallery-image" href="test.com" alt="product4">Product 4</div>
<div class="e-gallery-image" href="test.com" alt="product5">Product 5</div>
In fact it was really simple. I tried to target a parent element and it worked ! If anyone is interested, here's the code i use :
document.addEventListener('DOMContentLoaded', function () {
var filteredImages = document.querySelectorAll('YOUR_SELECTOR');
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function() {
location = "YOUR_WEBSITE_URL" + filteredImages[i].querySelector("YOUR_SELECTOR").getAttribute("alt");
});
};
for (var i = 0; i < filteredImages.length; i++) {
_loope(i);
}
});

How to switch the src attribute of the img element back into jquery?

I created a script that changes an image when you click a button. The problem is with clicking again, because the src attribute remains the same. I would like after clicking again the source of the photo to go back to the initial src. I tried to do it using toggle method, but with positive effect.
My code:
$(document).ready(function(){
$('#button').click(function(){
$('.logo').attr('src', 'http://domena.com/logo-1.jpg');
});
});
I tried to solve it that way, but I failed.
$(document).ready(function(){
$('#button').click(function(){
$('.logo').toggle(
function() {
$(this).attr('src', 'http://domena.com/logo-1.jpg');
},
function(){
$(this).attr('src', 'http://domena.com/logo-2.jpg');
}
);
});
});
You can pass the URL of new image in an attribute of <img>, then you can get the current image ie src and next image(data-new) and interchange their values, like so -
$(document).ready(function(){
$('#button').click(function(){
let curr_img = $('.logo').attr('src'); // get current image
let new_img = $('.logo').attr('data-new'); // get new image to be shown
$('.logo').attr({'src': new_img, 'data-new': curr_img}); // interchange their values
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- give next values as an attribute ie data-new here-->
<img src="https://w7.pngwing.com/pngs/247/564/png-transparent-computer-icons-user-profile-user-avatar-blue-heroes-electric-blue.png" class="logo" data-new="https://image.flaticon.com/icons/svg/21/21104.svg" style="width: 150px; height: 150px;">
<br>
<button id="button">Toggle image</button>
Hope it helps you.

Mouseover image stays the same

I have a problem with this code
I'll explain a little how this works,
The idea of this is that when hovering in tag (a), change the image of the id="meal", by the one that is in the (data-meal = "meal-14") .. in a few words
The pre-determined image is meal-0.png, hover in tag (a) with (data-meal = 14), replaces the url of the image with (meal-14.png),
Everything works fine, I only have one problem and is that when you stop hovering, do not go back to the pre-determined image, it stays in the image that became hover. Should return to the image meal-0.png.
<div class="imagen-hover" id="meal">
<img src="/public/tienda/meal-0.png" alt="">
</div>
<ul>
<li><a class="carne-a" data-meal="meal-14">14. Punta de Anca</a></li>
<li><a class="carne-a" data-meal="meal-16">16. Chata Angosta</a></li>
</ul>
jQuery(document).ready(function($) {
var path = "/public/images/";
$(".meal-a").on("mouseover", function() {
var meal = $(this).attr("data-meal") + ".png";
$("#meal img").attr("src", path + meal)
});
});
that is because it is doing exactly what you told it to do.
you need to make another event handler for mouseleave
or you can look at the jQuery docs , mouseenter can take two call backs , one for entering and one for leaving
$(".meal-a").mouseenter( function() {
var meal = $(this).attr("data-meal") + ".png";
$("#meal img").attr("src", path + meal)
}).mouseleave( function() { //for when mouse leaves
});
What I would recommend though... you do not need javascript or jQuery at all for this , there is a css selector for while the user is hovering over an element
.meal-a{ // regular code
}
.meal-a:hover{ // hover code
}
Also add a "mouseout" function to handle returning the image to its previous value
$(".meal-a").on("mouseout", function() {
$("#meal img").attr("src", "meal-0.png")
});

jQuery Lightbox gallery only working once

I am trying to build my own simple jQuery lightbox gallery. My logic behind it is as follows: Only thumbnails will be shown & created at first. These link to the full size images.
<section class="gallery-set">
<a href="img/about/gallery/a1.1.jpg">
<img src="img/about/gallery/thumb1.1.jpg" alt=""
height="192" width="383">
</a>
<a href="img/about/gallery/a1.jpg">
<img src="img/about/gallery/thumb1.jpg" alt=""
height="192" width="383">
</a>
<a href="img/about/gallery/a2.1.jpg">
<img src="img/about/gallery/thumb2.1.jpg" alt=""
height="192" width="383">
</a>
</section>
Therefore, when you click on any of these thumbnails, I dynamically create an overlay-lightbox and all full size images, showing only the one that links to the thumbnail you clicked. Although the rest of the images has been created too, these are hidden for now.
function lightBox() {
var gallery = $('.gallery-set'),
overlay = $('<div/>', {id: 'overlay'});
overlay.appendTo('body').hide();
gallery.on('click', 'a', function(event) {
event.preventDefault();
var clickedThumb = $(this),
clickedThumbPath = $(this).attr('href'),
clickedImg = $('<img>', {src: clickedThumbPath, alt: 'fullSizeImage', class: 'current'}),
prevThumbs = clickedThumb.prevAll(),
nextThumbs = clickedThumb.nextAll();
prevThumbs.each(function() {
var prevImg = $('<img>', {src: $(this).attr('href'), class: 'prev non-current'});
prevImg.appendTo(overlay);
});
clickedImg.appendTo(overlay);
nextThumbs.each(function() {
var nextImg = $('<img>', {src: $(this).attr('href'), class: 'next non-current'});
nextImg.appendTo(overlay);
});
overlay.show();
})
.....
.....
}
Now, when you click the second thumbnail, jQuery dynamically creates all the fullsize images and this is how HTML structure looks like:
Now that I have this structure, I can easily traverse the full sized images by left and right arrows. The current image gets hidden and the next one gets shown. For this logic I am using two classes, current and non-current where the first one has set display to block and the second one to none. This piece of code is within the lightbox() function:
$(document).on('keyup', function(event) {
var pressed = event.keyCode || event.which,
arrow = {left: 37, right: 39};
switch(pressed) {
case arrow.left:
var curr = overlay.find('.current'),
prev = curr.prev();
if(curr.hasClass('current')) {
curr.removeClass('current').addClass('non-current');
} else {
curr.addClass('non-current');
}
if(prev.hasClass('non-current')) {
prev.removeClass('non-current').addClass('current');
} else {
prev.addClass('current');
}
break;
case arrow.right:
var curr = overlay.find('.current'),
next = curr.next();
curr.removeClass('current').addClass('non-current');
next.removeClass('non-current').addClass('current');
break;
}
});
overlay.on('click', function() {
overlay.hide();
overlay.find('img').remove();
});
});
Everything works fine the first time. However, once I close the lightbox and try to open it again, the correct image opens but the arrows functionality is gone. I do not understand why - since I am dynamically creating the full sized images everytime user clicks on the gallery and putting event listeners (arrows) only once these have been created.
Just for the record, I am calling this lightbox() function from the HTML file right before the closing tag.
Any ideas much appreciated. Also, if there's a simpler / better way of doing this, please do let me know! I don't want to use any plugin as I think this is pretty simple and straightforward. Or, I thought it WOULD BE SIMPLE I should rather say.

how to repeat same Javascript code over multiple html elements

Note: Changed code so that images and texts are links.
Basically, I have 3 pictures all with the same class, different ID. I have a javascript code which I want to apply to all three pictures, except, the code needs to be SLIGHTLY different depending on the picture. Here is the html:
<div class=column1of4>
<img src="images/actual.jpg" id="first">
<div id="firsttext" class="spanlink"><p>lots of text</p></div>
</div>
<div class=column1of4>
<img src="images/fake.jpg" id="second">
<div id="moretext" class="spanlink"><p>more text</p></div>
</div>
<div class=column1of4>
<img src="images/real.jpg" id="eighth">
<div id="evenmoretext" class="spanlink"><p>even more text</p></div>
</div>
Here is the Javascript for the id="firsttext":
$('#firstextt').hide();
$('#first, #firsttext').hover(function(){
//in
$('#firsttext').show();
},function(){
//out
$('#firsttext').hide();
});
So when a user hovers over #first, #firsttext will appear. Then, I want it so that when a user hovers over #second, #moretext should appear, etc.
I've done programming in Python, I created a sudo code and basically it is this.
text = [#firsttext, #moretext, #evenmoretext]
picture = [#first, #second, #eighth]
for number in range.len(text) //over here, basically find out how many elements are in text
$('text[number]').hide();
$('text[number], picture[number]').hover(function(){
//in
$('text[number]').show();
},function(){
//out
$('text[number]').hide();
});
The syntax is probably way off, but that's just the sudo code. Can anyone help me make the actual Javascript code for it?
try this
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink").show();
});
Why not
$('.spanlink').hide();
$('.column1of4').hover(
function() {
// in
$(this).children('.spanlink').show();
},
function() {
// out
$(this).children('.spanlink').hide();
}
);
It doesn't even need the ids.
You can do it :
$('.column1of4').click(function(){
$(this); // the current object
$(this).children('img'); // img in the current object
});
or a loop :
$('.column1of4').each(function(){
...
});
Dont use Id as $('#id') for multiple events, use a .class or an [attribute] do this.
If you're using jQuery, this is quite easy to accomplish:
$('.column1of4 .spanlink').hide();
$('.column1of4 img').mouseenter(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').show();
});
$('.column1of4 img').mouseleave(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').hide();
});
Depending on your markup structure, you could use DOM traversing functions like .filter(), .find(), .next() to get to your selected node.
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink, img").show();
});
So, the way you would do this, given your html would look like:
$('.column1of4').on('mouseenter mouseleave', 'img, .spanlink', function(ev) {
$(ev.delegateTarget).find('.spanlink').toggle(ev.type === 'mouseenter');
}).find('.spanlink').hide();
But building on what you have:
var text = ['#firsttext', '#moretext', '#evenmoretext'];
var picture = ['#first', '#second', '#third'];
This is a traditional loop using a closure (it's better to define the function outside of the loop, but I'm going to leave it there for this):
// You could also do var length = text.length and replace the "3"
for ( var i = 0; i < 3; ++i ) {
// create a closure so that i isn't incremented when the event happens.
(function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(',')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
})(i);
}
And the following is using $.each to iterate over the group.
$.each(text, function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(', ')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
});
Here's a fiddle with all three versions. Just uncomment the one you want to test and give it a go.
I moved the image inside the div and used this code, a working example:
$('.column1of4').each(function(){
$('div', $(this)).each(function(){
$(this).hover(
function(){
//in
$('img', $(this)).show();
},
function(){
//out
$('img', $(this)).hide();
});
});
});
The general idea is 1) use a selector that isn't an ID so I can iterate over several elements without worrying if future elements will be added later 2) locate the div to hide/show based on location relational to $(this) (will only work if you repeat this structure in your markup) 3) move the image tag inside the div (if you don't, then the hover gets a little spazzy because the positioned is changed when the image is shown, therefore affecting whether the cursor is inside the div or not.
EDIT
Updated fiddle for additional requirements (see comments).

Categories

Resources