using a button to switch between two states - javascript

Essentially I want to use a button to bring a div to the front using the CSS z-index and then when pressing the button again I want it to revert back to its original state.
This is the code I have got so far and it will happily change it first time round but it wont revert it back.
function thumbnail(){
if (document.getElementById("div").style.zIndex= -3){
document.getElementById("div").style.zIndex= -2;
}
if (document.getElementById("div").style.zIndex= -2){
document.getElementById("div").style.zIndex= -3;
}
}

function thumbnail(){
var depth = document.getElementById("div").style.zIndex;
document.getElementById("div").style.zIndex = (depth == -3)? -2 : -3;
}

This slightly more efficient version avoids traversing the DOM more than once:
function thumbnail () {
var elStyle = document.getElementById ("div").style;
elStyle.zIndex = elStyle.zIndex == -3 ? -2 : -3;
}
Using div as an id may prove to be confusing when you return to this code later, use a name which identifies the function of the div.

Related

Fix header after scrolling Angular 4

I am having issue fixing the header after scrolling, I tried a lot of stuff but can't get it to work. I checked this thread but it doesnt work for me: Angular 4 #HostListener Window scroll event strangely does not work in Firefox . This is my component structure:
Layout
Steps
Routes
Inside steps is my header which I want to fix, after scrolling for 50px. Inside Layout is some other content like a div with logo background (above the content of steps).
This is what I tried inside Steps.ts
#HostListener('window:scroll', [])
onWindowScroll() {
const number = window.scrollY;
if (number > 40) {
this.fixed = true;
} else if (this.fixed && number < 10) {
this.fixed = false;
}
}
but the problem is that scroll is not triggering at all. I found examples
where scroll logs the event, but for me it doesn't work (I tried with $event as well). Anyone has a solution?
Found a solution. On my layout component I put a function
(scroll)="onWindowScroll($event)"
and in layout component i used:
#HostListener('window:scroll', ['$event'])
onWindowScroll($event) {
const number = $event.target.scrollTop;
if (number > 40) {
this.fixed = true;
} else if (this.fixed && number < 10) {
this.fixed = false;
}
}
I removed Steps component since I didnt need it anymore, all the content is inside layout now.
In Angular 5+ it works a little differently:
const number = $event.target.scrollingElement.scrollTop || $event.target.documentElement.scrollTop;
Since some people come via Google to this question:
I'm quite a fan of moving logic like this into something re-useable. For Angular this would mean a directive. Therefore as I run into this issue myself I created a library from my code that at least has some tests and support across many browsers. So feel free to use this tested piece of code instead of polluting your components with more code.
https://w11k.github.io/angular-sticky-things/
With the code I see in the answer I did run into some issues. In another SO I found this solution. It is crucial to determine the offsetY of the header element correctly.
// Thanks to https://stanko.github.io/javascript-get-element-offset/
function getPosition(el) {
let top = 0;
let left = 0;
let element = el;
// Loop through the DOM tree
// and add it's parent's offset to get page offset
do {
top += element.offsetTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return {
y: top,
x: left,
};

Is it possible to use transitions with display none to display block

I'm still developing a genius forum for my website. I want to add some fancy javascript effects. I don't want to use jQuery for now.
My problem is the following: I have an element which appears by checking if the value of the function is true or false. With those check my article shows or hides.
My question is: Is it possible to use transitions so that my block drops down like the way transitions do?
The first js function describes the check and the next function hides or show my article when the values are not empty.
function CheckEmptyValues() {
var inputFields = document.getElementsByTagName('input');
var textFields = document.getElementsByTagName('textarea');
var postData = [inputFields, textFields];
for(var i=0; i<postData.length; i++) {
for(var j=0; j<postData[i].length; j++) {
if(postData[i][j].value !== '') {
return false;
}
}
}
return true;
}
function showPreview() {
if (CheckEmptyValues() === false) {
this.prevPost.style.display = "block";
}
else {
this.prevPost.style.display = "none";
}
}
When my emptyvalues are false the article appears and if not, it disappears. But when this happens you see only show or hide, no further effect or something.
I want to make this something like this effect: http://www.w3schools.com/css/tryit.asp?filename=trycss3_transition1
The height value should start with 0 and end with 150 height or something like that.
Does anyone have a solution how to make this look cool?
Thanks in advance.
No, you can't, display is defined as non animatable.
If you want workarounds, see CSS3 Animation and Display None.
No, display doesn't come in transition-property. But, you can try opacity and for the display:block , put it in your div:hover or only div css.
You could use opacity, and set it to 0 or 1:
this.prevPost.style.display = "block";
this.prevPost.style.opacity = 1;

jquery moving element at the end of the list makes container disapper, seems like prepend

I'm trying to make a very simple rotating banners list.
Fiddle is here: http://jsfiddle.net/a9dAm/
if ($("#ads").length > 0) {
var count_banners = $("#ads a").length;
var delay_time = 1000;
var i = 1;
while (count_banners >= i) {
$("#ads a:nth-child("+ i +")").delay(delay_time * i).show(1, function(){
$(this).fadeOut("slow").prepend($("#ads"));
});
i++;
}
}
Prepend breaks everything and #ads disappears all together, what is going on? or what am I doing wrong?
I think you want .prependTo(), not .prepend().
$(this).fadeOut("slow").prependTo($("#ads"));
or just
$(this).fadeOut("slow").prependTo("#ads");
The .prepend() function prepends its argument to the element from which you call it.
It's disappearing because you were using .prepend rather than .prependTo. Basically, you were moving ads instead of the single ad.
Updated fiddle: http://jsfiddle.net/klatzkaj/a9dAm/1/
This is the relevant line: $(this).fadeOut("slow").prependTo($("#ads"));

Moving a box in JavaScript again -- the program seems to be detecting two key presses even though I'm only pressing one

I'm trying to build on the top answer here by adding "gravity" such that the box always moves down unless a key is pressed.
I've been fiddling for a couple of hours now and I can't figure it out. In the previous code he send two variables to the calculateNewValue function, for top and left of the css position.
I thought I would simply be able to break these two tests for true/false key presses out into four, and then add a +1 for when the up arrow is false, hence the box will always fall down unless you tell it not to.
It almost works, but the box moves down and to the right, instead of just down. And gravity doesn't work like that.
This must have something to do with top and left being used to move the box in two directions. But if the event handler is storing the keycode for only one key, wouldn't all the other tests return false? How can I get it to not move right?
$(function(){
var pane = $('#pane'),
box = $('#box'),
maxValue = pane.width() - box.width(),
keysPressed = {},
distancePerIteration = 3;
function calculateNewValue(oldValue) {
var newValue = parseInt(oldValue, 10)
- (keysPressed[37] ? distancePerIteration : 0)
- (keysPressed[38] ? distancePerIteration : 0)
+ (keysPressed[39] ? distancePerIteration : 0)
+ (keysPressed[40] ? distancePerIteration : 1)
return newValue < 0 ? 0 : newValue > maxValue ? maxValue : newValue;
}
$(window).keydown(function(event) { keysPressed[event.which] = true; });
$(window).keyup(function(event) { keysPressed[event.which] = false; });
setInterval(function() {
box.css({
left: function(index ,oldValue) {
return calculateNewValue(oldValue);
},
top: function(index, oldValue) {
return calculateNewValue(oldValue);
}
});
}, 20);
});
Usually you only use keyup() function. Then the keypress will only fire one event. Only in special cases it is necessary to use keydown().
Your code is flawed. Every 20 milliseconds you modify the the left/top of the box by the same amount every time.
The way you have set up the code, the left and top values always increase by the same amount every time the CSS is updated - so the box will always move either upleft or downright depending on if you press left/up keys.
If you're just trying to move the box up and down then you probably want to change the code not to modify the left attribute - and then change the calculateNewValue to not use the ascii for left/right arrows.

how to make a <div> appear in slow motion

I want the javascript code to show a div in slow motion.
function showDiv(divID)
{
if(document.getElementById(divID).style.display=='none')
{
document.getElementById(divID).style.display='block';
}
}
Here div appears, but not in slow motion. Can anyone help ??
Thanks in advance
Dev..
There is no need of jQuery in this atall , its just a basic I am using your function to explain how thats done.
function showDiv(divID)
{
if(document.getElementById(divID).style.display=='none')
{
document.getElementById(divID).style.display='block';
}
}
What your function is doing is basically removing the whole Element from BOX Model ( the toggle of block and none removes the element totally from the BOX Model so it doesnt occupies any space or anything , this but may / may not cause some layout issues );
Now to animate it in slow motion you need a timing function.
a timing function is a simple mathematical function which gives the value of the property ( opacity in your case ) for a given time or depending on other parameters .
Other then that you also need to use properties like opacity in order to fade it (Opacity is a CSS property that defines the transparency of an element and its childrens )
So let us begin with a very basic show / hide using setTimeout Function in JS.
function getValue(t,dir){
if( dir > 0){
return 0.5*t; /* Y = mx + c */
}else{
return 1-(0.5*t);
}
/*
Here the slope of line m = 0.5.
t is the time interval.
*/
}
function animator(divID){
if(!(this instanceof animator)) return new animator(divID); /* Ignore this */
var Node = document.getElementById(divID),
start = new Date.getTime(), // The initiation.
now = 0,
dir = 1,
visible = true;
function step( ){
now = new Date.getTime();
var val = getValue( now - start,dir)
Node.style.opacity = val;
if( dir > 0 && val > 1 || dir < 0 && val < 0 ){
visible = !(visible*1);
// Optionally here u can call the block & none
if( dir < 0 ) { /* Hiding and hidden*/
Node.style.display = 'none'; // So if were repositioning using position:relative; it will support after hide
}
/* Our animation is finished lets end the continous calls */
return;
}
setTimeout(step,100); // Each step is executated in 100seconds
}
this.animate = function(){
Node.style.display = 'block';
dir *= -1;
start = new Date.getTime();
setTimeout(step,100);
}
}
now you can simply call the function
var magician = new animator('divName');
then toggle its animation by
magician.animate();
Now playing with the timing function you can create whatever possibilities you want as in
return t^2 / ( 2 *3.23423 );
or even higher polynomial equations like
return t^3+6t^2-38t+12;
As you can see our function is very very basic but it explains the point of how to make animations using pure js . you can later on use CSS3 module for animation and trigger those classes with javascript :-)
Or perhaps write a cross browser polyfill using CSS3 where available ( it is faster ) , and JS if not :-) hope that helps
Crossbrowser solution (without jQuery) :
HTML :
<div id="toChange" ></div>
CSS :
#toChange
{
background-color:red;
width:200px;
height:200px;
opacity:0;//IE9, Firefox, Chrome, Opera, and Safari
filter:alpha(opacity=0);//IE8 and earlier
}
Javascript :
var elem=document.getElementById("toChange");
var x=0;
function moreVisible()
{
if(x==1)clearInterval(t);
x+=0.05;
elem.style.opacity=x;
elem.style.filter="alpha(opacity="+(x*100)+")";
}
var t=setInterval(moreVisible,25);
Fiddle demonstration : http://jsfiddle.net/JgxW6/1/
So you have a few jQuery answers but I wouldn't recommend jQuery if fading the div is all you want.
Certainly jQuery makes things easier but it is a lot of overhead for a single simple functionality.
Here is someone that did it with pure JS:
Fade in and fade out in pure javascript
And a CSS3 example:
How to trigger CSS3 fade-in effect using Javascript?
You can use jquery $.show('slow') for the same, if you want to do the same without using jquery then you might be required to code something to show the effect yourself, you may have a look at source of jquery's show function http://james.padolsey.com/jquery/#v=1.6.2&fn=show . alternatively , you can also use fadein() for fade in effect in jquery
Yes you can do it using Jquery. Here is my sample example
$('#divID').click(function() {
$('#book').show('slow', function() {
// Animation complete.
});
});
For details clik here
Thanks.

Categories