Images with "display: none" blinking in Firefox before displaying - javascript

I have a sequence of images that I want to display one at a time. All the other images are hidden with display: none. The problem is, although I'm waiting all images finish the request, when I change the image to be displayed, the image is blinking. Here is an example:
The issue happens only in Firefox. I also created a JSFiddle with the example above: https://jsfiddle.net/ofte9g5v/7/
I was able to achieve the expected behavior using opacity property but I still would like to know why the first approach doesn't work as it is the most straightforward solution and also works in all other browsers.
Edit: I forgot to mention the images blink only the first time they are loaded.

You're using JavaScript to switch the visibility in two separate calls; first you alter the CSS styles for the visible image, setting its display property to none. It looks like Firefox picks this up and paints faster than other browsers, resulting in no images showing. Next you set the display to block on one of the other images, prompting it to be painted as expected.
Generally when you want to switch between images like this you need to stack the images using CSS in order to prevent these sorts of unwanted effects. Transition Groups are a useful tool to handle transitioning state between hidden, transitioning in, visible, and transitioning out. In this case you can get by with a little CSS:
.imageContainer {
position: relative;
width: 100%;
padding-bottom: 100%;
}
.img {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
object-fit: cover;
z-index: 1;
}
Then when you want to show an image, simply set the z-index property on it to 2 or higher and set the z-index property on all other images to 1 afterward.

As an alternative, if you need the visible image to be position: relative; what I did was I set visibility:hidden; position: absolute; on the inactive images and visibility: visible; position: relative; on the active one.

The problem seems to be that Firefox doesn't decode images until they're within the viewport. So after you set the selected image to display: block; and the other images to display: none, there's a moment where no image is displayed while Firefox decodes the selected image.
The solution I found was to decode() the image prior to changing its display:
selectedImage.decode().then(() => {
for (var i = 0; i < unselectedImages.length; i++) {
unselectedImages[i].style.display = 'none';
}
selectedImage.style.display = 'block';
})

Related

How to display an image fullscreen on page load

I have the script from previous stack overflow question on how to pick an image from an array at random.
Script to display an image selected at random from an array on page load
I want to take his idea a bit further, and display this image fullscreen on page load. I am working on a website, and had the idea to use an image as a greeting page. Where, when the page loads, you are greeted with a fullscreen HD image. When clicked, this image would disappear and show the full site. I wasn't exactly sure how to accomplish this though. Any ideas?
Edit: I'm not looking for direct implementation. Just general thoughts or jsFiddles on how to accomplish this task.
For showing the image on the page load you can use $( document ).ready() function. on click() of the image you could show the website.
Try using CSS like,
First option,
img {
position: fixed;
top: 0;
left: 0;
/* Preserve aspet ratio */
min-width: 100%;
min-height: 100%;
}
Second option,
img {
/* Set rules to fill background */
min-height: 100%;
min-width: 1024px;
/* Set up proportionate scaling */
width: 100%;
height: auto;
/* Set up positioning */
position: fixed;
top: 0;
left: 0;
}
To understand the above options read Perfect Full Page Background Image
I recommend you to use a complete full page background image slider for your problem. If it is available then use it without wasting your time.
I found a full page slider on http://www.freshdesignweb.com/fullscreen-jquery-slider.html in which the first one background slider is best suitable to you.
Also you can go to https://www.google.co.in/?q=full+background+image+slider to get more image sliders

How can I replicate this image zoom animation effect in jQuery/javascript?

When clicking on the thumbnail on the image on this site: http://www.grouprecipes.com/138587/banana-oatmeal-chocolate-chip-cookies.html, it expands and loads the original (full-size) version of the image.
I think they are using prototype or something similar. I've been looking around on here and have only mainly found examples that just increase the size of the original image and don't actually load another version of the image (like the linked example does).
Anyone care to help me figure out what techniques I should use for this? Combination of CSS3 and some .animate()?
Here is a simple example using CSS3, a bit of JavaScript.
Explanation:
Initially both the thumbnail and the enlarged version of the picture are placed on the same space using absolute positioning.
The enlarged version is not loaded until the thumbnail is clicked because the enlarged img tag doesn't have any src to begin with. It is assigned dynamically through the JS.
The image move to a different position is achieved using the translateX and translateY options which moves the absolutely positioned enlarged version of the image by the mentioned no. of pixels in both X and Y axes.
JavaScript is used to add a show class to the enlarged picture which triggers the transition effect and also set the src of the img tag to the newer/bigger image.
The enlarged version would return back to its original position when clicked anywhere on the enlarged image.
The JS code is written using class name instead of id just in case you need multiple such thumbnails on the same page. If that is the case, you may want to remove the [0], put it inside a for loop and replace the [0] with the counter variable. Also the enlarged image's source for each such thumbnail image can be maintained through a key-value pair mapping.
The z-index: -1 on the image originally (prior to adding .show through JS) is to make sure that it stays in the background and doesn't hinder the click on the thumbnail.
Points to note:
transform, translateX and translateY are all CSS3 properties/functions and hence have no support in IE8 and less. For older versions of Chrome, Firefox, Opera and Safari, browser prefixes like -webkit-, -moz would be required.
The classList.add and classList.remove functions are HTML5 standard and are not supported in IE9 but they equivalent IE9 code to add or remove class (like className += ..) can be easily done.
var images = {'img1': 'http://placehold.it/400/400'};
document.getElementsByClassName('thumbnail')[0].onclick = function(){
document.getElementById('enlarged').src = images[this.id];
document.getElementById('zoomed').classList.add('show');
}
document.getElementById('enlarged').onclick = function(event){
if(event.target != document.getElementsByClassName('thumbnail')[0])
document.getElementById('zoomed').classList.remove('show');
}
.container{
position: relative;
}
.thumbnail{
height: 200px;
width: 200px;
}
#zoomed .enlarged{
opacity: 0;
z-index: -1;
min-height: 200px;
min-width: 200px;
height: 200px;
width: 200px;
position: absolute;
transition: all 1s;
left: 0px; top: 0px;
}
#zoomed.show .enlarged{
opacity: 1;
z-index: 2;
height: auto;
width: auto;
min-height: 400px;
min-width: 400px;
transform: translateX(200px) translateY(200px);
}
<div class="container">
<img src="http://placehold.it/200/200" alt="" class="thumbnail" id='img1'/>
<div id='zoomed'>
<img src="" alt="" class="enlarged" id='enlarged'/>
</div>
</div>
Additional Resource:
Here is a good article on how to pre-load images (the enlarged versions if needed) using CSS + JS, only JS and AJAX.

