Jquery height return false values - javascript

I'am serching solution in google. And saw some solutions to this but noone help me. When i asking in chrome about height(). It returns me true value, it's 1627. But when i write in script where it will be changed to this. It returns me 1290. And i don't know why. How can i return true height from document (because window can't help me). I'am trying with height(), innerHeight() and outerHeight().
Here is a screen with my problem: http://www.speedyshare.com/hTUDt/1.png
$(document).ready(function(){
var menu = $("#menu").height();
var content = $("body").outerHeight(true);
if(menu != content)
{
menu = content;
$("#menu").css({'height':menu+'px'});
}
});
or like this
$(document).ready(function () {
var menu = $('#menu');
$(window).resize(function () {
var height = $('#body').height();
menu.css({
'height': height + 'px',
});
}).trigger('resize');
});
It's doesn't work.
In css i have :
#menu {
width: 15%;
/*height: 100%;*/
background: #F5F5F5;
padding-top: 1%;
/* padding-bottom: 1%; */
font-size: 1.6rem;
font-family: 'Lato';
font-weight: 300;
color: #969696;
position: absolute;
border-right: 1px solid #c5c5c5;
box-shadow: 0px -1px 0px 1px #fff;
}
In firebug i see what's happend. He takes a height value 1290 (I don't know why) instead real height of body or 1626

$('element').css('height', 'auto !important')
Note: auto can be 100% or a fixed number (i.e '1626px')

Related

How to put an element in hover state when scrolled down using javascript

I am trying to make a div element which when scrolled down will change properties drastically. Here is the codepen example of how I want it to work.
Instead of hover I want it so that when scrolled down, the page wide div will turn into that little circle div which when clicked will function as a back to the top button. It doesn't matter if more classes are added or anything of that sort. I am very new to js and I tried a few things and also googled about it, I got the scroll code from w3school's how to make a back to top button guide which specifies that when scrolled down by 20px the code would react, but I don't know how to turn the JavaScript to JS when scrolled down along with the transformation of the div.
Thanks in advance
I think you want to implement scroll to top functionality, very common these days in most of the web app.
You need to keep below things and design that feature.
There is one header, that should have a reference ID with hash to scroll back to top
Create a button that will always static position (JS) button, will show up when user scroll the window
Bind click event on the button that scroll back to top
Here is the you can see this implementation and use it.
.html
<h1 class="intro-copy">
Scroll down to use this simple back-to-top button made with modern vanilla javascript.
</h1>
<a class="top-link hide" href="" id="js-top">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6"><path d="M12 6H0l6-6z"/></svg>
<span class="screen-reader-text">Back to top</span>
</a>
.css
body {
height: 2000px;
position: relative;
}
.intro-copy {
padding: 1em;
margin: 50vh auto;
max-width: 15em;
font-family: Helvetica;
font-weight: lighter;
font-size: 2em;
line-height: 1.2;
text-align: center;
}
.top-link {
transition: all .25s ease-in-out;
position: fixed;
bottom: 0;
right: 0;
display: inline-flex;
cursor: pointer;
align-items: center;
justify-content: center;
margin: 0 3em 3em 0;
border-radius: 50%;
padding: .25em;
width: 80px;
height: 80px;
background-color: #F8F8F8;
&.show {
visibility: visible;
opacity: 1;
}
&.hide {
visibility: hidden;
opacity: 0;
}
svg {
fill: #000;
width: 24px;
height: 12px;
}
&:hover {
background-color: #E8E8E8;
svg {
fill: #000000;
}
}
}
// Text meant only for screen readers.
.screen-reader-text {
position: absolute;
clip-path: inset(50%);
margin: -1px;
border: 0;
padding: 0;
width: 1px;
height: 1px;
overflow: hidden;
word-wrap: normal !important;
clip: rect(1px, 1px, 1px, 1px);
&:focus {
display: block;
top: 5px;
left: 5px;
z-index: 100000; // Above WP toolbar
clip-path: none;
background-color: #eee;
padding: 15px 23px 14px;
width: auto;
height: auto;
text-decoration: none;
line-height: normal;
color: #444;
font-size: 1em;
clip: auto !important;
}
}
JS:
// Set a variable for our button element.
const scrollToTopButton = document.getElementById('js-top');
// Let's set up a function that shows our scroll-to-top button if we scroll beyond the height of the initial window.
const scrollFunc = () => {
// Get the current scroll value
let y = window.scrollY;
// If the scroll value is greater than the window height, let's add a class to the scroll-to-top button to show it!
if (y > 0) {
scrollToTopButton.className = "top-link show";
} else {
scrollToTopButton.className = "top-link hide";
}
};
window.addEventListener("scroll", scrollFunc);
const scrollToTop = () => {
// Let's set a variable for the number of pixels we are from the top of the document.
const c = document.documentElement.scrollTop || document.body.scrollTop;
// If that number is greater than 0, we'll scroll back to 0, or the top of the document.
// We'll also animate that scroll with requestAnimationFrame:
// https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
// ScrollTo takes an x and a y coordinate.
// Increase the '10' value to get a smoother/slower scroll!
window.scrollTo(0, c - c / 10);
}
};
// When the button is clicked, run our ScrolltoTop function above!
scrollToTopButton.onclick = function(e) {
e.preventDefault();
scrollToTop();
}

