element not appends in body on window onload - javascript

I have been created the function which detects the screen zoom-in or zoom-out function. I am trying if window zoom == 100 or is in normal size the notification will remove else it append instantly.
In my code, it's working perfectly but it not working on window load, for showing the demo and result I have to click ctrl+ or ctrl-.
I am trying as window load it auto decide and append if window zoom, not 100 or normal.
Please help me with how I fix this?
function informationbar(percentage, zoomstatus) {
$("body").append('<div id="informationbar" style="top: 0px;"><img src="#" style="width: 14px; height: 14px; float: right; border: 0; margin-right: 5px" />You are using the window screen on ' + percentage + '% ' + zoomstatus + ' resolution, might some options are not visible properly on this current resolution please fit the screen on 100% as this our highly recommendation.</div>');
}
$(window).resize(function() {
var browserZoomLevel = Math.round(window.devicePixelRatio * 100);
if (browserZoomLevel !== '100') {
if (browserZoomLevel > "100") {
var status = "ZoomIn";
} else {
var status = "ZoomOut";
}
informationbar(browserZoomLevel, status);
} else {
$("div#informationbar").remove();
}
});
var browserZoomLevel = Math.round(window.devicePixelRatio * 100);
if (browserZoomLevel == '100') {
$("div#informationbar").remove();
} else {
if (browserZoomLevel > "100") {
var status = "ZoomIn";
} else {
var status = "ZoomOut";
}
informationbar(browserZoomLevel, status);
}
#informationbar {
position: fixed;
left: 0;
width: 100 %;
text - indent: 5 px;
padding: 5 px 0;
background - color: lightyellow;
border - bottom: 1 px solid black;
font: bold 12 px Verdana;
}
* html# informationbar {
/*IE6 hack*/
position: absolute;
width: expression(document.compatMode=="CSS1Compat" ? document.documentElement.clientWidth + "px": body.clientWidth + "px");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

You seem to be using !== to compare numbers and strings, e.g. browserZoomLeveL !== '100' where browserZoomLevel = Math.round(...).
That will always give false, since the a string isn't a number, and === is strict about types. You should replace === '100' with just === 100.

Related

How can I effectively pan an entire image programmatically?

