I've been wrestling with this for way too long.
Problem: I'm trying to make the image slide off of screen when the button is pressed, which I have successfully done, but not adequately. There are two problems:
I don't want to hide overflow on the body to hide the horizontal scroll being triggered when the div moves off the screen.
When I click on the button for a second time, I want the div to slide in from the right back to the original position. I haven't been able to figure this one out. I know I can do it, but creating another css class, but I know there has to be an easier way.
JSFiddle
CSS:
#abs {
position: absolute;
height: 200px;
width: 200px;
background-color: grey;
left: 0;
top:0;
transition: transform 3s;
}
.open {
transform: translateX(1050px);
}
.hide {
display: none;
}
p {
text-align: center;
}
JS:
$('#clickMe').on('click', function(){
$('#abs').toggleClass('open');
if($("#abs").hasClass("open")) {
setTimeout(
function() {
$("#abs").hide();
},
2500);
} else {
$("#abs").show();
}
})
Hi Please refer to the fiddle.https://jsfiddle.net/cdx7zeo2/1/
I modified your code to use jQuery animate.
$('#clickMe').on('click', function(){
var right = parseInt($('#abs').css('left'));
console.log(right);
if(right === 0){
$( "#abs" ).animate({
left:'2500px'
}, 1500);
}else{
$( "#abs" ).animate({
left:'0px'
}, 1500);
}
})
Also modified the id test to have overflow-y hidden, so that you don't need to tough overflow property of body. Note, here we are not using open class anymore.
#test {
position: relative;
height: 500px;
width: 500px;
background-color: black;
overflow-y:hidden;
}
Related
When using a combination of jQuery and CSS to trigger my navbar to shrink on scroll, it get's buggy when you scroll back up to a certain position, I have linked a video as an example.
I have tried two different methods. The first is using $(window).scrollTop) with an if statement and a series of .addClass and .removeClass. The second thing I have tried is using $(window).scrollTop) with a series of .css dynamic style modifications. Both of these attempts render the same end result that is shown in this video https://youtu.be/YXKsrL1cghs .
My first jQuery attempt:
$(document).ready(function () {
$(window).on("scroll", function () {
if ($(window).scrollTop() >= 40) {
$(".navbar").removeClass("py-5");
$(".navbar").addClass("compressed");
} else {
$(".navbar").addClass("py-5");
$(".navbar").removeClass("compressed");
}
});
});
My second jQuery attempt:
$(document).ready(function () {
$(window).on("scroll", function () {
if ($(window).scrollTop() >= 40) {
$(".navbar").css({ "padding-top": "10px" });
$(".navbar").css({ "padding-bottom": "10px" });
} else {
$(".navbar").css({ "padding-top": "3rem" });
$(".navbar").css({ "padding-bottom": "3rem" });
}
});
});
My CSS:
.navbar.compressed {
padding-top: 10px;
padding-bottom: 10px;
}
My expected results would be a smooth scrolling fixed navbar that shrinks to a smaller size after scrolling beyond a certain point.
What actually occurs is that when you scroll down past a certain point, for 20px worth of height, it gets super buggy and starts bouncing up and down. Once you clear those 20 or so px it's perfectly fine, but when you scroll back up it acts the same within those 20px.
When watching the video, I noticed that your .navbar has transition: all .3s. It could be the reason that when you remove the class py-5 and add class compressed, it triggers the transition twice.
It would be helpful if you can provide the HTML markup and CSS as well.
The script is manipulating the DOM quite a lot. I am not sure if this is going to fix your problem but it might be a good idea to only change the classes if the have not yet been applied.
$(document).ready(function() {
$(window).on("scroll", function() {
let navbar = $(".navbar");
if ($(window).scrollTop() >= 40) {
if (navbar.hasClass("py-5")) {
navbar.removeClass("py-5");
navbar.addClass("compressed");
}
} else {
if (navbar.hasClass("compressed")) {
navbar.addClass("py-5");
navbar.removeClass("compressed");
}
}
});
});
body {
height: 10000px;
position: relative;
}
.navbar {
width: 100%;
position: fixed;
height: 50px;
top: 0;
transition: all .3s
}
.py-5 {
background-color: blue;
padding-top: 10px;
padding-bottom: 10px;
}
.compressed {
background-color: red;
padding-top: 0px;
padding-bottom: 0px;
}
<html>
<head></head>
<body>
<nav class="navbar py-5">Navigation</nav>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>
The problem:
I have a form with a button underneath it to submit (post) from data with jQuery ajax(). I want for the button to be replaced with a spinner (animated png) for the duration of server ajax call. But such a trivial task is impossible in css to do right.
What i have tried:
I have placed button and image inside a bootstrap row. Ox ajax call I have set button display to none and img display to block. But because this two are not of the same size makes the whole page flicker, breaks the positioning of other elements and so on.
Another idea was to try to place both elements on top of each other with absolute positioning. But, stupid as css is I cannot center it on the middle of the row.
Is there a way to position both elements on top of each other so I can control their visibility?
Please bear in mind that I cannot used absolute position in pixel, because this is a web page and I do not not how wide the browser will be, image can change in the future, text in the button can change in the future, all this things affect absolute size.
If there is another solution to my problem which would prevent the page from jumping up and down it would also be great.
EDIT
Link to one of fiddle experiments:
https://jsfiddle.net/ofb2qdt8/
.button {
position: relative;
margin: auto;
height: 50px;
width: 30px;
background: blue;
z-index: 1;
display: block;
}
.spinner {
position: relative;
margin: auto;
height: 30px;
width: 50px;
background:red;
z-index: 2;
}
This renders second element underneath on screen. Not on different z layer.
Experiment 2:
https://jsfiddle.net/ofb2qdt8/
.button {
position: absolute;
margin: auto;
height: 50px;
width: 30px;
background: blue;
z-index: 1;
display: block;
}
.spinner {
position: absolute;
margin: auto;
height: 30px;
width: 50px;
background:red;
z-index: 2;
}
This does not center both elements, and they are pushed to the top of the containing div. The element with less height should be centered.
Check this working demo: https://jsfiddle.net/ofb2qdt8/3/
Add in a few lines of jquery and update your css.
Position your loading div according to button div's position, width, height using jquery.
*Click the button to see loading div, and try to play the margin of the button to any pixel.
###JQUERY
$(document).ready(function () {
$('.c2').each(function () {
$(this).css({
'width': $(this).siblings('.c1').outerWidth(),
'height': $(this).siblings('.c1').outerHeight(),
'top': $(this).siblings('.c1').offset().top,
'left': $(this).siblings('.c1').offset().left
});
});
$('.c2').on('click', function () {
$(this).hide(0);
});
});
###CSS
.c1 {
margin: 100px auto;
width: 100px;
text-align: center;
padding: 5px 10px;
background: blue;
z-index: 1;
}
.c2 {
position: fixed;
text-align: center;
background: red;
z-index: 2;
cursor: pointer;
}
Rough, ready and untested:
HTML
<div>
<input type='submit' />
<img src="spinneyIMage.gif" />
</div>
CSS
div{ text-align: center; }
div img{ display: none; }
jQuery
$('submit').click(function(e){
e.preventDefault();
$(this).hide().next().show();
});
After the Ajax call completes reverse the above jQuery.
As I haven't been able to find a working solution I have reverted to my first idea which I discarded at first. Albeit with a little twist.
HTML
<div class="row>
<div id="container-button" class="col-xs-12>
<button id="button" onclick="button_OnClick(e)">submit form via ajax</button>
<img src="img/spinner.png" sytle="display: none" />
</div>
</div>
JS
function btnContact_OnClick() {
// show the soinner and hide the button
showSpinner();
$.ajax(
{
type: 'POST',
url: "someurl.com/target",
data: $("#form").serialize(),
dataType: "json",
complete: function() { hideSpinner();},
success: onAjaxSuccess,
error : onAjaxError
});
}
function hideSpinner() {
$("#spinner").hide();
$("#button").show();
// make container height non-fixed and content adjustable again
$("#container-button").height('auto');
}
function showSpinner() {
// THis is the trick !!!
// Make the container fixed height as it was before displaying spinner, so it does not change with content (spinner is not the same height as button
$("#container-button").height($("#container-button").height());
$("#button").hide();
$("#spinner").show();
}
This is not the perfect solution but the best I could make.
Drawbacks:
it is not clean, you have to use javasript to fix what is css layout
problem
it still causes a little flicker
the height of container while displaying spinner is dependant on button, this may cause clipping if spinner is too big
Very impressed with jQuery lightGallery, it's been a joy to use. As per the first example on the lightGallery website, Gallery with animated thumbnails (http://sachinchoolur.github.io/lightGallery/examples.html) I have moved navigation arrows to the sides but have left the thumbnails hidden.
#lg-gallery .thumb-cont .thumb-info {
display: none;
}
#lg-action {
position: static;
}
#lg-action a#lg-prev,
#lg-action a#lg-next {
margin-top: -14px !important;
position: absolute;
top: 50%;
z-index: 9999999;
font-size: 18px;
}
#lg-action a#lg-prev {
left: 18px;
}
#lg-action a#lg-next {
right: 18px;
}
I have moved the open thumbs button next to the gallery close button at the top right hand corner of the window, as follows.
#lg-action a.cl-thumb {
position: absolute;
top: 18px;
right: 50px;
z-index: 9999999;
}
So, how do I hook-up an open/close toggle for the thumbs using the thumbs button? I guess I need to look at the onOpen callback, but I'm not sure how to use it, something like this perhaps.
onOpen: function() {
$("#lg-action a.cl-thumb").on("click", function(e) {
e.preventDefault();
if ($("#lg-gallery").hasClass("open")) {
$("#lg-gallery .thumb-cont").slideDown();
$("#lg-gallery").removeClass('open');
}
return false;
});
}
This (obviously) does not work.
Solved this by adding a function to the onOpen callback. I added a class called 'open-toggle' (and set the required css) to #lg-gallery.open when the thumbs button is first clicked. The second click removes the 'open-toggle' and 'open' classes from #lg-gallery and re-sets the css.
onOpen: function() {
$("#lg-action a.cl-thumb").on("click", function() {
$gallery = $("#lg-gallery");
if ($gallery.hasClass("open-toggle")) {
$gallery.removeClass('open-toggle open');
$("#lg-gallery .lg-slide").css("padding-bottom", "0");
}
else {
$gallery.addClass("open-toggle");
$("#lg-gallery.open .lg-slide").css("padding-bottom", "120px");
}
});
}
EDIT
I found that the images don't get out of the way if you toggle the thumbs bar, but they do get out of the way for the example on the website. I opened up Firebug and found that the website example page has a file called base.css which contains the following line:
* {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
I added this line to my css and animated the padding-bottom so that the images didn't jump to size when the thumbs were toggled.
onOpen: function() {
$("#lg-action a.cl-thumb").on("click", function() {
$gallery = $("#lg-gallery");
if ($gallery.hasClass("open-toggle")) {
$("#lg-gallery .lg-slide").animate({
"padding-bottom": 0
}, 500);
$gallery.removeClass('open-toggle open');
}
else {
$("#lg-gallery.open .lg-slide").animate({
"padding-bottom": 120
}, 500);
$gallery.addClass("open-toggle");
}
});
}
Anyway, maybe this will point someone in the right direction.
When I fadeIn a div, and this animation finished, the background suddenly disappears (this time only in Firefox).
I have a container, with two nested elements in it. The second element has a negative margin, so it appears on top of the first.
My script:
jQuery(document).ready(function($) {
$(".second_element").hide();
$(".container").each(function () {
$(this).mouseover(function () {
$(this).children(".second_element").stop(true, true);
$(this).children(".second_element").fadeIn(250, 'linear');
});
$(this).mouseout(function () {
$(this).children(".second_element").stop(true, true);
$(this).children(".second_element").fadeOut(100, 'linear');
});
});
});
CSS:
.container{
width: 221px;
height: 202px;
display: block;
float: left;
position: relative;
}
.first_element {
height: 200px;
width: 219px;
}
.second_element {
display:none;
background: #fff !important;
margin-top: -51px;
width: 219px;
height: 50px;
}
And for clarity, this a HTML example
<td class="container">
<div id="first_element">...</div>
<div id="second_element">...</div>
</td>
My second problem is, that when my mouse is hovering above the second element, the function is executed again (so the second element fades out and in). While the second element is just IN the container
This is shorter, and also, for first run, it is better that hide target by fadeOut() instead of hide()
$(".caption").fadeOut(1);
$(".container").each(function() {
$(this).mouseover(function() {
$(".caption", this).stop().fadeIn(250);
});
$(this).mouseout(function() {
$(".caption", this).stop().fadeOut(250);
});
});
Complementing the last comments; I got it. I tried it in several ways, and also with the caption to position: absolute, but instead I had to set the first element to position: absolute... now it works (however not with fading, but this is fine). I thank you very much for all your help and support!
I have a div which currently has a static background image.
I need to create a slideshow of background images for this div.
I am able to achieve this by just setting a timeout and then changing the background image in the CSS but this is not very elegant.
I would ideally like to fade the background images out and in, but the div contains other page elements so I can not alter the opacity in any way.
Does anyone know of a good way to do this using jquery??
Here's some code which fades out/in but fades out the contents of the div too.
$("#slideshow").fadeOut(5000, function(){
$("#slideshow").css('background-image','url(myImage.jpg)');
$("#slideshow").fadeIn(5000);
});
HTML:
<div class="slideshow"></div>
CSS:
.slideshow
{
position: relative;
width: 350px;
height: 150px;
}
.slideshow img
{
position: absolute;
width: 350px;
height: 150px;
z-index:-1;
}
jQuery
var images=new Array('http://placehold.it/250x150','http://placehold.it/250x150/123456','http://placehold.it/250x150/dbca98');
var nextimage=0;
doSlideshow();
function doSlideshow()
{
if($('.slideshowimage').length!=0)
{
$('.slideshowimage').fadeOut(500,function(){slideshowFadeIn();$(this).remove()});
}
else
{
slideshowFadeIn();
}
}
function slideshowFadeIn()
{
$('.slideshow').prepend($('<img class="slideshowimage" src="'+images[nextimage++]+'" style="display:none">').fadeIn(500,function(){setTimeout(doSlideshow,1000);}));
if(nextimage>=images.length)
nextimage=0;
}
jsfiddle Demo
How about adding a thumbs pagination list, to update the background image on click, and then, a second or two, and it starts fading in and out with the next bg img automatically?
HTML:
<div class="slideshow">
<h1>Text</h1>
<input type="button" value="Hello" />
</div>
<ul>
<li><img src="http://placehold.it/50x50"></li>
<li><img src="http://placehold.it/50x50/123456"></li>
<li><img src="http://placehold.it/50x50/dbca98"></li>
</ul>
CSS:
.slideshow
{
position: relative;
width: 350px;
height: 150px;
}
.slideshow img
{
position: absolute;
width: 350px;
height: 150px;
z-index:-1;
}
ul {position: absolute; top: 125px; left: 75px;}
li {
float: left;
border: 1px solid #000;
margin: 15px;
}
Javascript:
var images=new Array('http://placehold.it/250x150','http://placehold.it/250x150/123456','http://placehold.it/250x150/dbca98');
var nextimage=0;
doSlideshow();
function doSlideshow()
{
if($('.slideshowimage').length!=0)
{
$('.slideshowimage').fadeOut(500,function(){slideshowFadeIn();$(this).remove()});
}
else
{
slideshowFadeIn();
}
}
function slideshowFadeIn()
{
$('.slideshow').prepend($('<img class="slideshowimage" src="'+images[nextimage++]+'" style="display:none">').fadeIn(500,function(){setTimeout(doSlideshow,1000);}));
if(nextimage>=images.length)
nextimage=0;
}
See it all together at http://jsfiddle.net/tatygrassini/R4ZHX/75/.
Instead of just changing the background image, you could first call
fadeOut()
then change source, and then call
fadeIn()
something like...
$('#image').fadeOut(500, function() {
$(this).attr('src', 'new-image.png')
.load(function() {
$(this).fadeIn();
});
});
To use a variety of images, there are a number of solutions, but you could simply iterate through a list of them.
You can create an positioned absolutely and with a slider plugin change the images contained in the div. Otherwize you have to sprite the background. I achieved this with the Jquery Tools tabs plugin.
$(".slidetabs").tabs(".images > div", {
// enable "cross-fading" effect
effect: 'fade',
fadeOutSpeed: "slow",
// start from the beginning after the last tab
rotate: true
// use the slideshow plugin. It accepts its own configuration
}).slideshow();
Here is a solution that not only addresses your problem, but will also solve some other problems as well. Create another DIV on your DOM as an overlay, and execute your fade functions on this DIV only. It will appear as though the content is fading in / out. This approach is also more performant, as you are only fading a single DIV instead of multiple elements. Here is an example:
$('#containeroverlay').width($('#container').width()).height($('#container').height()).fadeIn('normal', function() {
// Step 1: change your content underneath the hidden div
// Step 2: hide the overlay
$('#containeroverlay').fadeOut('normal');
})
Most importantly, this approach will work in IE6-8 without screwing up the font aliasing of elements you may have on the div.