How to make a grid of interactive elements? - javascript

I'm trying to create a portfolio website that resembles this, a full-page grid of images that change when you hover over them... (another example, the third screen!)
And currently I have a crude solution that looks like:
<img src="1.png" id="img" swap="2.png"/>
// then in JS...
$("#img").hover(function(){
var _this = $(this);
var current = _this.attr("src");
var swap = _this.attr("swap");
_this.attr('src',swap).attr('swap',current);
}); //
code credit
But this isn't a very scaleable solution and other than having 1000 images, each with their own unique ID which is identified so the src can be toggled, I'm not sure what to do -- plus I don't know how this would react to different display sizes/screen cut-offs. And while background-image in CSS tiles nicely, it doesn't allow interactivity... unless maybe you had a JS script track cursor position(?)
!! This is my very first project, any help would be appreciated :) (Codecademy is a very sheltered learning environment........)

you don't have to use ids and create a handler for every image.
this will apply to every image CURRENTLY on the page:
$("img").hover(function(){
var _this = $(this);
var current = _this.attr("src");
var swap = _this.attr("swap");
_this.attr('src',swap).attr('swap',current);
});
and this will react to every image, even images added after the page is loaded:
$(document).on('hover', 'img', function () {
var _this = $(this);
var current = _this.attr("src");
var swap = _this.attr("swap");
_this.attr('src',swap).attr('swap',current);
});
To account for screen sizes and your other concerns, you'd need to either set a fixed width and height on your images, or make sure all your images are of similar resolution.
You could do this with backgrounds as well by creating a grid of divs then change the background of the div on hover, similar to the above handlers.

Related

Change Another Image On Link Hover

