Class added in one handler and already activating another one - javascript

About the title: I really could not think of a beter way to describe this.
I have this webpage here, and this is the jQuery code I use:
$('a[class]').click(function(){
var clas = $(this).attr('class');
$('#'+clas.substring(0,2)).fadeTo('fast',1).removeClass('faded');
$('p:not(#'+clas.substring(0,2)+')').fadeTo('fast',0.3);
$('.ans:visible').toggle('slow');
$('#'+clas.substring(0,2)+'a'+':hidden').fadeIn('slow');
$('p:not(#'+clas.substring(0,2)+')').addClass('faded') //the class gets added
});
$('p:not(p.faded)').click(function(){ //right after it fires this
$('p.faded').fadeTo('fast',1).removeClass('faded');
$('.ans:visible').toggle('slow');
});
HTML
<p id="q1">1. <a class="q1">Nem látom a kedvenc karakterem, hozzá tudod adni?</a>
<br>
<span id="q1a" style="display:none;" class="ans">
Persze. Írj egy e-mail-t a djdavid98#gmail.com címre a karakter nevével.
<br>
<span style="color:red">OC-kat és fillyket NEM adok hozzá.</span>
</span>
</p>
<p id="q2">2. <a class="q2">Hogyan tudok karaktert választani?</a>
<br>
<span id="q2a" style="display:none;" class="ans">
Látogass el a Karakterválasztás oldalra, ahol.
<br>
Haználhatod továbbá a "<i>Véletlenszerű karakter</i>" linket is.
</span>
</p>
<p id="q3">3. <a class="q3">Mi ennek az oldalnak a célja/alapötlete?</a>
<br>
<span id="q3a" style="display:none;" class="ans">
Eredetileg a milyennapvanma.hu weboldal pónisított változataként indult,
<br>
de azóta már nagy mértékben továbbfejlődött az oldal.
</span>
</p>
As you can see on the page, clicking on any of the numbered links will instantly show & hide, indicating that both of the above code runs, but the second only should run when the user clicks the text/link again.

Add stopPropagation() this link here is fiddle http://jsfiddle.net/GSwDN/
$('a[class]').click(function(e){
e.stopPropagation();
var clas = $(this).attr('class');
$('#'+clas.substring(0,2)).fadeTo('fast',1).removeClass('faded');
$('p:not(#'+clas.substring(0,2)+')').fadeTo('fast',0.3);
$('.ans:visible').toggle('slow');
$('#'+clas.substring(0,2)+'a'+':hidden').fadeIn('slow');
$('p:not(#'+clas.substring(0,2)+')').addClass('faded') //the class gets added
});
$('p:not(p.faded)').click(function(){ //right after it fires this
$('p.faded').fadeTo('fast',1).removeClass('faded');
$('.ans:visible').toggle('slow');
});
your code can be better/cleaned up but when you click the anchor, it bubbles up to the parent p which activates the click on the p and that's why you see both events firing