I have a 11500x11500 div that consists of 400 images, that obviously overflows the viewport.
I would like to pan around the whole div programmatically.
I want to generate an animation and by the time the animation is over, the whole of the div must have been panned across the viewport, top to bottom, left to right.
Right now, I am "splitting" my 11500x1500 div into tiles. The maximum width and height of each tile is the width and height of the viewport.
I store the coordinates of each tile and then I randomly choose one, pan it left-to-right and then move on to the next one.
I would like to know:
whether my method is correct or whether I am missing something in my calculations/approach and it could be improved. Given the size, it is hard for me to tell whether I'm actually panning the whole of the div after all
whether I can make the panning effect feel more "organic"/"natural". In order to be sure that the whole div is eventually panned, I pick each tile and pan it left-to-right, move on to the next one etc. This feels kind of rigid and too formalised. Is there a way to pan at let's say an angle or with a movement that is even more random and yet be sure that the whole div will eventually be panned ?
Thank in advance for any help.
This is the jsfiddle and this is the code (for the sake of the example/test every "image" is actually a div containing its index as text):
function forMs(time) {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, time)
})
}
let container = document.getElementById('container')
let {
width,
height
} = container.getBoundingClientRect()
let minLeft = window.innerWidth - width
let minTop = window.innerHeight - height
let i = 0
while (i < 400) {
// adding "image" to the container
let image = document.createElement('div')
// add some text to the "image"
// to know what we're looking at while panning
image.innerHTML = ''
let j = 0
while (j < 100) {
image.innerHTML += ` ${i + 1}`
j++
}
container.appendChild(image)
i++
}
let coords = []
let x = 0
while (x < width) {
let y = 0
while (y < height) {
coords.push({
x,
y
})
y += window.innerHeight
}
x += window.innerWidth
}
async function pan() {
if (!coords.length) {
return;
}
let randomIdx = Math.floor(Math.random() * coords.length)
let [randomCoord] = coords.splice(randomIdx, 1);
console.log(coords.length)
container.classList.add('fast')
// update style in new thread so new transition-duration is applied
await forMs(10)
// move to new yet-unpanned area
container.style.top = Math.max(-randomCoord.y, minTop) + 'px'
container.style.left = Math.max(-randomCoord.x, minLeft) + 'px'
// wait (approx.) for transition to end
await forMs(2500)
container.classList.remove('fast')
// update style in new thread so new transition-duration is applied
await forMs(10)
//pan that area
let newLeft = -(randomCoord.x + window.innerWidth)
if (newLeft < minLeft) {
newLeft = minLeft
}
container.style.left = newLeft + 'px'
// wait (approx.) for transition to end
await forMs(4500)
// move on to next random area
await pan()
}
pan()
html,
body {
position: relative;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
* {
margin: 0;
padding: 0;
}
#container {
position: absolute;
top: 0;
left: 0;
text-align: left;
width: 11500px;
height: 11500px;
transition: all 4s ease-in-out;
transition-property: top left;
font-size: 0;
}
#container.fast {
transition-duration: 2s;
}
#container div {
display: inline-block;
height: 575px;
width: 575px;
border: 1px solid black;
box-sizing: border-box;
font-size: 45px;
overflow: hidden;
word-break: break-all;
}
<div id="container"></div>
I think following improvements can be made:
Hide overflow on html and body so user can not move scrollbar and disturb the flow.
Calculate minLeft and minTop every time to account for window resizing. You might need ResizeObserver to recalculate things.
Increase transition times to avoid Cybersickness. In worse case RNG will pick bottom right tile first so your container will move the longest in 2seconds! Maybe, you can zoom-out and move then zoom-in then perform pan. Or use any serpentine path which will make shorter jumps.
Performance improvements:
Use transform instead of top, left for animation.
Use will-change: transform;. will-change will let browser know what to optimize.
Use translate3D() instead of translate(). ref
Use requestAnimationFrame. Avoid setTimeout, setInterval.
This is an old but good article: https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/
Modified code to use transform:
function forMs(time) {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, time)
})
}
let container = document.getElementById('container')
let stat = document.getElementById('stats');
let {
width,
height
} = container.getBoundingClientRect()
let minLeft = window.innerWidth - width
let minTop = window.innerHeight - height
let i = 0
while (i < 400) {
// adding "image" to the container
let image = document.createElement('div')
// add some text to the "image"
// to know what we're looking at while panning
image.innerHTML = ''
let j = 0
while (j < 100) {
image.innerHTML += ` ${i + 1}`
j++
}
container.appendChild(image)
i++
}
let coords = []
let x = 0
while (x < width) {
let y = 0
while (y < height) {
coords.push({
x,
y
})
y += window.innerHeight
}
x += window.innerWidth
}
let count = 0;
async function pan() {
if (!coords.length) {
stat.innerText = 'iteration: ' +
(++count) + '\n tile# ' + randomIdx + ' done!!';
stat.style.backgroundColor = 'red';
return;
}
let minLeft = window.innerWidth - width
let minTop = window.innerHeight - height
let randomIdx = Math.floor(Math.random() * coords.length);
randomIdx = 1; //remove after debugging
let [randomCoord] = coords.splice(randomIdx, 1);
stat.innerText = 'iteration: ' +
(++count) + '\n tile# ' + randomIdx;
console.log(coords.length + ' - ' + randomIdx)
container.classList.add('fast')
// update style in new thread so new transition-duration is applied
await forMs(10)
// move to new yet-unpanned area
let yy = Math.max(-randomCoord.y, minTop);
let xx = Math.max(-randomCoord.x, minLeft);
move(xx, yy);
// wait (approx.) for transition to end
await forMs(2500)
container.classList.remove('fast')
// update style in new thread so new transition-duration is applied
await forMs(10)
//pan that area
let newLeft = -(randomCoord.x + window.innerWidth)
if (newLeft < minLeft) {
newLeft = minLeft
}
xx = newLeft;
//container.style.left = newLeft + 'px'
move(xx, yy);
// wait (approx.) for transition to end
await forMs(4500)
// move on to next random area
await pan()
}
pan()
function move(xx, yy) {
container.style.transform = "translate3D(" + xx + "px," + yy + "px,0px)";
}
html,
body {
position: relative;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#container {
text-align: left;
width: 11500px;
height: 11500px;
transition: all 4s ease-in-out;
transition-property: transform;
font-size: 0;
will-change: transform;
}
#container.fast {
transition-duration: 2s;
}
#container div {
display: inline-block;
height: 575px;
width: 575px;
border: 1px solid black;
box-sizing: border-box;
font-size: 45px;
overflow: hidden;
word-break: break-all;
}
#stats {
border: 2px solid green;
width: 100px;
background-color: lightgreen;
position: fixed;
opacity: 1;
top: 0;
left: 0;
z-index: 10;
}
<div id=stats>iteration: 1 tile# 11</div>
<div id="container"></div>
Note I haven't implemented everything in above snippet.

