Have worked out a solution, see the bottom!
I'm experimenting with a responsive carousel (fluid). I have elements stacked on top of each other so that the width can be fluid depending on the width of the parent. The issue is I need the parent to have overflow hidden which is not possible with children that are absolute positioned.
Tip on cleaning up the JS are appreciated too!
Does anyone have any ideas how to improve this or alternatives? Heres the fiddle: http://jsfiddle.net/j35fy/5/
.carousel-wrap {
position: relative;
}
.carousel-item {
position: absolute;
top: 0;
}
$.fn.mwCarousel = function(options) {
//Default settings.
var settings = $.extend({
changeWait: 3000,
changeSpeed: 800,
reveal: false,
slide: true,
autoRotate: true
}, options );
var CHANGE_WAIT = settings.changeWait;
var CHANGE_SPEED = settings.changeSpeed;
var REVEAL = settings.reveal;
var SLIDE = settings.slide;
var AUTO_ROTATE = settings.autoRotate;
var $carouselWrap = $(this);
var SLIDE_COUNT = $carouselWrap.find('.carousel-item').length;
var rotateTimeout;
if (AUTO_ROTATE) {
rotateTimeout = setTimeout(function(){
rotateCarousel(SLIDE_COUNT-1);
}, CHANGE_WAIT);
}
function rotateCarousel(slide) {
if (slide === 0) {
slide = SLIDE_COUNT-1;
rotateTimeout = setTimeout(function(){
$('.carousel-item').css('margin', 0);
$('.carousel-item').show();
}, CHANGE_WAIT);
if (REVEAL) {
$($carouselWrap.find('.carousel-item')[slide]).slideToggle(CHANGE_SPEED);
} else if (SLIDE) {
var carouselItem = $($carouselWrap.find('.carousel-item')[slide]);
carouselItem.show();
var itemWidth = carouselItem.width();
carouselItem.animate({margin: 0}, CHANGE_SPEED);
} else {
$($carouselWrap.find('.carousel-item')[slide]).fadeIn(CHANGE_SPEED);
}
slide = slide+1;
} else {
if (REVEAL) {
$($carouselWrap.find('.carousel-item')[slide]).slideToggle(CHANGE_SPEED);
} else if (SLIDE) {
var carouselItem = $($carouselWrap.find('.carousel-item')[slide]);
var itemWidth = carouselItem.width();
carouselItem.animate({marginLeft: -itemWidth, marginRight: itemWidth}, CHANGE_SPEED);
} else {
$($carouselWrap.find('.carousel-item')[slide]).fadeOut(CHANGE_SPEED);
}
}
rotateTimeout = setTimeout(function(){
rotateCarousel(slide-1);
}, CHANGE_WAIT);
}
}
$('.carousel-wrap').mwCarousel();
Solution
The first slide actually never moves (last one visible) so that one is set to position: static and all works nicely.
I think by just changing your CSS you're actually there:
.carousel-wrap {
position: relative;
overflow:hidden;
height:80%;
width:90%;
}
Demo: http://jsfiddle.net/robschmuecker/j35fy/2/
Discovered the solution is in fact simple, as the first slide in the DOM (the last you see) never actually moves itself I can set that one slide to be position: static and thus the carousel wrap will set it's height accordingly.
http://jsfiddle.net/j35fy/7/
.container {
background: aliceblue;
padding: 3em;
}
.carousel-wrap {
position: relative;
overflow:hidden;
}
.carousel-item:first-child {
position:static;
}
.carousel-item {
position: absolute;
top: 0;
width: 100%;
}
img {
width: 100%;
}
Related
Using a code snippet I found online https://codepen.io/mattyfours/pen/LNgOWx
I made slight modifications and now, although the scroll/fixed functionality works, my 'fixed' side jumps when scrolling. I added 'background-size: contain' onto the fixed side which only works when scrolling has commenced However, on page load/ when no scrolling has occurred the image remains at its full-size meaning once scrolling begins the image goes from full width to 'contained' and created a jump.
Github:
https://github.com/tavimba/fixed-scroll
The issue can be seen in about.html
javascript:
var window_height;
var header_height;
var doc_height;
var posTop_sticky1;
var posBottom_sticky1;
var posTop_s2;
var posBottom_s2;
$(document).ready(function() {
getValues();
});
$(window).scroll(function(event) {
var scroll = $(window).scrollTop();
if (scroll < posTop_sticky1) {
$('.sticky').removeClass('fixy');
$('.sticky').removeClass('bottom');
}
if (scroll > posTop_sticky1) {
$('.sticky').removeClass('fixy');
$('.sticky').removeClass('bottom');
$('#sticky1 .sticky').addClass('fixy');
}
if (scroll > posBottom_sticky1) {
$('.sticky').removeClass('fixy');
$('.sticky').removeClass('bottom');
$('#sticky1 .sticky').addClass('bottom');
$('.bottom').css({
'max-height': window_height + 'px'
});
}
if (scroll > posTop_s2 && scroll < posBottom_s2) {
$('.sticky').removeClass('fixy');
$('.sticky').removeClass('bottom');
$('#s2 .sticky').addClass('fixy');
}
});
function getValues() {
window_height = $(window).height();
doc_height = $(document).height();
header_height = $('header').height();
//get heights first
var height_sticky1 = $('#sticky1').height();
var height_s2 = $('#s2').height();
//get top position second
posTop_sticky1 = header_height;
posTop_s2 = posTop_sticky1 + height_sticky1;
//get bottom position 3rd
posBottom_sticky1 = posTop_s2 - header_height;
posBottom_s2 = doc_height;
}
var rtime;
var timeout = false;
var delta = 200;
$(window).resize(function() {
rtime = new Date();
if (timeout === false) {
timeout = true;
setTimeout(resizeend, delta);
}
});
function resizeend() {
if (new Date() - rtime < delta) {
setTimeout(resizeend, delta);
} else {
timeout = false;
getValues();
}
}
CSS:
section {
width: 100%;
min-height: 100%;
float: left;
position: relative;
}
header {
width: 100%;
height: 5vw;
background-color: black;
float: left;
}
.sticky {
height: 100%;
width: 60%;
float: left;
position: absolute;
}
.sticky.fixy {
position: fixed;
top: 0;
left: 0;
}
.sticky.bottom {
position: absolute;
bottom: 0;
}
.green {
background-image: url(../imgs/front%20view.jpg);
background-size: cover;
}
.stickyBg {
background-image: url(../imgs/bonnets.jpg);
background-size: cover;
}
.scrolling {
float: right;
width: 50%;
padding: 20px;
h5 {
margin-left: 135px;
}
p {
margin-left: 135px;
font-size: 1em;
line-height: 1.5;
}
}
The jump is caused by change of position from absolute to fixed in combination with 100% height.
Besides, the above code has the following flaws:
Max-height assignment looks inconsistent.
JS assumes exactly two sections in HTML: #section1 and #s2. The third section won't work.
Window resize is handled incorrectly. The half-page-scroll logic consists of the two steps: CalculateVars and AdjustDOMElementPositions. For the smooth look these two actions have to be done in 3 cases: onDocumentLoad, onResize and onScroll.
Global vars.
Looks like, it needs some refactoring to get work ;)
<section class="js-half-page-scroll-section"><!-- Get rid of id -->
...
</section>
function halfPageScroll() {
let scrollTop, windowHeight, headerHeight; // and some other common vars
// Calculate vars
scrollTop = $(window).scrollTop();
//...
let repositionSection = function($section) {
let sectionHeight; // and some other vars related to current section
// Some logic
}
$('.js-half-page-scroll-section').each((i, el) => repositionSection($(el)));
}
$(document).ready(halfPageScroll);
$(window).scroll(halfPageScroll);
$(window).resize(halfPageScroll); // TODO: add some debounce wrapper with timeouts
I already tried to swap the functions on owl.carousel.js but it only works when the mouse moves.
var Autoplay = function(scope) {
this.core = scope;
this.core.options = $.extend({}, Autoplay.Defaults, this.core.options);
this.handlers = {
'translated.owl.carousel refreshed.owl.carousel': $.proxy(function() {
this.autoplay();
}, this),
'play.owl.autoplay': $.proxy(function(e, t, s) {
this.play(t, s);
}, this),
'stop.owl.autoplay': $.proxy(function() {
this.stop();
}, this),
'mouseover.owl.autoplay': $.proxy(function() {
if (this.core.settings.autoplayHoverPause) {
this.pause();
}
}, this),
'mouseleave.owl.autoplay': $.proxy(function() {
if (this.core.settings.autoplayHoverPause) {
this.autoplay();
}
}, this)
};
this.core.$element.on(this.handlers);};
Any idea how to make the slideshow work when mouse on top of the image?
When i had this problem, i used this code:
$('.owl-carousel .owl-dot').hover(function() {
$(this).click();
},
function() {}
);
and here my css for dots:
.owl-dot{
position: relative;
padding: 0;
height: 3px;
margin: 0;
float: left;
}
.owl-dot:before{
content: "";
position: absolute;
top: -168px; // the height of image
height: 168px; // the height of image
width: 100%;
left: 0;
z-index: 0;
}
when you will make hover to dots the image will be changing, that's all !!!
I've searched for similar question for quite a long time but all my searches gone in vain. Here is my code
<div class="footer-sidebar container" style="height:40px;"></div>
<button class="button">Click</button>
Now if someone clicks on button then my .container height should increase to 400px and if someone clicks on the same button it must back to 40px.
Edit: (Added CSS)
.footer-sidebar {
position: fixed;
z-index: 1500;
bottom: 0;
left: 0;
right: 0;
margin: 0 auto;
overflow: hidden;
}
Thanks
You could do that by adding a class to your div like this:
$('.button').on('click', function(){
$('.container').toggleClass('open');
}
Inline styles for this should be avoided. Use your css file and add something like this to it:
.container {
height: 40px;
}
.container.open {
height: 400px;
}
Javascript version (opposed to the previously added JQuery option):
Using booleans (tested):
var fullSize = false; // Used for toggling
var button = document.getElementsByClassName("button")[0]; // Get button
var div = document.getElementsByClassName("footer-sidebar")[0]; // Get div
button.onclick = function() {
if(fullSize) { div.style.bottom = 0 + "px"; fullSize = false; } // If div is already 400px...
else { div.style.bottom = -360 + "px"; fullSize = true; } // If div is already 40px...
};
Fiddle
Using classes (untested):
CSS:
.open {
height: 400px;
}
.closed {
height: 40px;
}
Javascript:
var button = document.getElementById("button"); // Get button
var div = document.getElementsByClassName("footer-sidebar container")[0]; // Get div
button.onclick = function() {
if(div.className = "closed") { div.className = "open" }
else if(div.className = "open") { div.className = "closed" }
else { div.className = "open" }
}
Hope this helps.
I want text to bounce of the left and right sides of a div tag (#header). It works fine when it bounces of the right, then goes back and hits the left. The problem is that after it hits the left and starts to go right again it never hits the right side. It just keeps going and the window scrollbar appears. It appears as soon as it hits the left side. It seems that the div tag.
var finishedGoingRight = false;
setInterval(function() {
slideText();
}, 10);
function slideText(){
if(!finishedGoingRight){
$('#header h1').css("right","-=1");
}else{
$('#header h1').css("left","-=1");
}
if($('#header h1').css("right") == "20px"){
finishedGoingRight = true;
}
if($('#header h1').css("left") == "485px"){
finishedGoingRight = false;
}
}
Hope I explained it clearly :)
Debugging your code revealed that $('#header h1').css("right") always equals "auto", unless you've set it explicitly somewhere.
This works:
http://jsfiddle.net/7z3a3/1/
var finishedGoingRight = false;
setInterval(function() { slideText(); }, 10);
function slideText() {
if (!finishedGoingRight) {
$('#header h1').css("left", "+=1");
} else {
$('#header h1').css("left", "-=1");
}
if ($('#header h1').position().left >= $('#header').width()-$('#header h1').width()) {
finishedGoingRight = true;
} else if ($('#header h1').position().left <= 0) {
finishedGoingRight = false;
}
}
Here's my solution using animate:
JS:
var inner = $('#inner'), widthInner = inner.width(), outer = $('#outer'), widthOuter = outer.width();
function animateRight() {
inner.animate({ left: widthOuter - widthInner }, 1000, function() {
animateLeft();
});
}
function animateLeft() {
inner.animate({ left: 0 }, 1000, function() {
animateRight();
});
}
animateRight();
HTML
<div id="outer"><h2 id="inner">Inner</h2></div>
CSS
div, h2 { border: 1px solid black; }
#outer { width: 300px; height: 200px; }
#inner { margin-top: 75px; width: 50px; position: relative; }
http://jsfiddle.net/rHEQA/2/
I'm trying to create a dialog window using the following CSS:
#blackOverlay {
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000000;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80);
-moz-opacity: 0.8;
-khtml-opacity: 0.8;
opacity: 0.8;
z-index: 1001;
}
#whiteOverlay {
display: block;
position: absolute;
top: 10%;
left: 10%;
width: 80%;
height: 80%;
z-index:2002;
overflow: auto;
background: #c4e982;
}
and the following JS:
var div = $("<div id='blackOverlay'></div");
$("body").prepend(div);
var div = $("<div id='whiteOverlay'></div");
div.html("Loading......");
var u = "myurl?function=example";
div.load(u);
$("body").prepend(div);
This works correctly in Firefox, Safari, Chrome and Opera.
Unfortunately it fails in IE, at least on version 8.0. The color/opacity is only applied to body and NOT on other DIV's. Instead of "hidding" everything behind the blackOverlay, everything (links, buttons, input fields, ...) is still usable although the loaded content is displayed correctly (in front, center of screen).
Any help is appreciated!
Thank you jduren for pointing me in the right direction. After attempting to handle it in similar way as described here I came up with the following workaround:
function shime() {
jQuery.each(jQuery.browser, function(i) {
if($.browser.msie){
$('div').each(function() {
$(this).addClass("shine");
});
}
});
}
function unshime() {
jQuery.each(jQuery.browser, function(i) {
if($.browser.msie){
$(".shine").each(function() {
$(this).removeClass("shine");
});
}
});
}
And the following CSS:
div.shine {
display: none;
}
I know that it's not the best solution, but I'm getting tired of running in circles due to IE "features".
You need to create what's called an iFrame shim. IE paints controls over everything that isn't windowed so you won't be able to handle this by CSS/HTML hacks alone.
Here is a quick overview of Iframe Shimming http://www.macridesweb.com/oltest/IframeShim.html
Also, the Mootools More library includes an iFrame shim Feature http://mootools.net/docs/more/Utilities/IframeShim as do most popular javascript frameworks that create overlayed UI elements.
This is the IFrame Shim class from mootools more library to give you an idea of what's involved, don't use this as it depends on other Mootoosl classes.
var IframeShim = new Class({
Implements: [Options, Events, Class.Occlude],
options: {
className: 'iframeShim',
src: 'javascript:false;document.write("");',
display: false,
zIndex: null,
margin: 0,
offset: {x: 0, y: 0},
browsers: (Browser.Engine.trident4 || (Browser.Engine.gecko && !Browser.Engine.gecko19 && Browser.Platform.mac))
},
property: 'IframeShim',
initialize: function(element, options){
this.element = document.id(element);
if (this.occlude()) return this.occluded;
this.setOptions(options);
this.makeShim();
return this;
},
makeShim: function(){
if(this.options.browsers){
var zIndex = this.element.getStyle('zIndex').toInt();
if (!zIndex){
zIndex = 1;
var pos = this.element.getStyle('position');
if (pos == 'static' || !pos) this.element.setStyle('position', 'relative');
this.element.setStyle('zIndex', zIndex);
}
zIndex = ($chk(this.options.zIndex) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1;
if (zIndex < 0) zIndex = 1;
this.shim = new Element('iframe', {
src: this.options.src,
scrolling: 'no',
frameborder: 0,
styles: {
zIndex: zIndex,
position: 'absolute',
border: 'none',
filter: 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'
},
'class': this.options.className
}).store('IframeShim', this);
var inject = (function(){
this.shim.inject(this.element, 'after');
this[this.options.display ? 'show' : 'hide']();
this.fireEvent('inject');
}).bind(this);
if (!IframeShim.ready) window.addEvent('load', inject);
else inject();
} else {
this.position = this.hide = this.show = this.dispose = $lambda(this);
}
},
position: function(){
if (!IframeShim.ready || !this.shim) return this;
var size = this.element.measure(function(){
return this.getSize();
});
if (this.options.margin != undefined){
size.x = size.x - (this.options.margin * 2);
size.y = size.y - (this.options.margin * 2);
this.options.offset.x += this.options.margin;
this.options.offset.y += this.options.margin;
}
this.shim.set({width: size.x, height: size.y}).position({
relativeTo: this.element,
offset: this.options.offset
});
return this;
},
hide: function(){
if (this.shim) this.shim.setStyle('display', 'none');
return this;
},
show: function(){
if (this.shim) this.shim.setStyle('display', 'block');
return this.position();
},
dispose: function(){
if (this.shim) this.shim.dispose();
return this;
},
destroy: function(){
if (this.shim) this.shim.destroy();
return this;
}
});
window.addEvent('load', function(){
IframeShim.ready = true;
});