How can I customised alert boxes for both mobile and desktop display from this code?

I am quite new to JS and, although enjoying, am finding it difficult to get syntax correct.
I wanted to customise my alert boxes with my own version of them, and it seemed easy enough. I found a neat tutorial here and ran it successfully, did a bit of styling and found it wasn't very mobile friendly.
The main issue stems from two parts of the code, CSS here:
#dialogbox {
display: none;
position: fixed;
background: #0b6623;
border-radius: 7px;
width: 550px;
z-index: 2001;
}
Firstly, the dialogue box is set to 550px, which is fine on a large screen. The real issue occurs when you run the script which sets the position of the dialogue box:
function CustomAlert(){
this.render = function(dialog){
let winW = window.innerWidth;
let winH = window.innerHeight;
let dialogoverlay = document.getElementById('dialogoverlay');
let dialogbox = document.getElementById('dialogbox');
dialogoverlay.style.display = "block";
dialogoverlay.style.height = winH+"px";
dialogbox.style.left = (winW/2) - (550 * .5)+"px";
dialogbox.style.top = "100px";
dialogbox.style.display = "block";
document.getElementById('dialogboxhead').innerHTML = '<strong>Share your score to Facebook</strong>';
document.getElementById('dialogboxbody').innerHTML = dialog;
document.getElementById('dialogboxfoot').innerHTML = '<button class="btn btn-danger" onclick="Alert.ok()"><i class="far fa-times-circle"></i> Close</button>';
}
this.ok = function(){
document.getElementById('dialogbox').style.display = "none";
document.getElementById('dialogoverlay').style.display = "none";
}
}
let Alert = new CustomAlert();
There are lines there that set the box directly into the centre of the screen.
My question is - I still want centre screen but I want the dialogue box to be fluid and shrink down to size on a mobile phone. Does anyone have suggestions on how to do this with that CSS?
The full script is available here: https://www.developphp.com/video/JavaScript/Custom-Alert-Box-Programming-Tutorial
Thanks kindly :)
Okay last attempt to help here.
The sample code below behaves exactly the same as the built in browser alert dialog boxes. It puts the box in the middle, auto sizes according to the content, and anything else on the page is NOT clickable or editable until the dialog box is closed. Well I wrote is a while back and I don't see any difference. It should work on any device so use it, change it, style it however you want. Note the "DO NOT CHANGE" comments. Changing that defeats the purpose. You do need the JQuery.js so download the the latest one here https://jquery.com/download/.
<!DOCTYPE html>
<html lang="en">
<head>
<style type="text/css">
.main-container{
display: flex; /* DO NOT CHANGE */
height: 100vh; /* DO NOT CHANGE */
width: 100%; /* DO NOT CHANGE */
}
.c-message{
display: flex; /* DO NOT CHANGE */
position: fixed; /* DO NOT CHANGE */
top: 0px; /* DO NOT CHANGE */
left: 0px; /* DO NOT CHANGE */
width: 100%; /* DO NOT CHANGE */
height: 100%; /* DO NOT CHANGE */
}
.c-msgbox{
padding: 30px;
text-align: center;
margin: auto; /* DO NOT CHANGE */
background-color: #e4e4e4;
border-radius: 4px;
border: 1px solid #adadad;
-webkit-box-shadow: 0px 0px 50px rgba(0, 0, 0, 0.60);
-moz-box-shadow: 0px 0px 50px rgba(0, 0, 0, 0.60);
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.40);
}
.standerd-button2{
border: none;
font-family: arial,helvetica,clean,sans-serif;
font-size: 10px;
font-weight: 600;
color: white;
background: #1A709F;
padding: 3px;
text-align: center;
vertical-align: middle;
-webkit-border-radius: 3px;
width: max-content;
min-width: 50px;
margin: 2px;
}
.standerd-button2:hover{
background: crimson;
cursor: default;
}
</style>
<script type="text/javascript" src="JQuery.js"></script>
</head>
<body>
<div class="main-container">
<div>
<a id="ok" href="#">Normal Alert</a>
<br>
<a id="yn" href="#">Yes/No Alert</a>
</div>
<div>
<script type="text/javascript">
$.fn.CustomAlert = function (options, callback) {
var settings = $.extend({
message: null,
detail: null,
yesno: false,
okaytext: null,
yestext: null,
notext: null
}, options);
var frm = "";
detail = "<b>" + settings.detail + "</b>";
message = "<b>" + settings.message + "</b>";
if (settings.detail === null) {
detail = "";
};
frm = frm + message + "<div style='text-align: left; margin-top: 15px; margin-bottom: 15px;'>" + detail + "</div>";
if (settings.yesno === false) {
frm = frm + "<input id='ok' type='button' value='" + settings.okaytext + "' class='standerd-button2' />";
} else {
frm = frm + "<div><input id='yes' type='button' value='" + settings.yestext + "' name='yes' class='standerd-button2' />" +
"<input id='no' type='button' value='" + settings.notext + "' name='no' class='standerd-button2' /></div>";
};
var frmesg = "<div id='cmessage' name='cmessage' class='c-message'>" +
"<div class='c-msgbox'>" +
"<form>" + frm + "</form>" +
"</div>" +
"</div>";
$(".main-container").append(frmesg);
if (!settings.yesno) {
$("#cmessage #ok").click(function () {
$("#cmessage").remove();
callback(false);
});
} else {
$("#cmessage #yes").click(function () {
$("#cmessage").remove();
callback(true);
});
$("#cmessage #no").click(function () {
$("#cmessage").remove();
callback(false);
});
};
};
$("#yn").click(function(){
$().CustomAlert({message: "<div style='text-align: left;'><p><b>Confirmation Alert</b></p></div>",
yestext: "Yes",
notext: "No",
yesno: true},
function(success){
if (success) {
null;
// Do something
} else {
null;
// Do something else
};
});
});
$("#ok").click(function(){
$().CustomAlert({message: "<div style='text-align: left;'><p><b>Bla bla bla</b></p></div>",
okaytext: "Continue",
yesno: false},
function(success){
if (success) {
null;
// Do something
};
});
});
</script>
</body>
You can use Media Queries. Give your modal dialog a different style on mobile, tablet and desktop if needed. https://www.w3schools.com/css/css_rwd_mediaqueries.asp
#media only screen and (min-width: 480px) {
#dialogbox {
/* your mobile styles */
}
}
#media only screen and (min-width: 720px) {
#dialogbox {
/* your mobile styles */
}
}
#dialogbox {
/* your normal styles */
}
I stuck with this function in JS but removed one line and its variable:
let winW = window.innerWidth;
dialogbox.style.left = (winW/2) - (550 * .5)+"px";
The CSS had some changes too:
#dialogbox {
display: none;
position: fixed;
margin-top: 17.5%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #0b6623;
border-radius: 7px;
width: 67.7%;
max-width: 550px;
z-index: 2001;
}
It's not perfect, granted, but it is 10s of 1000s of times better than before.
For those wondering why a z-index of 2001, because I am using bootstrap modals and they have a z-index of 1040 or so. And the z-index of 2000 is taken up by the white overlay (see code in OP).
This is what I suggest, if what I think you want is correct.
Copy this below and test it.
If it is not what you need, sorry, just tried to help.
<!DOCTYPE html>
<html lang="en">
<head>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.main-container{
display: flex;
height: 100vh;
width: 100%;
}
.dialogbox{
display: flex;
margin: auto;
padding: 20px;
border-radius: 4px;
border: 1px solid #adadad;
-webkit-box-shadow: 0px 0px 50px rgba(0, 0, 0, 0.60);
-moz-box-shadow: 0px 0px 50px rgba(0, 0, 0, 0.60);
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.40);
}
.dialogbox .dialogtext{
margin: auto;
}
</style>
</head>
<body>
<div class="main-container">
<div class="dialogbox">
<span class="dialogtext">
<h3>Some text</h3>
</span>
</div>
<div>
</body>
Note: this answer has become somewhat discursive, in terms of answering the question as set, the use of CSS vw/vh and media queries as recommended by other contributors will solve the immediate problem. I have left this answer here though as pondering the question raised additional issues of 'what are we trying to do with an alert function?'
The alert function in Javascript has some characteristics that you cannot emulate in your own Javascript, but you can get close.
The main thing about alert is that it is just that, the user is informed no matter what else is going on so it sits on top. It can get 'lost' in the middle of a wide window if the window is partially off the screen.
On most mobiles though it's a bit better because normally if your code is running the window will be at least partially visible on the screen.
For your immediate question, the best bet for making the alert box be visible, is to use the viewport dimensions plus fixed (as you have done)- the given code uses window dimensions and that just isn't going to work in all cases - the alert box could be way off the screen - for example if the window is representing a long scroll which the user is scrolling through.
Second you want the box to be visible above anything else that's in your window, so setting the z-index in CSS to something higher than you will ever use in the rest of your code is needed. (Does anyone know if all browsers would accept Number.MAX_SAFE_INTEGER - for ultimate safety though that would be quite extreme)
Third you need to fix the alert box in the viewport so the user can't scroll away from it - you want the user to respond so you know they have seen the message and can't completely ignore it.
Fourth is the question of blocking. A JS alert does this, but is it wise to have our own function do it and/or replace the native alert totally with our own function. Probably not, at some point you may want the real alert to work so might be best to leave it alone.
Replacing window.width with vw will make the box responsive - but it could be unreadable at small screens or not large enough on enormous ones. Fortunately CSS has media queries so you can use them with breakpoints at the most common sizes of screen to decide the width of your alert box (you need to let the height be scrollable as you don't know how much info is to be shown).
Note: the code below uses different naming from the original question to prevent confusion as the use of some of the elements is slightly different.
Moving the styling and especially the sizing decisions totally to CSS the JS can become something like:
function myAlert(alertMessage){
document.getElementById('alertinfo').innerHTML = alertMessage;
document.getElementById('alertoverlay').style.display = "block";
}
function myRemove(event) {
event.preventDefault();
event.stopPropagation();
document.getElementById('alertoverlay').style.display = 'none';
}
CSS
#alertoverlay {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999999;
background-color: rgba(0,0,0,0.2);
overflow: hidden;
display: none;
}
#alertbox {
font-family: Arial, Helvetica, sans-serif;
width : 100vw;
height: auto;
overflow-y: auto;
position: fixed;
font-size: 10px;
background-color: white;
text-align: center;
}
#alertheader {
font-size: 3em;
}
#alertinfo {
margin-top: 20px;
}
#alertokbox {
width: 44px;
height: 44px !important;
float: right;
margin: 10px;
border-style: solid;
border-radius: 10%;
vertical-align: center;
}
#alertok {
margin-top: 14px;
}
#media only screen and (min-width: 550px) {
#alertbox {
width: 550px;
left: 50vw;
margin-left: -275px;
font-size: 16px;
}
}
#media only screen and (min-width: 1600px) {
#alertbox {
width: 30vw;
left: 50vw;
margin-left: -15vw;
font-size: 1vw;
}
}
HTML
<div id="alertoverlay">
<div id="alertbox">
<div id="alertheader">Alert</div>
<div id="alertinfo"></div>
<div id="alertokbox" onclick="myRemove(event);"></div>
<div id="alertok">OK</div>
</div>
</div>
You can have as many media 'breakpoints' as you like - for example if you are coding for a huge display screen right down to the smallest smart phone you will need to think about just how big you want your box to be.
For centering to work (the left and margin-left settings in the CSS) you will need to have the alert box in a div which is fixed with width the width of the screen - so left: 0; right: 0;
<!DOCTYPE html>
<html>
<head>
<style>
#alertoverlay {
position: fixed;
left: 0;
top:0;
bottom:0;
right:0;
z-index: 999999;
background-color: rgba(0,0,0,0.2);
overflow: hidden;
display:none;
}
#alertbox {
font-family: Arial, Helvetica, sans-serif;
width : 100vw;
height: auto;
overflow-y: auto;
position: fixed;
font-size: 10px;
background-color:white;
text-align:center;
}
#alertheader {
font-size: 3em;
}
#alertinfo {
margin-top: 20px;
}
#alertokbox {
width:44px;
height: 44px !important;
float:right;
margin: 10px;
border-style: solid;
border-radius: 10%;
vertical-align:center;
}
#alertok {
margin-top:14px;
}
#media only screen and (min-width: 550px) {
#alertbox {
width: 550px;
left:50vw;
margin-left:-275px;
font-size: 16px;
}
}
#media only screen and (min-width: 1600px) {
#alertbox {
width: 30vw;
left: 50vw;
margin-left: -15vw;
font-size: 1vw;
}
}
#application {
width:2000px;
height:2000px;
background-color: white;
}
</style>
</head>
<body>
<div id="application">
<button onclick="myAlert('Read this important message then click OK');">Click me to show an alert</button>
</div>
<div id="alertoverlay">
<div id="alertbox">
<div id="alertheader">Alert</div>
<div id="alertinfo"></div>
<div id="alertokbox" onclick="myRemove(event);"><div id="alertok">OK</div></div>
</div>
</div>
<script>
function myAlert(alertMessage){
document.getElementById('alertinfo').innerHTML = alertMessage;
document.getElementById('alertoverlay').style.display = "block";
}
function myRemove(event) {
event.preventDefault();
event.stopPropagation();
document.getElementById('alertoverlay').style.display='none';
}
</script>
</body>
</html>
Okay. This part is the function
$.fn.CustomAlert = function (options, callback) {
var settings = $.extend({
message: null,
detail: null,
yesno: false,
okaytext: null,
yestext: null,
notext: null
}, options);
....
....
As you can see it takes a few parameters. 1) Is the message that will be centered. 2) Message detail(optional that will be aligned to the left. 3) yesno is either true or false. True for confirmation dialog or false for just an ok dialog. 4) okaytext is usually "Okay" or "Continue" if yesno is false. 5) yestext is usually "Yes" if yesno is true. 6) notext is usually "No if yesno is true.
All are optional but with a little logic you will figure out what to pass when.
The following is the click event and then the function call.
$("#yn").click(function(){
$().CustomAlert({message: "<div style='text-align: left;'><p><b>Confirmation Alert</b></p></div>",
yestext: "Yes",
notext: "No",
yesno: true},
function(success){
if (success) {
null;
// Do something
} else {
null;
// Do something else
};
});
});
$("#yn").click(function(){ // This is the event when that anchor with the id of "yn" is clicked. By the parameters you can also see that it is confirmation dialog.
Make sense?
I recommend spending a little time learning JQuery. It is not so difficult and very powerful. It saves you a lot of coding. Took me less then a day, and that just from w3schoole. Try not using the plugins and JQuery UI. Rather write your own plugins as I did. This code is all from my lib. It just helps to understand it better. Also I do not recommend using bootstrap, not that there is anything wrong with it, but doing your own CSS3 stylesheets empowers you to what you want. That is just my opinion.
Use vh and vw.
These are view width and height, relative to the browser window.
One unit equals 1% of the browser width or height.
Use vh and vw if you want to set specific width and heights.
But I would suggest having all your content in a main div with a css style "display: flex;" and your actual dialogue box(div) size not specified but just with a css property of "margin: auto;".
This will center it and automatically be sized according to your content in the box.
But then again, if you want to specify a size you can still then use vw and vh.
Up to you.

Jquery Popup not centered

I'm developing my website and I have a problem with the display of my popups. When picture is clicked, a function is called in order to put the picture in a popup. The probleme is when I click for the first time on the picture, it is not centered in the window and for the second time it's centered. It's weird, maybe the computation of the margin-top and margin-left is not well in my function.
JS :
function popup(rel, size){
var popID = rel; //Find popup
var popWidth = size; //find width
//make display the popup
$('#' + popID).fadeIn().css({ 'width': popWidth});
//Releasing of margin, that allow to center the window
var popMargTop = ($('#' + popID).height()+20) / 2;
var popMargLeft = ($('#' + popID).width()+20) / 2;
//Apply Margin to Popup
$('#' + popID).css({
'margin-top' : -popMargTop,
'margin-left' : -popMargLeft
});
// appearance of the background - .css({'filter' : 'alpha(opacity=80)'}) to correct bugs of oldest version of IE
$('body').append('<div id="fade"></div>');
$('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn();
return false;
}
HTML :
<div id="photoPopup" class="popup_block">
</div>
CSS :
h1#titlePopup {
margin-top: -50px;
color: white;
text-shadow: 0px 0px 9px black;
}
div#photoPopup {
padding: 0px 0px 0px 0px;
}
#fade { /*--Black opaque mask background--*/
display: none; /*--default mask--*/
background: #000;
position: fixed; left: 0; top: 0;
width: 100%; height: 100%;
opacity: .4;
z-index: 9999;
}
.popup_block{
display: none;
background: #fff;
padding: 20px;
border: 10px solid #ddd;
float: left;
font-size: 1.2em;
position: fixed;
top: 50%;
left: 50%;
z-index: 99999;
-webkit-box-shadow: 0px 0px 20px #000;
-moz-box-shadow: 0px 0px 20px #000;
box-shadow: 0px 0px 20px #000;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 5px;
}
/*--position fixed for IE6--*/
*html #fade {
position: absolute;
}
*html .popup_block {
position: absolute;
}
If you want see the problem into the page "photo" : http://manuelmenneveux.pusku.com
Thank you anyway for your help :)
For people who have the same problem than me I found the solution, it's because the popup is loaded before the picture is loaded, so the position is made depending to the size of popup. As the popup is empty before the loading of picture, the position is computed.
Sounds like the image hasn't loaded and the centering relies on the image dimensions for that.
One possible solution is to get the image source from the image tag and load it into a dummy image node. Then you would check the dimensions on that dummy image node. You could either use those dimensions directly and size and center the div or calculate the aspect ratio and set the height or width to 100% and then center the div. Then you'd finally load the image inside.
Here's some code that might get you started.
Example HTML
<!-- Store image with data-src to prevent image from loading (if you want) -->
<img data-src='img.png'>
Example jQuery
// Image source
var imageSource = $('img').attr(imageSourceAttribute);
// Create image element
$('<img>').attr('src', imageSource).load(function() {
// Native image dimensions
// Note: $(this) won't work on in-memory images
var nativeWidth = this.width,
nativeHeight = this.height;
// ... Do more things ...
// Load image
$('image').attr('src', imageSource);
});