Dark Mode/Light Mode - html,css

so I have the following code:
let darkMode = false;
const DOMDarkMode = document.querySelector(".dark");
const DOMLightMode = document.querySelector(".light");
function toggle(x, y) {
// Calculating circle size to fill a background
bubbleSize = Math.max(
// Distances calculating: to the click point..
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)), // ..from left-top point
Math.sqrt(Math.pow(innerWidth - x, 2) + Math.pow(y, 2)), // ..from right-top point
Math.sqrt(Math.pow(x, 2) + Math.pow(innerHeight - y, 2)), // ..from bottom-left point
Math.sqrt(Math.pow(innerWidth - x, 2) + Math.pow(innerHeight - y, 2)), // ..from bottom-right point
);
if (darkMode) {
darkMode = false;
DOMLightMode.style.setProperty("--x", x + "px");
DOMLightMode.style.setProperty("--y", y + "px");
DOMLightMode.style.setProperty("--size-to-fill", bubbleSize + "px");
DOMLightMode.classList.add("active");
DOMDarkMode.classList.remove("active");
} else {
darkMode = true;
DOMDarkMode.style.setProperty("--x", x + "px");
DOMDarkMode.style.setProperty("--y", y + "px");
DOMDarkMode.style.setProperty("--size-to-fill", bubbleSize + "px");
DOMDarkMode.classList.add("active");
DOMLightMode.classList.remove("active");
}
}
document.addEventListener("click", e=>{
toggle(e.x, e.y)
});
// IFRAME EFFECT
let iframe = true;
let tick = false;
let end = false;
setTimeout(()=>{ tick = true; }, 500);
setTimeout(()=>{ tick = true; }, 1500);
setTimeout(()=>{ end = true; }, 2100);
document.addEventListener("mouseover", e=>{ iframe = false; });
effects = setInterval(()=>{
if (!iframe)
end = true;
if (tick == true) {
tick = false;
toggle(0, 0);
}
if (end) {
darkMode = false;
DOMLightMode.classList.remove("active");
DOMDarkMode.classList.remove("active");
clearInterval(effects);
}
}, 0);
body {
margin: 0;
overflow: hidden;
}
* {
font-family: 'Open Sans', sans-serif;
font-size: 20px;
text-align: center;
user-select: none;
}
h1 {
font-family: 'Yusei Magic', sans-serif;
font-size: 2em;
margin: 0;
margin-bottom: .4em;
}
p {
margin: 0;
}
.main {
position: absolute;
}
.mode {
z-index: 1;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
}
.box {
margin: 2em;
}
.active {
z-index: 2;
animation: show .6s ease;
}
#keyframes show {
from {
clip-path: circle(0 at var(--x) var(--y));
}
to {
clip-path: circle(var(--size-to-fill) at var(--x) var(--y));
}
}
.light {
background: #eee;
color: #000;
}
.dark {
background: #222;
color: #fff;
}
<div class="main">
<div class="dark mode">
</div>
<div class="light mode">
</div>
</div>
If you click anywhere, it toggles from dark mode to light mode and vice-versa. My question is where should I include the html of the above code in my website so it applies to the whole website, because right now, whenever I click somewhere, only my homepage toggles from dark mode to light mode and vice-versa. But how would I make it so that the above code works for the whole website, and wherever in my website I click, the whole website switches from dark mode to light mode and vice-versa.
I tried including the code at the top of my website's index.html after the head section but it still does not work. Any suggestions?
If you want to switch your whole website to light or dark mode, you can use window.localStorage to save and pass the mode setting to the other pages in your site that your users may visit.
You can put some code like this in the head of each page on your site:
window.dark = JSON.parse(window.localStorage.getItem("theme_mode"));
if (window.dark === null) { // First time - use prefers color to set the theme
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
window.dark = true;
document.documentElement.className = document.documentElement.classList.add("dark-mode");
} else {
window.dark = false;
}
localStorage.setItem("theme_mode", JSON.stringify(window.dark));
} else if (window.dark === true) { // Returning user - prefers dark
document.documentElement.classList.add("dark-mode");
} // Returning user - prefers light - window.dark is false
This code will also start your page as light or dark based on your user’s preference.
You will, of course, need to update localStorage every time your user toggles the between modes.
localStorage is accessible to pages with the same origin (https://example.com is different from http://example.com or https://m.example.com)

How to create a curved slider?

i'm trying to create a curved slider with jquery like this:
with no success.
can anyone point be to the right direction?
Thanks allot
Avi
This is what you want exactly. By using the jQuery roundSlider plugin you can make any type of arc slider with custom appearance.
Please check this jsFiddle for the demo of you requirement.
Live demo:
$("#arc-slider").roundSlider({
sliderType: "min-range",
circleShape: "custom-quarter",
value: 75,
startAngle: 45,
editableTooltip: true,
radius: 350,
width: 6,
handleSize: "+32",
tooltipFormat: function (args) {
return args.value + " %";
}
});
#arc-slider {
height: 110px !important;
width: 500px !important;
overflow: hidden;
padding: 15px;
}
#arc-slider .rs-container {
margin-left: -350px; /* here 350 is the radius value */
left: 50%;
}
#arc-slider .rs-tooltip {
top: 60px;
}
#arc-slider .rs-tooltip-text {
font-size: 25px;
}
#arc-slider .rs-border{
border-width: 0px;
}
/* Appearance related changes */
.rs-control .rs-range-color {
background-color: #54BBE0;
}
.rs-control .rs-path-color {
background-color: #5f5f5f;
}
.rs-control .rs-handle {
background-color: #51c5cf;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.roundslider/1.0/roundslider.min.js"></script>
<link href="https://cdn.jsdelivr.net/jquery.roundslider/1.0/roundslider.min.css" rel="stylesheet"/>
<div id="arc-slider" class="rslider"></div>
Screenshots of the Output:
To know more about the roundSlider, please check the demos and documentation page.
Please check this LINK, you will get enough details for the slider.
'slide': function(e, ui){
var percentLeft;
var submitValue;
var Y = ui.value - 100; //Find center of Circle (We're using a max value and height of 200)
var R = 100; //Circle's radius
var skip = false;
$(this).children('.ui-slider-handle').attr('href',' UI.val = ' + ui.value);
//Show default/disabled/out of bounds state
if ( ui.value > 0 && ui.value < 201 ) { //if in the valid slide rang
$(this).children('.ui-slider-handle').addClass('is-active');
}
else {
$(this).children('.ui-slider-handle').removeClass('is-active');
}
//Calculate slider's path on circle, put it there, by setting background-position
if ( ui.value >= 0 && ui.value <= 200 ) { //if in valid range, these are one inside the min and max
var X = Math.sqrt((R*R) - (Y*Y)); //X^2 + Y^2 = R^2. Find X.
if ( X == 'NaN' ) {
percentLeft = 0;
}
else {
percentLeft = X;
}
}
else if ( ui.value == -1 || ui.value == 201 ) {
percentLeft = 0;
skip = true;
}
else {
percentLeft = 0;
}
//Move handle
if ( percentLeft > 100 ) { percentLeft = 100; }
$(this).children('.ui-slider-handle').css('background-position',percentLeft +'% 100%'); //set new css sprite, active state
//Figure out and set input value
if ( skip == true ) {
submitValue = 'fail';
$(this).children('.ui-slider-handle').css('background-position',percentLeft +'% 0%'); //reset css sprite
}
else {
submitValue = Math.round(ui.value / 2); //Clamp input value to range 0 - 100
}
$('#display-only input').val(submitValue); //display selected value, demo only
$('#slider-display').text(submitValue); //display selected value, demo only
$(this).prev('.slider-input').val(ui.value); //Set actual input field val. jQuery UI hid it for us, but it will be submitted.
}
You can also try this LINK also.
If you want any other assistance, then please add comment.
Regards D.
Alternative way you can use this plugin for a curved/360 degree slider
Reference
Here is the coding:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="js/round-slider.min.js"></script>
<div class="box dotted">
<div class="left">
<div id="degrees" class="demo"></div>
</div>
<div class="right">
<p class="name">Degrees</p>
<p id="degrees-data"></p>
</div>
</div>
Javascript
(function($){
'use strict';
var set_html = function(value, index, angle, unit){
var html = ''
,val = value;
if(unit !== ''){
val += unit;
}
html += '<b>Value: </b>' + val + '<br/>';
html += '<b>Index: </b>' + index + '<br/>';
html += '<b>Angle: </b>' + angle + '<br/>';
return html;
};
$('document').ready(function(){
var self = {
degrees: null
};
self.degrees = $('#degrees').round_slider({
min: 0,
max: 359,
unit_sign: '\u00b0',
bg: 'img/bg/degrees-theme.png',
handle_bg: 'img/handles/wheel-33-33.png',
input_bg: 'img/input/round-50.png',
points_bg: 'img/points/degress-white.png',
angle_changed_callback: function(value, index, angle, unit){
$('#degrees-data').html(set_html(value, index, angle, unit));
}
});
});
})(jQuery);
Check here for the demo
Demo

How to remove flicking in IE?

I have created this fiddle where I have flicking problem in IE. Even Chrome isnt good, but in fiddle it looks more or less fine. I think problem is in "size of step" for one scroll, when you grab scroller manualy everything is smooth, but using your mousewheel leads to jumping/flicking in IE and Chrome.
window.addEventListener('scroll', function() { ...}, false);
This is my current HTML:
<div id="fakeBody">
<div id="spacer">scroll down</div>
<div class="niceBanner hide roller" id="niceBannerFrame">
<div id="bannerShadow"></div>
<div id="thumb0">
<div id="niceBannerOriginal" class="roller thumb1 thumb2"></div>
<div id="niceBannerBlur" class="roller deblur thumb1 thumb2"></div>
<div id="blackRow"></div>
</div>
</div>
</div>
Script:
window.addEventListener('scroll', function () {
var totalHeigth, currentScroll, visibleHeight;
var newResolutionBannerHeight = 0;
currentScroll = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
totalHeigth = (document.height !== undefined) ? document.height : document.getElementById("fakeBody").offsetHeight;
visibleHeight = document.documentElement.clientHeight;
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight || e.clientHeight || g.clientHeight;
var curentWidth = x;
console.log('curent Width: ' + curentWidth);
if (curentWidth < 1070) {
var newBannerWidth = Math.round((curentWidth / 1070) * 1920);
var newMargin = Math.round((newBannerWidth - curentWidth) / 2);
newResolutionBannerHeight = Math.round((500 / 1920) * newBannerWidth);
} else {}
//now it is easy to recognize if visitor is at the bottom of page
if (visibleHeight + currentScroll >= totalHeigth) {
//do the magic with banner
document.getElementById("niceBannerFrame").className = "unhide";
var bannerHeight = visibleHeight + currentScroll - totalHeigth;
var style = document.createElement('style');
style.type = 'text/css';
var number = (curentWidth < 500) ? 10 + bannerHeight : 50 + bannerHeight; //not ideal solution, slower rolling for small screen, picture is realy small
if (curentWidth > 1070) {
number = (number > 500) ? 500 : number;
var opacityBlur = 1 - (number / 500);
style.innerHTML = '.roller {bottom:-' + number + 'px;} .deblur {opacity:' + opacityBlur + ';} .thumb2{height: 500px;} ';
} else {
number = (number > newResolutionBannerHeight) ? newResolutionBannerHeight : number;
var opacityBlur = 1 - (number / newResolutionBannerHeight);
style.innerHTML = '.roller {bottom:-' + number + 'px;} .deblur {opacity:' + opacityBlur + ';} .thumb2{height:' + newResolutionBannerHeight + 'px;} ';
}
document.head.appendChild(style);
} else {
//it is not good time for magic, scroll a bit more or I will hide already visible bilboard
document.getElementById("niceBannerFrame").className = "hide";
}
}, false);
and CSS:
#spacer {
height: 1000px;
background-color: whitesmoke;
}
#niceBannerOriginal {
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/1920x500_original.jpg);
position: absolute;
z-index:-3;
}
#niceBannerBlur {
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/1920x500_blur.jpg);
position: absolute;
z-index:-2;
}
#bannerShadow {
position:absolute;
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/Stin.png);
background-repeat:repeat-x;
width:100%;
z-index:-1;
height:25px;
}
.hide {
display: none;
}
.unhide {
display: block;
}
#fakeBody {
height:1000px;
position:relative;
top:0;
left:0;
right:0;
}
#blackRow {
display:none;
}
#niceBannerFrame {
overflow: hidden;
}
#media (min-width: 1921px) {
#blackRow {
background-color: #000000;
display: block;
height:500px;
position: absolute;
width: 100%;
z-index: -6;
}
}
/*desktop resolution*/
#media (min-width: 1070px) and (max-width: 1920px) {
.thumb1 {
width: 100%;
height: 500px;
background-position: 50% 50%;
/*image centering*/
}
.thumb2 {
}
}
/*mobile and tablet resolution*/
#media (max-width: 1069px) {
.thumb2 {
width: 100%;
height: 500px;
background-repeat:no-repeat;
/*background-position: 50% 50%; image centering*/
}
#niceBannerOriginal {
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/1920x500_original-thumb.jpg);
background-size: 100%;
}
#niceBannerBlur {
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/1920x500_blur-thumb.jpg);
background-size: 100%;
}
}
My question is do you how to remove this flicking? Or do you know how to cut one mouse wheel step to more smaller ones?
PS: I can not use jQuery or other plugins.
I can't be 100% sure about this, but I think the flickering isn't from the amount you're scrolling, but due to the fact that you're changing the display mode, and pushing the view back up a tiny bit.
Essentially if you are just underneath the visibleHeight+currentScroll >= totalHeigth test by a couple of pixels, then currentScroll get's pushed up a tiny bit when whatever happens in there happens (I don't entirely understand what's going on, so I can't really give any better advice on that), so that it's no longer greater than totalHigth, and so it then fails the test immediately after, hence the flickering.
Worked this out by getting rid of the hide line at the end and it seems to work. Unfortunately I don't entirely understand the code, so I can't give you any better idea than that, though hopefully it points you towards a solution.