For the blinking effect I would suggest using CSS3 functionality.
#-webkit-keyframes 'blink' {
0% { background: rgba(255,0,0,0.5); }
50% { background: rgba(255,0,0,0); }
100% { background: rgba(255,0,0,0.5); }
}
.animate {
-webkit-animation-direction: normal;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-name: blink;
-webkit-animation-timing-function: ease;
}
I would then add this class to the button inside onclick event:
$('a[class]').click(function(e){
$(this).addClass('animate')
}
This saves you time but also makes your JS look cleaner.

Related

Transition on Stretching Div

I have a div with some content in it, and I am showing a button with jQuery. I want to fade it in thus I used:
setTimeout(function() {
jQuery('#button').css('opacity', 1);
}, 100);
First, on html, I have set the button's html to display:none; opacity: 0 I have achieved showing/hiding button, however when it shows, it's making the div stretch instantly. Instead, I want the parent div to expand with transition.
I have created a Fiddle: https://jsfiddle.net/atg5m6ym/7450/ . In this example, when I press the trigger button, I want the button to fade in as well as applying transition on the parent div.
For optimal performance, when using transitions and animations in CSS, you should stick to opacity and transform instead of display: none; and width/height.
Will quote the comment I stated above:
The way you designed this is not ideal, you should not be using
display: none; in transitions or animations. This will cause redrawing
in your browser, and you cannot transition properties with binary
settings, display just switches between states (ex: none/block), not
between values like opacity does.
What you could do is separate your content, sharing the same background color to simulate it is the same container.
Then use transform and the scale() function.
Code Snippet:
jQuery('#trigger').click(function() {
jQuery('.bottom-content').addClass('open');
})
.top-content,
.bottom-content {
background-color: lightblue;
}
.bottom-content {
transform: scaleY(0);
transition: transform 250ms ease-in;
transform-origin: top;
}
.bottom-content.open {
transform: scaleY(1);
}
.bottom-content.open #otherButton {
opacity: 1;
}
#otherButton {
margin-top: 20px;
opacity: 0;
transition: opacity 10s;
transition-delay: 250ms;
/* Separated for clarity purposes, wait for parent transition to end before starting this one*/
}
<script src="https://www.addressfinder.co.nz/assets/v2/widget.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="content">
<section class="top-content">
<button id="trigger">
Trigger
</button>
<br />Lalala La
<br />Lalala La
<br />Lalala La
<br />
</section>
<section class="bottom-content">
<button id="otherButton">
Test Btn
</button>
</section>
</div>
</div>
The accepted answer is overkill. Just use .fadeIn() and forget the opacity and transition settings completely. If you want to have the div expand separate from the button, just apply the effect to the div and then trigger the button effect at the end of the div effect. This snippet does the same thing as the accepted answer without any of the CSS troubles:
$(function(){
jQuery('#otherButton').hide();
jQuery('#two').hide();
});
$('#trigger').click(function() {
$('#two').slideDown(2000, function(){
$('#otherButton').fadeIn();
});
})
#container, #two {
background-color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="container">
<div id="content">
<button id="trigger">Trigger</button>
<br>
Lalala La<br>
Lalala La<br>
Lalala La<br>
<div id="two">
<button id="otherButton">Test Btn</button>
</div>
</div>
</div>
You can combine the jquery:
jQuery('#trigger').click(function() {
jQuery('#otherButton').slideDown(300).css('opacity', 1);
})
Note that I used the slideDown() function rather than show(). Using a transition function allows you to set an execution time. show() simply toggles the css display property, but you can not transition the display property.
Updated Fiddle
Instead of adding CSS with jQuery, you can simply add a class instead.
Set this class to whatever properties you want on it, us as:
.is-visible {
opacity: 1;
}
Example Fiddle: https://jsfiddle.net/atg5m6ym/7456/
Now, CSS doesn't like to transition when switching display: none; so instead I have simply set the height: 0; and only applied necessary styling on the .is-visible class.

CSS Transformation causing scroll back/flash