Span Text Hidden by Animated DIV Despite z-index

I'm working on a hobby project of mine -- it's something of a glorified RSS feed reader/grabber. I've been able to get most things working, but for some reason I cannot get the text in a certain span to be drawn above an animated div.
When a feed is grabbed, certain operations are performed before displaying the results. During this time, I keep track of the progress and display them in an animated "progress bar" div. All of the sub-operations each have their own progress bars, and they all work correctly (text on top of bar), but the final progress bar (overall progress) does not layer the text correctly.
I created a simple mock-up in JSFiddle to give an example of my problem.
$('#progress-total-box').bind('click', draw);
function draw() {
if (($('#progress-totalbar-fill').css('width')) == "0px") {
$('#progress-total-box').unbind();
$('#progress-totalbar-fill').animate({width: '100%'}, 2000, function() {
var description = document.createElement('span');
$(description).attr('id', '#progress-total-text');
$(description).html('100%');
$('#progress-totalbar-empty').append(description);
$('#progress-total-box').bind('click', draw);
});
}
else {
$('#progress-total-box').unbind();
$('#progress-totalbar-fill').animate({width: 0}, 2000, function() {
document.getElementById('progress-totalbar-empty').innerHTML = '';
$('#progress-total-box').bind('click', draw);
});
}
}
The style/position/etc is purely for sake of demonstration. In this example, when the grey loading bar div is clicked, it animates its width from 0% to 100% (or vice-versa). When the animation is complete, a new child span is created and appended to the 'empty bar' background div, wherein the total percentage is displayed (100%, in this case).
This span element is intentionally removed when the bar is reset.
Do you guys have any ideas as to what's going wrong, and how I can fix it?
I have encountered this error is present in both Chrome and Firefox.
Thanks in advance!
There are multiple problems here.
First off, you need to remove the # from this line
$(description).attr('id', 'progress-total-text');
The new span, was never getting the css it was supposed.
Second, you need to either change your markup or your css.
In this case, I updated the CSS, but the id name don't make sense anymore
body {
width: 100%;
height: 125px;
margin: 0;
}
#progress-category-box {
position: relative;
width: 100%;
height: 100%;
font-size: 0;
background-color: red;
}
#progress-total-box {
position: relative;
width: 100%;
height: 40px;
top: 32.5%;
float: right;
text-align: center;
background-color: #515A5C;
}
#progress-totalbar-empty {
position: relative;
width: 100%;
height: 100%;
border: 1px solid #97b0b1;
background-color: transparent;
z-index: 3;
}
#progress-totalbar-fill {
position: relative;
width: 0%;
height: 100%;
top: -42px;
border-left: 1px solid #97b0b1;
border-top: 1px solid #97b0b1;
border-bottom: 1px solid #97b0b1;
background-color: #00FF00;
z-index: 2;
}
#progress-total-text {
position: relative;
color: black;
top: 30%;
font-size: 15px;
z-index: 3;
}
Thing is, you were showing the animated div over the text.
So I put the text over the animation and put a transparent background behind it.
I applied the grey background to the container instead. I also changed it's height and applied height:100% to it's children.
Here's a full fiddle

