Dynamically Changing CSS Background Image - javascript

What I'm looking for is a way to make my HTML header tag change background images every few seconds. Any solutions are welcome, as long as it is not to complex.
I have this code right now as well as linking to JQuery:
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
$(function() {
var header = $(‘.mainHeader’);
var backgrounds = new Array(
‘url(img/rainbow.jpg)’,
‘url(img/chickens_on_grass.jpg)’
‘url(img/cattle_on_pasture.jpg)’
‘url(img/csa_bundle.jpg)’
);
var current = 0;
function nextBackground() {
header.css(‘background’,backgrounds[current = ++current % backgrounds.length]);
setTimeout(nextBackground, 10000);
}
setTimeout(nextBackground, 10000);
header.css(‘background’, backgrounds[0]);
});
My HTML header:
<header class="mainHeader"></header>
And CSS:
.mainHeader {
background: no-repeat center bottom scroll;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
min-height: 150px;
padding-top: 2%;
font-size: 100%;
}
Right now I have now background image at all.

Made a few amendments to your code
DEMO: http://jsfiddle.net/p77KW/
var header = $('body');
var backgrounds = new Array(
'url(http://placekitten.com/100)'
, 'url(http://placekitten.com/200)'
, 'url(http://placekitten.com/300)'
, 'url(http://placekitten.com/400)'
);
var current = 0;
function nextBackground() {
current++;
current = current % backgrounds.length;
header.css('background-image', backgrounds[current]);
}
setInterval(nextBackground, 1000);
header.css('background-image', backgrounds[0]);
Biggest changes (as noted in others comments) is that you have to use apostrophe**'**s, not those funky open and close single-quotes and that your array wasn't correct.
With these corrections out of the way I simplified a few things:
Increment current then take modulus (I know this is basically what you did but how much easier is that to debug ;))
Target background-image directly
Used setInterval() instead of a double call to setTimeout

You could acheive this same technique with HTML/CSS Only by 1. placing images within an "img" tag in your HTML surrounded by a "div wrapper" and setting it to position:relative and div wrapper img's to position:absolute. For full-width/full-height you can use percentages or potentially "background-size:cover" (haven't checked) and then call a CSS animation to change the images dynamically.
Or 2. you can add multiple images to a background in your CSS separated by commas, apply background-size:cover and again use CSS animations to change the background.
Here's an example and also Mozilla CSS3 Animation Documentation

<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
$(document).ready(function(){
var header = $('body');
var backgrounds = new Array(
'url(http://placekitten.com/100)'
, 'url(http://placekitten.com/200)'
, 'url(http://placekitten.com/300)'
, 'url(http://placekitten.com/400)'
);
var current = 0;
function nextBackground() {
current++;
current = current % backgrounds.length;
header.css('background-image', backgrounds[current]);
}
setInterval(nextBackground, 1000);
header.css('background-image', backgrounds[0]);
});
</script>
</head>
<body>
<header></header>
</body>
</html>

You can't delimit JavaScript strings with ‘ characters. You must use " or '.

It must be late but may help to another one.
For this goal in some situations I prefer to use a jquery plugin named tcycle which have only a few lines of code and supports just fade transition, but it works smoothly even with large images.
Setting up a slideshow with tcycle is easy and even could be done with declarative markup such as
<div class="tcycle">
<img src="p1.jpg">
<img src="p2.jpg">
</div>
The trick could be donde using css z-index:-1 for container div and setting width and height to 100%
Homepage for downloading and check for other examples is Malsup jQuery plugins

Related

How do I scroll to an element which is present inside an overflow div which itself is inside an an overflow container? [duplicate]

