Show a different image (bigger version) on mouse hover - javascript

I want to load a different image (A bigger version) of existing one when mouse is hovered over that image. So I place all the images through AJAX call
<main class="container">
<ul class="gallery">
</ul>
</main>
success: function (data) {
$.each(data, function (index, element) {
$(".gallery").append($(`<img src="${`images/square/${element.path}`}"
alt="${element.title}"id="${element.path}"city="${element.city}"
taken="${element.taken}"/>`));
});
},
Now I want to load a bigger image (from local disk) of existing image when mouse is hovered and show that image over it (kind of zoom in, but not zoom in over the image but load a bigger image, and append the div to body) in the body.
I've tried many different versions of this
(".gallery").mouseenter(function(){
$(this).css("gray");
$(this).append('<div id="preview"');
// console.log($(this).attributes);
// $(this).append($(`<img src="${`images/medium/"${$(this).attr('id')}"`}"
// alt="${$(this).attr('title')}"/>`
// ));
$(this).append('</div>')
})
I am unable to access the attributes dynamically. this. attribute remains return undefined. Something seems off here. Can you please tell, how to go about it ?

You are getting attribute of .gallery which doesn't have any id or alt your img tag has that so use .find() to get that particular image where user hover and then get attributes using .attr('yourattributename').
Demo Code :
$(document).on('mouseenter', '.gallery li', function() {
var imgs = "<div id=preview><img src=images/medium/" + $(this).find('img').attr('id') + " alt=" + $(this).find('img').attr('alt') + "></div>";
$(this).append(imgs)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main class="container">
<ul class="gallery">
<li><img src="images/square/${element.path}" alt="Soemehing" id="Soemehingdd" city="${element.city}" taken="${element.taken}" />
</li>
<li><img src="images/square/${element.path}" alt="Soemehing2" id="Soemehingdd2" city="${element.city}" taken="${element.taken}" />
</li>
</ul>
</main>

Use arrow function instead of normal fucntion.
Arrow functions do not bind their own this, instead, they inherit the one from the parent scope, which is called "lexical scoping".
(".gallery").mouseenter(() => {
$(this).css("gray");
$(this).append('<div id="preview"');
// console.log($(this).attributes);
// $(this).append($(`<img src="${`images/medium/"${$(this).attr('id')}"`}"
// alt="${$(this).attr('title')}"/>`
// ));
$(this).append('</div>')
})

Related

lazy loading images on scroll and "come into view"

I am using Lazy as a lazy image loading plugin. I have a div where I load divs like this:
<div class="nano-content" id="lScroll">
/*... MORE LIKE THIS ... */
<div class="card">
<div class="city-selected city-medium clickChampion pointer"
data-champ-id="1">
<article>
<div class="info">
<div class="city">
CHAMPNAME
</div>
</div>
</article>
<figure class="cFigure lazy" data-src="images/champions/CHAMPNAME_0.png"></figure>
</div>
</div>
/*... MORE LIKE THIS ... */
</div>
So I initiate the plugin and it works for the first ones visible and when I scroll:
var $lazy = $('#lScroll .lazy');
if ($lazy.length) {
$lazy.Lazy({
appendScroll: $('#lScroll')
});
}
But now I have a function that "filters" the divs by their attributes when I enter sth in my search input and it fails to load the image when the according div is shown:
$(document).on("keyup", "#searchVod", function () {
var $search = $(this);
var $sVal = $search.val().toLowerCase();
if ($sVal !== "") {
$(".vodCard").hide();
$('[data-champ*="' + $sVal + '"]').show();
$('[data-role*="' + $sVal + '"]').show();
} else {
$(".vodCard").show();
}
});
I tried bind: "event" /w and w/out delay: 0 (loading the plugin in the search function) but when I searched it would load ALL images immediately in the background.
Any hint highly appreciated
UPDATE: I just noticed in Chrome DevTab after entering one letter in my searchbox it loads ALL the images and eventually the one I am searching for (if its the last it takes some time (30MB sth)
There is an excellent library called Lozad.js which can help you to make it easier to load your images like lazy load do but in easier way.
You can download it here from Github.
Demo page here.
Explanation:
This library will load your images one by one on scrolling to each image anchor by class name.
Example
HTML:
At the header ->
<script src="https://cdn.jsdelivr.net/npm/lozad"></script>
Image element should looks like this:
<img class="lozad" data-src="image.png">
Javascript
// Initialize library
lozad('.lozad', {
load: function(el) {
el.src = el.dataset.src;
el.onload = function() {
el.classList.add('fade')
}
}
}).observe()
Hope it will help you.
Best,
Ido.

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 hover-based popup events for every product in list

I have a little problem with a function in jquery. I need to display a pop-up every time that a user is hover a Product. My products are in a list, and I would like to have a pop-up specified to every product in order to display it's title and description :
This is the List of Products (displayed in a thumbnail)
<!-- This Div contains the List of Products -->
<ul class="thumbnails">
#foreach (var thumbnail in Model.ForfaitsInThumbNail)
{
<div class="thumbnail">
<img src= "#Url.Action("GetById", "ImageForfait", new { idForfait = thumbnail.Forfait.Id })" alt=""/>
<div class="caption">
<h2 class="fontTitle">#thumbnail.Forfait.Titre</h2> <h5 class="fontYearHijri"> pour l'année #thumbnail.Forfait.AnneeHijri H </h5>
.......
</div>
<!-- This div should contain the pop-up for every Product -->
<div class='pop-up' id='pop-up'> <h3>"#thumbnail.Forfait.Titre"</h3><p>"#thumbnail.Forfait.Description"</p></div>
</div>
</div>
}
</ul>
This is my poor jquery function wich only works with one Product and not all of them in a list
<script>
$('.thumbnail').each(function() {
$(this).hover(function (e) {
$('.pop-up').show()
.css('top', e.pageY + 20)
.css('left', e.pageX + 10)
.appendTo('body');
}, function () {
$('.pop-up').hide();
});
});
$('.thumbnail').each(function() {
$('.thumbnail').mousemove(function(e) {
$(".pop-up").css('top', e.pageY + 20).css('left', e.pageX + 10);
});
});
This function has no errors, but it displays only the pop-up of the last Product, and that seems logic because it can't identify the div of the specified Product. So my question is, how can I implement this functionnality like I want to be (special pop-up for every Product)? Any Ideas ? Thank You :)
I've update this answer by constructing a fiddle to show a working solution. In future, could you please provide a Fiddle where possible, as it saves us all a lot of time having to construct one for ourselves.
Here is my JavaScript:
// Note, this is important
$(document).ready(function () {
// We don't need an each, and include the e event handler
$('.thumbnail').hover(function (e) {
$('#pop-up').show()
.css('top', e.pageY + 20)
.css('left', e.pageX + 10)
.appendTo('body');
}, function () {
$('#pop-up').hide();
});
$('.thumbnail').mousemove(function (e) {
$("#pop-up").css('top', e.pageY + 20).css('left', e.pageX + 10);
});
});
Things you should also note: You don't need to have both an ID #pop-up and a class .popup on the same element, unless this is some special pop-up which inherits from the standard pop-up class. It looks like your ID/Class usage might be off, so just make sure that you're using IDs whenever something is unique, and classes when you have multiple instances.
Couple of fixes I made:
Always wrap your jQuery in a $(document).ready() method, this will ensure that your DOM is fully loaded before the events are applied
You forgot to include an event handler on your hover function, though I think you've updated your question with this included.
You forget to pass event object parameter on hover event
//do this
...
$(this).hover(e){
--
}
...
Hope this should work.
If you notice you used (e.pageX) so where does (e) come from. It has to be passed as a parameter.

blocking specific links with jquery

In a gallery I want to block certain thumbnails from expanding their original picture via lightbox.
The images don't have an ID, just a class. All of the links are read from a table in a database.
$(document).ready(function(){
if($('.product-image').attr('target', 'blockedpath')) {
$('.product-image').click(function(e) {
e.preventDefault();
return false;
});
}
});
<li class="product">
<div class="productInfo">
<h3>#i.ToString()</h3>
<a href="#Href("~/Images/2013/" + i.ToString() + ".jpg")" rel="lightbox" class="link">
<img class="product-image" src="#Href("~/Images/2013/Thumbnails/" + i.ToString() + ".jpg")" alt="foto" />
</a>
</div>
</li>
If I use this, all thumbnails get blocked. How can I prevent just the blocked pictures and avoid blocking the thumbnails.
Would it be possible, to save all images which should be blocked in an array and loop through that array to block those thumbnails?
You are first checking whether any images exist with target = blockedpath, then blocking all images.
You could use something like this:
$(document).ready(function(){
// Select elements with the product-images class, that also
// have a target attribute with a value equal to 'blockedpath'
// Bind a click event to the matched elements
$('.product-image[target="blockedpath"]').click(function(event) {
event.preventDefault();
return false;
});
});
$('[target=blockedpath]').click(function( e ){
e.preventDeault();
});
or the opposite:
$('.product-image').not('[target=blockedpath]').click(function(){
alert('hi!');
});
http://api.jquery.com/event.preventDefault/

deactivate ONE button/thumb of a list

I have a video array, and then a list of thumbs that correspond to the array. When you click on one of the buttons, it needs to be deactivated for the duration of the video. I have it so that after the first click, it deactivates the whole list
$('li', '.thumbs').on('touchend click', function() {
$("#myVid").on("loadeddata", function() {
$("#bigPic").addClass("move");
$("#MyT").fadeOut(750);
});
playVideo2( $(this).index() );
$('li', '.thumbs').unbind();
});
if each item in the list is set up like this:
<li rel='1' id="first">
<div style="top:0px;">
<img src="graphics/filler.png" alt="" width="280" height="128" />
</div>
</li>
with the id being different for each, can I just put the id instead of the .thumbs, and just have it unbind or turn off itself? I know this must be inefficient, but I'm not sure how else to do it. Do I use this() somehow? If so, how?
You could make use of a global variable to check which video is playing.
//init
var currentlyPlaying = undefined;
Within your event handling part you set this variable to the ID of the clicked button.
currentlyPlaying = $(this).attr('id');
With that setup you can check the variable before doing anything in your script.
if ( !(currentlyPlaying == $(this).attr('id')) ) {
// your script
}
Alternatively, you can use the ID to unbind as you suggested, of course.
$('li', '.thumbs #' + $(this).attr('id')).unbind();

Categories

Resources