How do I create a slideshow with fancyBox?

I've created two image galleries at http://www.spanish-bookworld.com/fancybox_demo.html
The lack of "Next" button on the image when the mouse is not over it worries me. My audience is very computer illiterate and most of them will not see that there are more images in the gallery.
I reckon I have two options. One is to have a Next button permanently on the images, and the other one is to have a slideshow.
Unfortunately I can't figure out how to code either solution.
Any clues? Thanks.
As the fancybox documentation states in their button example (http://jsfiddle.net/Xh3B2/), you should try to set the CSS on fancybox navigaton to visible (and then set their position with CSS).
For your example, you should use this kind of CSS first to set the navigation always visible and then set the next/previous button position.
.fancybox-nav {
width: 60px;
}
.fancybox-nav span {
visibility: visible;
opacity: 0.5;
}
.fancybox-nav:hover span {
opacity: 1;
}
.fancybox-next {
right: -60px;
}
.fancybox-prev {
left: -60px;
}
For the slideshow option, you should set your fancybox script to "autoPlay = true. The default value is set to "false" which make the slideshow disabled.

How to hide an element without taking up space and still respond to events?

display:none takes the element away from the layout flow and thus not taking up space on the page but its events get disabled.
visibility:hidden hides the element, but the element still takes up space.
I need a way to hide a file input element without taking up space and responding when I call its .click() event.
Example
Simply setting opacity to 0 should work. The element won't show up, and it wont take space either. And its events will work.
When giving opacity, also specify the opacity counterparts of all browsers (-moz.., -webkit, filter: ..) etc.. to ensure cross-browser compatibility.
EDIT
Your style should look something like:
.mydiv {
position: absolute;
left: 10px; /* change as needed */
top: 10px; /* change as needed */
opacity: 0;
}
Working demo here: http://jsfiddle.net/t2BHg/6/
Setting display: none; does not disable events for an element, but it will prevent it from being clicked because the element has no pixel dimensions to click into. You can still call its onclick events programmatically. See an example
How about making it invisible, but with absolute positioning off the left of the screen:
CSS:
#yourelement, .hidden {
visibility : hidden;
position : absolute;
left : -1000px;
width : 1px;
height : 1px;
overflow : hidden;
}
You could make it visibility: hidden and set width and height to 0
Less code:
position: fixed; z-index: -1;

IE 6, 7 & 8 z-index

I have two divs, overlay and results, with z-indexes of 100 and 200 respectively.
The divs css is below:
.overlay {
width: 100%;
height: 100%;
background: #000;
opacity: 0.5;
z-index: 100;
}
.results {
position: absolute;
z-index: 200;
}
Content is pulled via Ajax, sent to the results div, and then shown with javascript.
The overlay, regardless of what I do, always sits on top of the results window. I've tried altering the css immediately after the results are shown which makes no difference. This only happens IE 6-8 which I'm assuming is because of the peculiar way z-index works for those versions.
Any insight into how I could go about bringing the results box into view?
Elements with a higher z-index will appear in front of elements with a lower z-index in the same stacking context. If two elements have the same z-index, the latter one appears on top. Stacking context is defined by:
The Document Root
Elements with position: absolute or position: relative and a z-index
Elements that are partially transparent, that is they have an opacity < 1
In IE7, any element with position: absolute or position: relative (this can cause many bugs since it is the only browser that acts this way)
If IE7 is an issue, you can make all browsers behave the same by always adding z-index : 1 to any element that also has some position or opacity set.

Categories