I am creating a chat using Ajax requests and I'm trying to get messages div to scroll to the bottom without much luck.
I am wrapping everything in this div:
#scroll {
height:400px;
overflow:scroll;
}
Is there a way to keep it scrolled to the bottom by default using JS?
Is there a way to keep it scrolled to the bottom after an ajax request?
Here's what I use on my site:
var objDiv = document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight;
This is much easier if you're using jQuery scrollTop:
$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);
Try the code below:
const scrollToBottom = (id) => {
const element = document.getElementById(id);
element.scrollTop = element.scrollHeight;
}
You can also use Jquery to make the scroll smooth:
const scrollSmoothlyToBottom = (id) => {
const element = $(`#${id}`);
element.animate({
scrollTop: element.prop("scrollHeight")
}, 500);
}
Here is the demo
Here's how it works:
Ref: scrollTop, scrollHeight, clientHeight
using jQuery animate:
$('#DebugContainer').stop().animate({
scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);
Newer method that works on all current browsers:
this.scrollIntoView(false);
var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));
Works from jQuery 1.6
https://api.jquery.com/scrollTop/
http://api.jquery.com/prop/
alternative solution
function scrollToBottom(element) {
element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
}
smooth scroll with Javascript:
document.getElementById('messages').scrollIntoView({ behavior: 'smooth', block: 'end' });
If you don't want to rely on scrollHeight, the following code helps:
$('#scroll').scrollTop(1000000);
Java Script:
document.getElementById('messages').scrollIntoView(false);
Scrolls to the last line of the content present.
My Scenario: I had an list of string, in which I had to append a string given by a user and scroll to the end of the list automatically. I had fixed height of the display of the list, after which it should overflow.
I tried #Jeremy Ruten's answer, it worked, but it was scrolling to the (n-1)th element. If anybody is facing this type of issue, you can use setTimeOut() method workaround. You need to modify the code to below:
setTimeout(() => {
var objDiv = document.getElementById('div_id');
objDiv.scrollTop = objDiv.scrollHeight
}, 0)
Here is the StcakBlitz link I have created which shows the problem and its solution : https://stackblitz.com/edit/angular-ivy-x9esw8
If your project targets modern browsers, you can now use CSS Scroll Snap to control the scrolling behavior, such as keeping any dynamically generated element at the bottom.
.wrapper > div {
background-color: white;
border-radius: 5px;
padding: 5px 10px;
text-align: center;
font-family: system-ui, sans-serif;
}
.wrapper {
display: flex;
padding: 5px;
background-color: #ccc;
border-radius: 5px;
flex-direction: column;
gap: 5px;
margin: 10px;
max-height: 150px;
/* Control snap from here */
overflow-y: auto;
overscroll-behavior-y: contain;
scroll-snap-type: y mandatory;
}
.wrapper > div:last-child {
scroll-snap-align: start;
}
<div class="wrapper">
<div>01</div>
<div>02</div>
<div>03</div>
<div>04</div>
<div>05</div>
<div>06</div>
<div>07</div>
<div>08</div>
<div>09</div>
<div>10</div>
</div>
You can use the HTML DOM scrollIntoView Method like this:
var element = document.getElementById("scroll");
element.scrollIntoView();
Javascript or jquery:
var scroll = document.getElementById('messages');
scroll.scrollTop = scroll.scrollHeight;
scroll.animate({scrollTop: scroll.scrollHeight});
Css:
.messages
{
height: 100%;
overflow: auto;
}
Using jQuery, scrollTop is used to set the vertical position of scollbar for any given element. there is also a nice jquery scrollTo plugin used to scroll with animation and different options (demos)
var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;
if you want to use jQuery's animate method to add animation while scrolling down, check the following snippet:
var myDiv = $("#div_id").get(0);
myDiv.animate({
scrollTop: myDiv.scrollHeight
}, 500);
I have encountered the same problem, but with an additional constraint: I had no control over the code that appended new elements to the scroll container. None of the examples I found here allowed me to do just that. Here is the solution I ended up with .
It uses Mutation Observers (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) which makes it usable only on modern browsers (though polyfills exist)
So basically the code does just that :
var scrollContainer = document.getElementById("myId");
// Define the Mutation Observer
var observer = new MutationObserver(function(mutations) {
// Compute sum of the heights of added Nodes
var newNodesHeight = mutations.reduce(function(sum, mutation) {
return sum + [].slice.call(mutation.addedNodes)
.map(function (node) { return node.scrollHeight || 0; })
.reduce(function(sum, height) {return sum + height});
}, 0);
// Scroll to bottom if it was already scrolled to bottom
if (scrollContainer.clientHeight + scrollContainer.scrollTop + newNodesHeight + 10 >= scrollContainer.scrollHeight) {
scrollContainer.scrollTop = scrollContainer.scrollHeight;
}
});
// Observe the DOM Element
observer.observe(scrollContainer, {childList: true});
I made a fiddle to demonstrate the concept :
https://jsfiddle.net/j17r4bnk/
Found this really helpful, thank you.
For the Angular 1.X folks out there:
angular.module('myApp').controller('myController', ['$scope', '$document',
function($scope, $document) {
var overflowScrollElement = $document[0].getElementById('your_overflow_scroll_div');
overflowScrollElement[0].scrollTop = overflowScrollElement[0].scrollHeight;
}
]);
Just because the wrapping in jQuery elements versus HTML DOM elements gets a little confusing with angular.
Also for a chat application, I found making this assignment after your chats were loaded to be useful, you also might need to slap on short timeout as well.
Like you, I'm building a chat app and want the most recent message to scroll into view. This ultimately worked well for me:
//get the div that contains all the messages
let div = document.getElementById('message-container');
//make the last element (a message) to scroll into view, smoothly!
div.lastElementChild.scrollIntoView({ behavior: 'smooth' });
small addendum: scrolls only, if last line is already visible. if scrolled a tiny bit, leaves the content where it is (attention: not tested with different font sizes. this may need some adjustments inside ">= comparison"):
var objDiv = document.getElementById(id);
var doScroll=objDiv.scrollTop>=(objDiv.scrollHeight-objDiv.clientHeight);
// add new content to div
$('#' + id ).append("new line at end<br>"); // this is jquery!
// doScroll is true, if we the bottom line is already visible
if( doScroll) objDiv.scrollTop = objDiv.scrollHeight;
Just as a bonus snippet. I'm using angular and was trying to scroll a message thread to the bottom when a user selected different conversations with users. In order to make sure that the scroll works after the new data had been loaded into the div with the ng-repeat for messages, just wrap the scroll snippet in a timeout.
$timeout(function(){
var messageThread = document.getElementById('message-thread-div-id');
messageThread.scrollTop = messageThread.scrollHeight;
},0)
That will make sure that the scroll event is fired after the data has been inserted into the DOM.
This will let you scroll all the way down regards the document height
$('html, body').animate({scrollTop:$(document).height()}, 1000);
You can also, using jQuery, attach an animation to html,body of the document via:
$("html,body").animate({scrollTop:$("#div-id")[0].offsetTop}, 1000);
which will result in a smooth scroll to the top of the div with id "div-id".
Scroll to the last element inside the div:
myDiv.scrollTop = myDiv.lastChild.offsetTop
You can use the Element.scrollTo() method.
It can be animated using the built-in browser/OS animation, so it's super smooth.
function scrollToBottom() {
const scrollContainer = document.getElementById('container');
scrollContainer.scrollTo({
top: scrollContainer.scrollHeight,
left: 0,
behavior: 'smooth'
});
}
// initialize dummy content
const scrollContainer = document.getElementById('container');
const numCards = 100;
let contentInnerHtml = '';
for (let i=0; i<numCards; i++) {
contentInnerHtml += `<div class="card mb-2"><div class="card-body">Card ${i + 1}</div></div>`;
}
scrollContainer.innerHTML = contentInnerHtml;
.overflow-y-scroll {
overflow-y: scroll;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="d-flex flex-column vh-100">
<div id="container" class="overflow-y-scroll flex-grow-1"></div>
<div>
<button class="btn btn-primary" onclick="scrollToBottom()">Scroll to bottom</button>
</div>
</div>
Css only:
.scroll-container {
overflow-anchor: none;
}
Makes it so the scroll bar doesn't stay anchored to the top when a child element is added. For example, when new message is added at the bottom of chat, scroll chat to new message.
Why not use simple CSS to do this?
The trick is to use display: flex; and flex-direction: column-reverse;
Here is a working example. https://codepen.io/jimbol/pen/YVJzBg
A very simple method to this is to set the scroll to to the height of the div.
var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);
On my Angular 6 application I just did this:
postMessage() {
// post functions here
let history = document.getElementById('history')
let interval
interval = setInterval(function() {
history.scrollTop = history.scrollHeight
clearInterval(interval)
}, 1)
}
The clearInterval(interval) function will stop the timer to allow manual scroll top / bottom.
I know this is an old question, but none of these solutions worked out for me. I ended up using offset().top to get the desired results. Here's what I used to gently scroll the screen down to the last message in my chat application:
$("#html, body").stop().animate({
scrollTop: $("#last-message").offset().top
}, 2000);
I hope this helps someone else.
I use the difference between the Y coordinate of the first item div and the Y coordinate of the selected item div. Here is the JavaScript/JQuery code and the html:
function scrollTo(event){
// In my proof of concept, I had a few <button>s with value
// attributes containing strings with id selector expressions
// like "#item1".
let selectItem = $($(event.target).attr('value'));
let selectedDivTop = selectItem.offset().top;
let scrollingDiv = selectItem.parent();
let firstItem = scrollingDiv.children('div').first();
let firstItemTop = firstItem.offset().top;
let newScrollValue = selectedDivTop - firstItemTop;
scrollingDiv.scrollTop(newScrollValue);
}
<div id="scrolling" style="height: 2rem; overflow-y: scroll">
<div id="item1">One</div>
<div id="item2">Two</div>
<div id="item3">Three</div>
<div id="item4">Four</div>
<div id="item5">Five</div>
</div>