Not completely sure how to explain what's going on. I'm trying to do a transformation on my search bar after it's submitted. The CSS and HTML are pretty large so I'm linking to CodePen to see in action, but I'll post the JS/CSS here as well.
I'd like to do something 'fancy' with the search bar, while the results pop up on the same screen so I thought 'transitions'.
CSS
.postSearch{
-webkit-transition: all 3s ease;
-webkit-transform: rotate(1440deg);
-moz-transition: all 3s ease;
-moz-transform: rotate(1440deg);
margin-left: 80%;
}
HTML Form
<div class="revolver">
<form id="myForm">
<p class="inp-wrap search-wrap">
<label for="charName" class="search-label grid-25">Find</label>
<input type="search" name="charName" id="charName" class="grid-75" placeholder="e.g. Teodoro" />
</p>
<p class="inp-wrap cat-wrap">
<label for="servers" class="grid-20">on</label>
<select name="servers" id="servers" class="grid-80">
<option>Thrall</option>
</select>
</p>
<p class="inp-wrap submit-wrap">
<button class="grid-100 btn" name="SubmitButton" onclick="updateTransition()" type="button">
<span class="search-icon-container">
<i class="fa fa-search" aria-hidden="true"></i>
</span> GO!
</button>
</p>
</form>
</div>
JS
function updateTransition() {
var el = document.querySelector("div.revolver");
if (el) {
$('#myForm').addClass('postponed');
$('#myForm').removeClass('myForm');
el.className = "postSearch";
} else {
$('#myForm').addClass('myForm');
$('#myForm').removeClass('postponed');
el = document.querySelector("div.postSearch");
el.className = "revolver";
}
};
There is a lot more to this page in production which is why some of the IDs etc don't make sure. I feel like using 'toggleClass' is a better idea for the myForm/postponed swap also. (I do this so hitting 'Go' again doesn't re-submit the form.
The codepen is located here - If you notice when you hit 'go' you'll see a scroll bar periodically pop up. On smaller resolutions it happens, on 4K it happens. On the website it actually is causing the background image to 'shake' and snap around.
I'm not too familiar with transitions, but I followed the documents pretty specifically. I'll end up inverting it to get the search bar to go back since it kind of 'snaps' back right now. Would appreciate any advice.
Thanks.
It is because of the component is going out from document. Try by adding overflow: hidden to it's parent container. Please try this and let me know if this is helpful for you.
function updateTransition() {
var el = document.querySelector("div.revolver");
if (el) {
$('#myForm').addClass('postponed');
$('#myForm').removeClass('myForm');
el.className = "postSearch";
} else {
$('#myForm').addClass('myForm');
$('#myForm').removeClass('postponed');
el = document.querySelector("div.postSearch");
el.className = "revolver";
}
};
html,
body {
position: relative;
height: 100%;
margin: 0;
/* temporary class */
}
.overflow-hidden {
overflow: hidden;
position: relative;
min-height: 100%;
}
.postSearch {
-webkit-transition: all 3s ease;
-webkit-transform: rotate(1440deg);
-moz-transition: all 3s ease;
-moz-transform: rotate(1440deg);
margin-left: 80%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="overflow-hidden">
<div class="revolver">
<form id="myForm">
<p class="inp-wrap search-wrap">
<label for="charName" class="search-label grid-25">Find</label>
<input type="search" name="charName" id="charName" class="grid-75" placeholder="e.g. Teodoro" />
</p>
<p class="inp-wrap cat-wrap">
<label for="servers" class="grid-20">on</label>
<select name="servers" id="servers" class="grid-80">
<option>Thrall</option>
</select>
</p>
<p class="inp-wrap submit-wrap">
<button class="grid-100 btn" name="SubmitButton" onclick="updateTransition()" type="button">
<span class="search-icon-container">
<i class="fa fa-search" aria-hidden="true"></i>
</span> GO!
</button>
</p>
</form>
</div>
</div>
Scroll occurs because while form is spinning it goes out parent.
One possible solution is to add overflow: hidden for the time of animation.
body.transitionActive{
overflow: hidden;
}
js
[...]
$('#myForm').addClass('postponed');
$('body').addClass('transitionActive');
setTimeout(function(){
$('body').removeClass('transitionActive');
}, 3000);
$('#myForm').removeClass('myForm');
[...]
See how it works here: http://codepen.io/anon/pen/ALNLak

HTML Blinking text for all browser but in different areas of the body

I am trying to get different areas of my html page to blink 'certain' text. However my code makes all of the text blink. Here is my code:
<script type="text/javascript">
function blinker()
{
if(document.getElementById("blink"))
{
var d = document.getElementById("blink") ;
d.style.color= (d.style.color=='red'?'white':'red');
setTimeout('blinker()', 500);
}
}
</script>
<body bgcolor="#F0F0c0"; onload="blinker();">
<align="Right"><font size="3">Type of Alarm: <span style="font-
weight:bold"; div id="blink">Fire</div>
<align="Right"><font size="3"># of Employees Clocked In:<span style="font-
weight:bold"; div Id="blink">5</div>
I only want the words 'Fire' and '5' to blink, but everything blinks.
I just tried to express as better as i can what probably you would try to accomplish, this is actually still not have the expected behaviour but with the snippet you provide you may agree with me is not easy.
I'll give you an example plunkr that you can edit in order to help you:
Plunkr
function blinker()
{
if(document.getElementById("blink"))
{
var d = document.getElementById("blink") ;
d.style.color= (d.style.color =='red' ? 'white' : 'red');
setTimeout(blinker(), 500);
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body bgcolor="#F0F0c0" onload="blinker()">
<span style="font-weight:bold; font-size:30px;">Type of Alarm:</span>
<div id="blink">Fire</div>
<span style="font-weight:bold; font-size:30px;"># of Employees Clocked In:</span>
<div id="blink">5</div>
</body>
</html>
There are several issues in your markup that will need to be addressed. If you were to start again, one way that you can achieve what you are trying to do is with CSS animation.
You define your keyframe colours for 0% and 100% then any element which has a blink class will toggle between those colours on an infinite loop like this:
/* -- CSS -- */
#keyframes colours {
0% {color: #f00;}
100% {color: #fff;}
}
.blink { /*browser prefixes removed for brevity*/
animation-direction: normal;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-name: colours;
animation-timing-function: ease;
}
<!-- HTML -->
Type of Alarm:<span class="blink">Fire</span><br />
# of Employees Clocked In:<span class="blink">5</span>
You're html code is not valid.
Why don't you use this tag :
<blink>
You can start with this example since we know what you are trying to do but you have invalid mark up:
https://jsfiddle.net/jws5wpfm/
HTML
<h3>Type of Alarm:
<span class="blink white">Fire</span>
<br/>
# of Employees Clocked In
<span class="blink">5</span>
</h3>
CSS
.blink {
color:red
}
.white {
color: white !important
}
JS
window.setInterval(function() {
$("span").toggleClass("white");
}, 500);

Retain element screen position after adding a new element before it in DOM

I have a div containing two spans which hold text:
<div class="jumbotron">
<span id="span-one" class="name-letters">One</span>
<span id="span-two" class="name-letters">Two</span>
</div>
I perform a CSS animation on these spans to move one element away from the other (took out browser prefixes for better legibility) JSFiddle:
#span-two {
animation-delay: 3s;
animation-duration: 3s;
animation-name: slide;
animation-fill-mode: forwards;
}
#keyframes slide {
from {
margin-left: 0%;
}
to {
margin-left: 25%;
}
}
Example:
start:
One Two
stop:
One Two
Now, I would like to add a third span, once the animation has completed, next to the first span. However, I would like the second span to keep its animation end position.
Example:
what I want:
One Three Two
what I get: JSFiddle
One Three Two
This is because I add to the margin-left attribute of the second span for it to move in the animation. So, when I add a new element before it, the second span moves further to meet the margin-left value that was set. My Question: How can I achieve this without moving the second spans position after the third span is added?
You can set span #3 positioned absolutely (or fixed), but without specifying top and left values (!):
#span-three {
position: absolute;
}
and
span.id = "span-three";
Demo: http://jsfiddle.net/gcgtveo5/2/
I can't write pure javascript, but could you do something like this instead of the absolute positioned span?
HTML:
<div>
<div class="container">
<span id="span-one" class="name-letters">One</span>
</div>
<div class="container" id="spanThreeContainer">
</div>
<div class="container">
<span id="span-two" class="name-letters">Two</span>
</div>
CSS:
.container {width:33.33%; float:left;}
and then append your new span to '#spanThreeContainer'?

How to make a animated <div> be visible only inside another <div>

Firstly thank you for accepting me in the group.
I need help with a question about animation with jQuery.
This is an animation which I found on items in the navigation menu of this template, the template monster.
http://www.templatemonster.com/demo/40492.html
Apparently these are two images that move on the canvas and gradually fade at some point.
Studying examples of jQuery I saw that part of the effect is obtained with the use of animation attribute top (css). But unfortunately the element that I animated do not gradually disappears as the example shown in the link.
Please help me understand how I can achieve the same effect using jQuery.
You can simply make it as per below.
CSS
#font-face {
font-family: 'Six Caps';
font-style: normal;
font-weight: 400;
src: local('Six Caps'), local('SixCaps'), url(http://themes.googleusercontent.com/static/fonts/sixcaps/v5/tMrhQDUBAHnnGuM33-yobPesZW2xOQ-xsNqO47m55DA.woff) format('woff');
}
.clear{clear:both;}
.nav{}
.menubox{width:200px;float:left;margin:0px 10px;height:80px;overflow:hidden;position:relative;font-family: 'Six Caps', sans-serif;line-height: 80px;color: #161616;font-size: 80px;color:#000;display:block;cursor:pointer;}
.menubox > span{width:100%;height:80px;display:block;position:absolute;text-align:center;}
.menubox > span.default-txt{top:0px;left:0px;}
.menubox > span.hover-txt{top:80px;left:0px;color:red;}
HTML
<div class="nav">
<a class="menubox">
<span class="default-txt">menu</span>
<span class="hover-txt">menu</span>
</a>
<a class="menubox">
<span class="default-txt">menu</span>
<span class="hover-txt">menu</span>
</a>
<a class="menubox">
<span class="default-txt">menu</span>
<span class="hover-txt">menu</span>
</a>
<a class="menubox">
<span class="default-txt">menu</span>
<span class="hover-txt">menu</span>
</a>
<div class="clear"></div>
</div>
jQuery
$(document).ready(function(){
$('.menubox').mouseenter(function(){
$(this).children('.default-txt').stop(true,true).animate({top:'-100px'});
$(this).children('.hover-txt').stop(true,true).animate({top:'0px'});
}).mouseleave(function(){
$(this).children('.default-txt').stop(true,true).animate({top:'0px'});
$(this).children('.hover-txt').stop(true,true).animate({top:'100px'});
});
});
JSFiddle
Working Demo
Here's a simple example: http://jsfiddle.net/qtdtL/. Note the that element with the animation for "top" has position: fixed.
$("nav").click(function() {
var el = $(this);
var elTop = el.position().top == 0 ? "-70px" : "0";
el.animate({top: elTop});
});
Basically you add
div
{
transition: all 0.5s ease;
-webkit-transition: all 0.5s ease; /* Safari */
}
first property tells what kind of changes that should be animated on change the second one tell how long time it should take and the third one timing, there's also a fourth for giving it a delay if so is desired

Categories

Resources