Large background images causing lag while scrolling

The website I am building has 4 large background images that take up the entire height and width of the user's browser. They are implemented as CSS background divs. The problem is, when scrolling on larger screen sizes, it is very laggy and choppy. Scrolling between these images is done automatically via JavaScript when the user presses a button, so this is part of the core functionality of my website and I must find a way to prevent lag.
So far, I have tried preloading the images via JS and converting the images from PNG to JPEG (increase compression and decrease quality) server-side. Neither of these worked.
The minimum height of the image can be 630 pixels. How can I prevent lag while scrolling between sections?
Here's my code:
CSS:
body { height: 100%; margin: 0px; font-family: HelveticaNeue, Helvetica, Arial, sans-serif; }
.area { height: 630px; border: 0px solid red; background: repeat-x; margin-bottom: 0px; }
a { text-decoration: none; }
h1, h2, h3, h4, h5, h6 { font-family: Av, Helvetica, Arial, sans-serif; color: #292E37; font-weight: lighter; }
#top { position: fixed; width: 100%; height: 10%; background: #292E37; box-shadow: inset 0px -1px 5px #000; z-index: 1000; }
#navigation { float: right; height: 100%; }
#bottom { width: 100%; position: fixed; bottom: 0px; padding: 10px; background: #292E37; box-shadow: inset 0px 1px 5px #000; text-shadow: 0px 1px 0px #000; color: #fff; }
#sceneSelection { top: 20%; position: fixed; padding: 10px; }
#info { margin-top: 50px; margin-bottom: 50px; }
.box { margin-top: 50px; padding: 75px; background: #292E37; box-shadow: inset 0px 1px 5px #000; text-shadow: 0px 1px 0px #000; color: #fff; }
.nav { position: relative; top: 38%; height: 100%; margin-right: 35px; display: inline-block; color: #fff; text-shadow: 0px 1px #000; }
.nav:hover { color: #EA5555; }
.nimage { float: left; width: 16px; height: 16px; position: relative; top: 5%; left: -20%; }
.home { background: url(site_images/icons/nav/home.png); }
.pricing { background: url(site_images/icons/nav/pricing.png); }
.features { background: url(site_images/icons/nav/features.png); }
.blog { background: url(site_images/icons/nav/blog.png); }
.contact { background: url(site_images/icons/nav/contact.png); }
.about { background: url(site_images/icons/nav/us.png); }
.logo { font-size: 2em; text-shadow: 0px 1px #000; padding-top: 10px; padding-left: 15px; color: #EA5555; font-family: Av, Helvetica, Arial, sans-serif; }
.red { color: #EA5555; }
.white { color: #fff; text-shadow: 0px 1px 0px #000; font-weight: bold; }
.dark { color: #202020; }
.center { text-align: center; }
.left { text-align: left; }
.right { text-align: right; }
.larger { font-size: 1.25em; }
.buttoni { -webkit-border-radius: 2px; -moz-border-radius: 0px; border-radius: 4px; background: #ddd; display: block; color: #ccc; font-size: 14pt; height: 50px; text-align: right; margin: 10px; cursor: pointer; color: #505050; }
.buttoni:hover { background: #EA5555; color: #fff; }
.btext { padding: 15px; position: relative; top: 25%; }
.groundi { background: url(ground_button.png); }
.skyi { background: url(sky_button.png); }
.stratospherei { background: url(stratosphere_button.png); }
.spacei { background: url(space_button.png); }
.image { height: 50px; width: 50px; float: left; border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
li { color: #EA5555; }
li span { color: #505050; }
HTML:
<div class="space area" id="a4">
</div>
<div class="stratosphere area" id="a3">
</div>
<div class="sky area" id="a2">
</div>
<div class="ground area" id="a1">
</div>
JavaScript:
function scroll_to(id, speed, margin) {
$('html, body').animate({
scrollTop: $('#' + id).offset().top - margin
}, speed);
}
function match_height() {
var heights = [11, 630, 693, 756, 819, 882, 945, 1008, 1071, 1134, 1197, 1260, 1323, 1386, 1449, 1512, 1575, 1638, 1701, 1764, 1827, 1890, 1953, 2016, 2079, 2142, 2205, 2268, 2331, 2394, 2457, 2520];
var browsery = $(window).height();
var i = 0;
while(browsery > heights[i]) {
i++;
}
var h = heights[i];
$(".area").css("height", h + "px");
$(".area").css("width", "100%");
$(".ground").css("background", "url(scenes/ground/" + h + ".png)");
$(".sky").css("background", "url(scenes/sky/" + h + ".png)");
$(".stratosphere").css("background", "url(scenes/stratosphere/" + h + ".png)");
$(".space").css("background", "url(scenes/space/" + h + ".png)");
}
match_height();
var pos = 0;
$(".buttoni").click(function() {
var id = $(this).attr("id");
if(pos != id) {
scroll_to("a" + id, 2000, 0);
}
pos = id;
});
OP,
For browsers that support 3d transforms, e.g.: -webkit-transform, you could try the following:
your.div { -webkit-transform: translate3d(0,0,1px); }
Might not look like much, but doing the above causes the div in question to be hardware-accelerated.
Should you run into any flickering issues—they've been known to turn up in some cases—the following should sort you out:
your.div {
-webkit-transform: translate3d(0,0,1px);
-webkit-backface-visibility: hidden;
}
Via David Walsh - http://davidwalsh.name/translate3d
The use of translate3d pushes CSS animations into hardware acceleration. Even if you're looking to do a basic 2d translation, use translate3d for more power! If your animation is still flickering after switching to the transform above, you can use a few little-known CSS properties to try to fix the problem
Hope that helps.
As per my understanding, the issue and the solution drafted in the OP is two-fold:
initially, within the match_height() function, the OP author retrieves the images that best fits the screen height, so that upon completed animation the user sees one full background image.
after initial load, the user can navigate up and down the sections (with their respective background images) with the help of some buttons that trigger the scroll_to() function and its contained animation. Here is where the actual problem resides.
My efforts and the resulting fiddle focus on the scroll_to() function and the associated animation. I applied the following measures that, in conjunction, result in a (as per my subjective observation) 'smoother' scolling experience:
the original animation happened against 'html' and 'body', I'm reducing the jQuery selector to one selector only. In order to be able to use jQuery 1.9 (where jQuery.browser is deprecated) I'm using feature detection to get the 'right' selector:
function getScrollerSelector() {
var $body = $("<body/>");
$body.scrollTop(1);
return $body.scrollTop() == 1 ? "body" : "html";
}
In order to reduce the browser's processing load, I'm applying a logic that, per CSS, sets the background image of invisible sections to none during scrolling:
.scrolldown.scrollto-a2 #a1,
.scrolldown.scrollto-a3 #a1, .scrolldown.scrollto-a3 #a2,
.scrolldown.scrollfrom-a3 #a4,
.scrolldown.scrollfrom-a2 #a4, .scrolldown.scrollfrom-a2 #a3,
.scrollup.scrollto-a3 #a4,
.scrollup.scrollto-a2 #a4, .scrollup.scrollto-a2 #a3,
.scrollup.scrollfrom-a2 #a1,
.scrollup.scrollfrom-a3 #a1, .scrollup.scrollfrom-a3 #a2
{ background: none; }
I played around with linear easing, but that did not necessarily improve anything
All in all, scrolling doesn't seem choppy to me any more, but please take into account that this is also dependent on the client computers processing power.
Here's the scroll_to() function:
function scroll_to(id, speed, margin) {
var currentScrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var scrollTop = $('#' + id).offset().top - margin;
var direction = scrollTop > currentScrollTop ? "down" : "up";
$("body").addClass("scroll"+direction + " scrollto-"+id + " scrollfrom-"+getScrollFrom(direction));
$( scrollerSelector ).animate({
scrollTop: scrollTop
}, {
//easing: 'linear',
duration: speed,
complete: function() {
$("body").removeClass("scrollup scrolldown scrollto-a1 scrollto-a2 scrollto-a3 scrollto-a4 scrollfrom-a1 scrollfrom-a2 scrollfrom-a3 scrollfrom-a4");
}
}
);
}
This is the link to jsfiddle
Since you are Scaling up the image, you can tell the Browser how to handle the rendering of image.
During the animation / scrolling, you can tell browser to Optimize on Speed and on completion of Animation / scrolling, Optimize on Quality.
Here is the CSS Property you can use on img: 'image-rendering' with values as optimizeSpeed / optimizeQuality.
https://developer.mozilla.org/en-US/docs/CSS/image-rendering
One thing you could do to images is smush it using http://www.smushit.com/ysmush.it/
this reduces the size of the image without loosing quality removing all unwanted meta data.
Testing locally it seems like your code should work ok, I have firefox 15 and chrome and don't see any lagging
What if you try this for the scroll to method?
function scroll_to(id, speed, margin) {
$('html, body').animate({
scrollTop: $('#' + id)
}, speed);
}
I had a similar problem with a website I was working on. In the end the problem seemed to be because of the large dimensions of the image that the computer/browser had to compute and render on screen.
My recommendation would be to try and reduce the amount of image that needs to be shown and scrolled on screen if possible.
Most modern browsers now support hardware (graphics card) rendering instead of the traditional (usually slower) software based (CPU) rendering. Hardware based rendering should in theory reduce that lag you're experiencing. However if your PC only has base or average graphics rendering capabilities, you're not going to have much success regardless. I personally had no success with either in Chrome, FireFox or IE until I gave in and removed the images.

Categories

Resources