Fade In / Fade Out background images without white background

I want to create a website with background images that change over time with a fade in/fade out effect, but I don't want to use the existing jQuery fade in/fade out effect because with when one image faded out, a white background appeared before other image faded in. I found a plugin named Maximage that suits my request but it uses img tags while I want to work with background-image CSS (I have a good reason for doing this). Does anyone know how to do this?
Here's my HTML code:
<div id="wrapper">
//My contain here
</div>
Here's my JavaScript code so far:
//Auto change Background Image over time
$(window).load(function() {
var images = ['img/top/bg-1.jpg','img/top/bg-2.jpg','img/top/bg-3.jpg'];
var i = 0;
function changeBackground() {
$('#wrapper').fadeOut(500, function(){
$('#wrapper').css('background-image', function () {
if (i >= images.length) {
i = 0;
}
return 'url(' + images[i++] + ')';
});
$('#wrapper').fadeIn(500);
})
}
changeBackground();
setInterval(changeBackground, 3000);
});
Example: http://www.aaronvanderzwan.com/maximage/examples/basic.html
AHH ! Finally ! I found a nice technique ! I'm using a double wrapper.
The problem in your code is a bit logical. You can't fadeOut and fadeIn at the same time a single wrapper.
So the idea is to create two wrapper and to switch between them back and forth. We have one wrapper called: "wrapper_top" that encapsulate the second wrapper called: "wrapper_bottom". And the magic was to put beside the second wrapper: your content.
Thus having the structure ready which is the following:
<div id='wrapper_top'>
<div id='content'>YOUR CONTENT</div>
<div id='wrapper_bottom'></div>
</div>
Then a bit of JS+CSS and voilà ! It will be dynamic with any amount of images !!!
Here is the implementation: http://jsbin.com/wisofeqetu/1/
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function() {
var i =0;
var images = ['image2.png','image3.png','image1.png'];
var image = $('#slideit');
//Initial Background image setup
image.css('background-image', 'url(image1.png)');
//Change image at regular intervals
setInterval(function(){
image.fadeOut(1000, function () {
image.css('background-image', 'url(' + images [i++] +')');
image.fadeIn(1000);
});
if(i == images.length)
i = 0;
}, 5000);
});
</script>
</head>
<body>
<div id="slideit" style="width:700px;height:391px;">
</div>
</body>
</html>
If it doesn't have to be background-image, you can place all the images in your #wrapper, in <img>, it will work like a charm:
<div id="wrapper">
<img src="firstImage" class="imageClass"></img>
<img src="secoundImage" class="imageClass"></img>
<img src="thirdImage" class="imageClass"></img>
</div>
then some style. Every image has to be in same spot, so add position relative to #wrapper, and position absolute to .imageClass:
#wrapper{
position: relative;
}
.imageClass{
position: absolute;
top: 0;
left: 0;
display: none;
}
display: none; will hide every image.
Now some JQuery. To appear first image when window load write this:
$(window).load(function() {
$('.imageClass').eq(0).show();
});
by the .eq() "command" you can specify which one element with class '.imageClass' you want to use exactly. Starts with 0. After that just do something like that:
function changeBackground() {
var current = 0;
//tells which image is currently shown
if(current<$('.imageClass').length){
//loop that will show first image again after it will show the last one
$('.imageClass').eq(current).fadeOut(500);
current++;
$('.imageClass').eq(current).fadeIn(500);
} else {
$('.imageClass').eq(current).fadeOut(500);
current=0;
$('.imageClass').eq(current).fadeIn(500);
}
}
changeBackground();
setInterval(changeBackground, 3000);
});
That should work, hope you will like it.
You may also use jQuery plugin backstretch.