Javascript animation only works in one direction

The webpage I'm trying to create has a bidirectional sliding animation on it. However the animation is only partially working. To be more precise, the animation slides up, but it only slides down partway. Here's my JavaScript:
function showLayer() {
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition > 315) {
hiddenLayer.style.top = (layerPosition - 5) + "px";
setTimeout("showLayer()", 20);
}
}
function hideLayer() {
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition <= 315) {
hiddenLayer.style.top = (layerPosition + 5) + "px";
setTimeout("hideLayer()", 20);
}
}
Notice on the fourth line of the hideLayer function, I have the condition set to <= 315, this is due to the fact that setting it equal to 315 causes the element to move only a few pixels in either direction after clicking the trigger element. Here's the HTML elements I have dedicated to the animation:
<div id="mainbutton" onclick="showLayer('mainmenu'); hideLayer('mainmenu')"></div>
<div id="mainmenu" style="position: absolute; top: 690px; left: 9px;"
onclick="showLayer('mainmenu')"> </div>
And here are the styles for them:
div#mainmenu { width: 600px; height: 350px; border-style: solid; background-color:
rgb(0, 0, 0) ; border-width: 3px; border-top-right-radius: 7px; border-top-left-
radius: 7px; }
div#mainbutton { position: absolute; top: 674px; left: 12px; width: 28px; height:
28px; border-style: solid; border-color: rgb(255, 255, 255); border-width: 1px; border-
radius: 4px; }
And the fiddle : http://jsfiddle.net/JAtLA/
I had to put some of the styles inline with the HTML because the animation wouldn't work any other way. At first I thought the problem had solely lain in the if conditional of the hideLayer function. But after tweaking it I'm not so sure now.
I don't know if it's what you want but here is my answer :
There is a problem of logic in your code. You wrote
if(layerPosition<=315){
hiddenLayer.style.top = (layerPosition + 5) + "px";}
It means that if the top is 315 or less, the top will increase until it arrives to 316. But in the first function, you say it to stop at 315. So the function hideLayer will just get it moving from 1 pixel.
The solution is to tell him <400 instead of <=315 (or something higher than 400).
Here is a modified fiddle : http://jsfiddle.net/7egr7/2/
It looks like "hideLayer" will stop if (layerPosition <= 315). Is that really what you want? It happens after 1 iteration.
Note that the y axis goes down the screen (i.e. zero is at the top).
Clicking the button will call showLayer, and then hideLayer.
If the menu is open (i.e. layerPosition > 315), showLayer will not do anything (i guess that is what you intend), and hideLayer will make the menu go up by 5 (from 315 to 320).
On the next iteration of hideLayer (layerPosition <= 315) will be false, so it will not do anything.
Try this:
var open = false;
function showLayer() {
if (open)
return;
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition > 315) {
hiddenLayer.style.top = (layerPosition - 5) + "px";
setTimeout("showLayer()", 20);
}
else {
open = true;
}
}
function hideLayer() {
if (!open)
return;
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition <= 685) {
hiddenLayer.style.top = (layerPosition + 5) + "px";
setTimeout("hideLayer()", 20);
}
else {
open = false;
}
}
In the html, I would like to check if the thing is open or closed before doing anything.
<div id="mainbutton" onclick="if (!open) { showLayer('mainmenu'); } else { hideLayer('mainmenu'); }">
but layerPosition <= 685 is the only change that really matters.

Categories