The output in HTML is something like this:
ProductImage1 ProductImage2 ProductImage3 ProductImage4
Color1 Color2 Color3 Color2 Color4 Color5 Color6
What I want to do is when I hover my mouse over any color above, an original (current) image of ProductImage will change to another one (to match the hovered color). And that original image will be back when mouse leaves.
Here is the javascript I've done for hovering over each ProductImage.
var sourceSwap = function () {
var $this = $(this);
var newSource = $this.data('alt-src');
$this.data('alt-src', $this.attr('src'));
$this.attr('src', newSource);
}
$(function () {
$('img.main').hover(sourceSwap, sourceSwap);
});
UPDATE
I excluded unnecessary parts from my question. The answer from #hunter worked very well when I tested it here jsfiddle.net/4dK2x/27. However it didn't work when I combined it with my php parts to create dynamic lists. I'm still looking around and trying to find out the problems. I will come back and update my answer if I find a solution for it.
Here's updated code which should work with as many sets of products as you need if you mimic a similar html structure
$('.image .toggles img').hover(function () {
var src = $(this).attr("src");
var $main = $(this).closest(".image").find(".main");
$main.attr("toggle", $main.attr("src")).attr("src", src);
},
function () {
var $main = $(this).closest(".image").find(".main");
$main.attr("src", $main.attr("toggle"));
});
Example: http://jsfiddle.net/4dK2x/1/
You could do this two ways, you can try it by using CSS:
#tagName{
background: url("yourImage.jpg");
}
#tagName:hover{
background: url("anotherImage.jpg");
}
this assumes you have a div tag around the image, you can also reference class id's etc. (read into CSS for more details).
or you could do it through JavaScript
lets say you are not using JQuery (i need to familiarize myself more with JQuery)
var image1 = document.getElementById("nameofDivTag");
//on hovering kinda forgotten the JS version of hovering, JQuery has probably easier way
image1.style.background("url:("aDifferentImage.jpg"));
if i am wrong yay! if not yay!
hope it helps

Why does my js function only find the first image?

I am writing a function that uses pxLoader to load images in a set of thumbs. When they are loaded it hides the loader and fades the image in. Here is the markup:
<div style="margin-bottom:1px;" class="rsNavItem rsThumb front">
<div class="rsTmb portfolio">
<img class="the-image" src="<!-- image loaded from cms -->">
<div class="image-loader"></div>
</div>
</div>
Then here is my js function for it:
loadThumbs: function () {
var app = this;
$('.rsThumb').each( function () {
var $mainHolder = $(this).find('.rsTmb');
var $mainImage = $mainHolder.find('img');
console.log($mainImage);
$mainImage.addClass('the-image');
$mainImage.parent().append('<div class="image-loader"></div>');
var $mainImageSrc = $mainImage.attr('src');
// //
// Load the thumbs //
// ------------------------------------------------- //
var pxLoader = new PxLoader();
var pxImage = pxLoader.addImage($mainImageSrc);
pxLoader.addCompletionListener(function () {
$('.image-loader').hide();
$('.the-image', $mainHolder)
.attr('src', $mainImageSrc) // Update the image source
.transition({ // Fade the image in
opacity: 1
}, 300);
});
pxLoader.start();
});
}
For some reason when iterating over the images to replace the image when its finished it finds the first one and loads that into all of the divs. In my console I get all the images etc but no joy with the urls being different, they are all the same as the first one.
It might be me thats being stupid but I have tried allsorts of things.
Cheers
I have some questions about your code:
Firstly, there is something i don't understand: you are retrieving your image src attribute (var $mainImageSrc = $mainImage.attr('src');) then in the completion listener your are replacing its value with the same one $('.the-image', $mainHolder).attr('src', $mainImageSrc). Is there a reason ?
Another thing is about this instruction .transition({ opacity: 1 }, 300);. Is it a pxLoader function or are you using another jquery plugin to do this, cause i am not aware about a transition() function in jQuery. You can use the fadeIn() function available in jQuery.
Please tell me if i misunterstood, but you want to show something like loading spinners while images are loading (from your cms) like in this jsFiddle (clear your browser cache if you run it multiple times), no ?
This code seems to work so could you give us more context ? How/When are you calling your loadThumbs() function ? Do you have a test-case url or could you set up a jsFiddle ?

jQuery select images above the fold

I am currently using the jQuery lazyload plugin to load images. I am using javascript to replace the src and data-original attributes. This causes a slight flicker on load. I am wondering if there is a way with jquery to select only the images below the fold or above the fold so that I can avoid this flicker.
var $imgs = $("img:not(.nolazy)");
$imgs.each( function(){
var imgSrc = $(this).attr("src");
$(this).attr("data-original",imgSrc).attr("src","gray.gif");
});
$imgs.lazyload({
effect : "fadeIn"
});
Edit: #Jason Sperske great answer. This is the code that I have resolved the flickering issue with:
var wH = $(window).height();
var $imgs = $("img:not(.nolazy)");
$imgs.each( function(){
var imgPosition = $(this).offset();
if(imgPosition.top > wH){
var imgSrc = $(this).attr("src");
$(this).attr("data-original",imgSrc).attr("src","gray.gif");
}
});
$imgs.lazyload({
effect : "fadeIn"
});
While there is no built in selector for this purpose you could iterate over them and look for position values that are greater than the window height. Ben Pickles (his SO profile) has implemented this into a filter called onScreen which you can use like a selector (note that it will still fetch all elements, but then pair down the list before you attempt to modify them, so the selector won't be any faster (actually slightly slower), but the reduced set of elements will be faster to update).

Multiple, unique, popup windows with JPopUp script?

I know this has probably been answered multiple times before, but this is the second time I've worked with JQuery, and I'm not entirely sure what I need to do, since I'm not familiar with this format of coding. I've looked at other, similar, questions, but none of the answers are making sense to me, and I really need this to click in my head so I can keep working.
I'm using Jpopup for this, so the script info is all there, but my question is this:
I have two areas in an image that I need to be clickable, both showing different content, but I can only call one page at a time to pop up, and multiple anchor tags just give me the same content twice. What do I need to add to that script to allow the page to show two different popups?
This is the script in my HTML page
<script language="javascript">
$(document).ready(function() {
//Change these values to style your modal popup
var source = "demo.html";
var width = 920;
var align = "center";
var top = 100;
var padding = 10;
var backgroundColor = "#FFFFFF";
var source = 'popups/demo.html';
var borderColor = "#000000";
var borderWeight = 4;
var borderRadius = 5;
var fadeOutTime = 300;
var disableColor = "#666666";
var disableOpacity = 40;
var loadingImage = "popups/loading.gif";
//This method initialises the modal popup
$(".modal").click(function() {
modalPopup( align,
top,
width,
padding,
disableColor,
disableOpacity,
backgroundColor,
borderColor,
borderWeight,
borderRadius,
fadeOutTime,
source,
loadingImage );
});
//This method hides the popup when the escape key is pressed
$(document).keyup(function(e) {
if (e.keyCode == 27) {
closePopup(fadeOutTime);
}
});
});
</script>
The HTML
<div style="margin-top:200px;margin-left:395px;">
<a class="modal" href="javascript:void(0);"><img src="images/clickmelarge.png" border="0">
</a></div>
I studied the source code of the "plugin" and studied also the invoked source code of the HTML page at runtime. In my eyes this popup plugin doesn't support multiple popups at same time. Why?
Well, I used Firebug to exermine the source code at runtime and I saw only the same divs, added to the DOM tree by this. As far as I did understand when the DOM was complete loaded the author added the main divs to the DOM tree and set they all to 'hide'. If you call your function these divs will set to 'visible'.
Another reason is -in my eyes a very tricky way- the div with the Id 'blockModalPopupDiv' covers the full browser window. If you click on this element, the function of hiding all divs will be executed. You won't be have chance to click outside the div element.
So what can you do?
I think you have only three options :
Ask the author for an opportuniti to add your requirement.
Download the source code and modifiy it your self. Its created in standard Javascript.
Try to use another plugin or change your concept.

Rendering custom photo set using tumblr JSON

I am creating this custom theme www.designislikethis.tumblr.com, which uses the jQuery Masonry and the Slider plugins. In creating this theme I wanted to create my own photoset slideshow instead of messing around with the default Flash-based one.
I started by pulling the images from the JSON of each photoset post by the post's ID using JS and jQuery.
I then rendered these images onto my frontpage in a special div that is linked to a minimal jQuery slideshow plugin, so each image fades in and out.
The code I use to pull/render for each photoset post is as follows:
function photoSet() {
$('.photoset').each(function () {
var postID = $(this).attr('id');
var that = $(this);
$.getJSON("http://designislikethis.tumblr.com/api/read/json?id="+postID+"&callback=?",
function(data) {
var postPhotos = data["posts"][0]["photos"];
var postPermalink = data["posts"][0];
for(var i = 0; i<postPhotos.length; i++)
{
var photo250 = new Image();
photo250.src = postPhotos[i]['photo-url-250'];
postLink = postPermalink["url-with-slug"];
var setClass = ".photoset"+ i;
var imgClass = ".img"+ i;
$(that).find('.slide').append('<a class="'+ setClass +'" href="'+postLink+'"><img class="'+ imgClass +'" src="' +photo250.src+ '"/></a>');
}
});
});
}
Now my problem lies in that all the other elements on my tumblr index page are not rendered with JSON, so they load faster. By the time my photo set renders it's divs are unproportional to everything that has loaded around it, and so the image slider wont kick in and you are left with a mess of rendered images.
What's most annoying about this problem is that some times it works fine, and others it's a mess, depending on how fast the page loads, or if you have the website already cached in your browser.
To see the extent of my Javascript and how I am calling this photoset funciton see here:
http://helloauan.com/apps/DILTtheme/utils.js
I know it's a little messy, for I am new to all of this. :)
Thanks.
I don't know if it will help, but you could try the following:
If the images are the same size and you know that size set the ".slide" div to that;
Try preloading the images and only starting the slide show when they are loaded. e.g using a preload plug-in.
and making use of the "callback" function.

Categories