how to change background images with fade

so far (with the help of this comm :)) I created a full viewport background, thats able to switch on click.
Since I'm a beginner I have two questions:
1) Is the code "good", or did I wrote it to complicated?
and the Mainquestion:
How can I put a fade effect into my code? Now it's kinda ugly, because the images are loading slow (stuttering). I imagine something like this:
Image--Click--Fading black--Fading in new Image--Click--Fading black---Fading in new Image--..
Here is the code I wrote:
HTML:
<div class="t1">
</div>
CSS:
.t1 {
background: url(pics/homescreen.JPG) no-repeat center center fixed ;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
width: 100%;
height: 100%;
}
jQuery:
$(function () {
var y = 1;
$('.t1').click(function () {
var x = ['url(pics/screen1.jpg) no-repeat center center fixed',
'url(pics/screen2.jpg) no-repeat center center fixed',
'url(pics/schild.jpg) no-repeat center center fixed'
]
$('.t1').css('background', x[y]);
$('.t1').css('background-size', 'cover');
if (y == 2) {
y = 0;
} else {
y = y + 1;
}
});
})
Demo: http://jsfiddle.net/bSAm2/
This doesn't include preloading, but the effect is quite nice.
If you are interested in a preloader, you probably want to preload images one at a time, when they are needed: loading all images upfront or worse in the head of your document, will likely slow down page loading beyond what's an acceptable UX.
Also, transition won't work on older browsers (see here)
To animate CSS properties, you can use http://api.jquery.com/animate/
In particular, you can fade out the current image by animating its opacity (to 0), then, when this animation is completed change the image source (while it is not visible) and start the fade-in animation.
For best appearance, you can preload images "Just in Time", for example you can preload the next image to show, so there won't be any latency
EDIT
This example works, and uses closure so that you can have multiple images rotating independently:
$(function () {
var images = ['url(http://lorempixel.com/output/people-q-c-640-480-8.jpg) no-repeat center center fixed',
'url(http://lorempixel.com/output/nature-q-c-640-480-8.jpg) no-repeat center center fixed',
'url(http://lorempixel.com/output/fashion-q-c-640-480-9.jpg) no-repeat center center fixed'
];
function bindSwitcher (elem) {
var imageIndex = 0;
return function switchImage () {
elem.fadeOut(function (){
elem.css('background', images[imageIndex]);
if (imageIndex == images.length - 1) {
imageIndex = 0;
} else {
imageIndex += 1;
}
elem.css('background-size', 'cover');
elem.fadeIn();
});
};
}
var imageSwitcher = bindSwitcher($('#t1'));
$('#t1').click(imageSwitcher);
$('#t2').click(bindSwitcher($('#t2')));
});
And the HTML, with a little change to show the difference:
<div id="t1" class="t1" style="position: absolute; left:0%">
</div>
<div id="t2" class="t1" style="position: absolute; left:50%">
</div>
Demo: http://jsfiddle.net/abhitalks/FNUx8/8/
Is the code "good", or did I wrote it to complicated?
A couple of things which you could do is:
Take your image array outside of click handler. You woudn't want to create that array every time a click happens.
Reduce the code to cycle the array by using a modulus.
Refer to the element using this.
Use an id instead of class to target the element directly if that is unique.
So, effectively your code reduces to:
var x = ['url(...1.jpg) no-repeat center center fixed',
'url(...2.jpg) no-repeat center center fixed',
'url(..3.jpg) no-repeat center center fixed'
];
var index = 0;
$('#t1').click(function () {
index = (index + 1) % x.length;
$(this).css('background', x[index]);
});
How can I put a fade effect into my code? Now it's kinda ugly, because
the images are loading slow (stuttering)
(1.) You can put a fade effect using CSS3 transition:
#t1 {
...
transition: 1s;
}
(2.) There is stuttering because the images are loaded at runtime. You could avoid that by pre-loading images:
One way could be like this:
var d = []; // create an array for holding dummy elements
for (var i = 0; i < x.length; i++) {
d[i] = $("<img>"); // create an img and add to the array
d[i].attr('src', x[i]).hide(); // add src to img and hide it
$("body").append(d[i]); // add the img to body to start load
}
Ideally wrap this code in the head so that this is done by the time DOM is ready. Put rest of your code either wrapped in body at the end or in .ready.
Edit:
Changed the preloading code to use img. Updated the fiddle.
The code is not complicated, in time you'll learn to write cleaner (good) code. Here is my suggestions:
1. move the x definition outside the click event, put it right after y and y should be 0 initially;
2. if(y == 2) is too static, beter take the length of the array if(y == x.length);
3. remove background-size from script, it's set in css;
4. For fade effect you can do something like this:
$('.t1').fadeOut(300, function() {
$(this).css('background', x[y]).fadeIn(300);
});
I haven't tested it, but should do the job.

Apply Different Rules when clicking on Different Thumbnails (jquery)

I'm pretty much a newbie on the HTML/CSS realm and have been facing a jquery challenge ever since I started building my first website. I want to create an jquery-powered image gallery, using thumbnails. The tutorial I followed for that matter was Ivan Lazarevic's (http://workshop.rs/2010/07/create-image-gallery-in-4-lines-of-jquery/). I also made use of Stackoverflow's forum through this thread: http://goo.gl/ILzsx.
The code he provides replaces the large image on display with the larger version of the thumbnail that's been clicked. This seems to work pretty smoothly but just for pictures that have the same orientation. The following code appears on two different files, thus establishing a difference between the horizontal and vertical images:
<div id="mainImage">
<img id="largeImage" src="Images/Projects/UOW/UOWII_large.jpg"/>
</div>
AND:
<div id="mainImageVERTICAL">
<img id="largeImageVERTICAL" src="Images/Projects/UOW/UOWI_large.jpg" />
</div>
I have created different CSS rules for both the largeImage and largeImageVERTICAL parameters, depending on whether the image has a portrait or landscape orientation.
#largeImage {
position: fixed;
height: 83%;
width:auto;
top: 15%;
left: 5%;
}
AND:
#largeImageVERTICAL {
position: fixed;
height: 83%;
width:auto;
top: 15%;
left: 36.36%;
}
These two rules just place the images at different points of the screen. However, what I would like to know is how to modify my code so that I can create a page with both portrait and landscape-oriented images applying the CSS rule that belongs to each. Up to now, what I have is what I got from Lazarevic's approach, which is:
$('#thumbs img').click(function(){
$('#largeImage').attr('src',$(this).attr('src').replace('thumb','large'));
});
This code just replaces the thumbnails with the bigger pictures. As stated, I want to be able to apply the right rule to the right image and I'm assuming this has to be be made through some JS coding, which I know pretty much nothing about.
I would appreciate some help so that I can keep on with this project. Any ideas how to make this work? Maybe a JS function that tells the machine to use one or another CSS rule depending on which image is clicked upon? I'm really stuck here...
Thanks in advance!
There are a couple of ways you could do this.
Use a HTML5 data-* attribute to specify which of the <img> elements should be updated. So:
<div id="thumbs">
<img src="img.jpg" data-large="largeImage"/>
<img src="anotherimg.jpg" data-large="largeImageVERTICAL"/>
</div>
Then:
$('#thumbs img').click(function(e) {
var imageId = $(this).attr('data-large'),
newSrc = this.src.replace('thumb', 'large');
$('#' + imageId).attr('src', newSrc);
});
Or, use the dimensions of the thumbnail to determine whether it's portrait or landscape:
$('#thumbs img').click(function(e) {
var $this = $(this),
height = $this.height(),
width = $this.width(),
newSrc = this.src.replace('thumb', 'large');
var imageId = (height > width) ? 'largeImageVERTICAL' : 'largeImage';
$('#' + imageId).attr('src', newSrc);
});
In either case, you'll probably need to hide the other, unused <img> element so that you don't have the previously selected image for the other orientation displayed.
One way to achieve this would be:
var alternateImageId = (imageId === 'largeImage') ? 'largeImageVERTICAL' : 'largeImage';
$('#' + alternateImageId).hide();
Add the above two lines to the click event handler above, and call .show() after calling .attr('src', ...).
Use class not id.
#largeImage{
top: 15%;
width:auto;
height: 83%;
position: fixed;
}
.portrait{
left: 36.36%;
}
.landscape{
left: 5%;
}
js
$('#largeImage').on('load', function () {
var that = $(this);
if (that.width() < that.height()) {
that.addClass('portrait');
} else {
that.addClass('landscape');
}
});
$('#thumbs').on('click', 'img', function () {
$('#largeImage').attr('src',$(this).attr('src').replace('thumb','large'));
});

Scroll event background change

I am trying to add a scroll event which will change the background of a div which also acts as the window background (it has 100% width and height). This is as far as I get. I am not so good at jquery. I have seen tutorials with click event listeners. but applying the same concept , like, returning scroll event as false, gets me nowhere. also I saw a tutorial on SO where the person suggest use of array. but I get pretty confused using arrays (mostly due to syntax).
I know about plugins like waypoints.js and skrollr.js which can be used but I need to change around 50-60 (for the illusion of a video being played when scrolled) ... but it wont be feasible.
here is the code im using:-
*
{
border: 2px solid black;
}
#frame
{
background: url('1.jpg') no-repeat;
height: 1000px;
width: 100%;
}
</style>
<script>
$(function(){
for ( i=0; i = $.scrolltop; i++)
{
$("#frame").attr('src', ''+i+'.jpg');
}
});
</script>
<body>
<div id="frame"></div>
</body>
Inside your for loop, you are setting the src attribute of #frame but it is a div not an img.
So, instead of this:
$("#frame").attr('src', ''+i+'.jpg');
Try this:
$("#frame").css('background-image', 'url(' + i + '.jpg)');
To bind a scroll event to a target element with jQuery:
$('#target').scroll(function() {
//do stuff here
});
To bind a scroll event to the window with jQuery:
$(window).scroll(function () {
//do stuff here
});
Here is the documentation for jQuery .scroll().
UPDATE:
If I understand right, here is a working demo on jsFiddle of what you want to achieve.
CSS:
html, body {
min-height: 1200px; /* for testing the scroll bar */
}
div#frame {
display: block;
position: fixed; /* Set this to fixed to lock that element on the position */
width: 300px;
height: 300px;
z-index: -1; /* Keep the bg frame at the bottom of other elements. */
}
Javascript:
$(document).ready(function() {
switchImage();
});
$(window).scroll(function () {
switchImage();
});
//using images from dummyimages.com for demonstration (300px by 300px)
var images = ["http://dummyimage.com/300x300/000000/fff",
"http://dummyimage.com/300x300/ffcc00/000",
"http://dummyimage.com/300x300/ff0000/000",
"http://dummyimage.com/300x300/ff00cc/000",
"http://dummyimage.com/300x300/ccff00/000"
];
//Gets a valid index from the image array using the scroll-y value as a factor.
function switchImage()
{
var sTop = $(window).scrollTop();
var index = sTop > 0 ? $(document).height() / sTop : 0;
index = Math.round(index) % images.length;
//console.log(index);
$("#frame").css('background-image', 'url(' + images[index] + ')');
}
HTML:
<div id="frame"></div>
Further Suggestions:
I suggest you change the background-image of the body, instead of the div. But, if you have to use a div for this; then you better add a resize event-istener to the window and set/update the height of that div with every resize. The reason is; height:100% does not work as expected in any browser.
I've done this before myself and if I were you I wouldn't use the image as a background, instead use a normal "img" tag prepend it to the top of your page use some css to ensure it stays in the back under all of the other elements. This way you could manipulate the size of the image to fit screen width better. I ran into a lot of issues trying to get the background to size correctly.
Html markup:
<body>
<img src="1.jpg" id="img" />
</body>
Script code:
$(function(){
var topPage = 0, count = 0;
$(window).scroll( function() {
topPage = $(document).scrollTop();
if(topPage > 200) {
// function goes here
$('img').attr('src', ++count +'.jpg');
}
});
});
I'm not totally sure if this is what you're trying to do but basically, when the window is scrolled, you assign the value of the distance to the top of the page, then you can run an if statement to see if you are a certain point. After that just simply change run the function you would like to run.
If you want to supply a range you want the image to change from do something like this, so what will happen is this will allow you to run a function only between the specificied range between 200 and 400 which is the distance from the top of the page.
$(function(){
var topPage = 0, count = 0;
$(window).scroll( function() {
topPage = $(document).scrollTop();
if(topPage > 200 && topPage < 400) {
// function goes here
$('#img').attr('src', ++count +'.jpg');
}
});
});

Categories

Resources