Replacing a containers content with css transition between with unkown height - javascript

I would like to replace the content of a modal popup dynamically, and it do a smooth transition between the old size and the new size.
I thought I may be able to do this using CSS transition, however I have been unsuccessful so far.
My setup is something similar to the JS fiddle here, where I have a container, and I swap out the inner content with different width and height.
http://jsfiddle.net/Lsf76eby/24/
html
<input type="button" value="press me" onclick="changeDiv()" />
<div id="container">
<div id="a">
</div>
</div>
js
function changeDiv(){
var b = $('<div id="b">');
$('#container').empty().append(b);
}
css
#container{
transition: 2s;
height: auto;
}
#a {
height: 200px;
width: 200px;
background:blue;
}
#b {
height: 400px;
width: 300px;
background:red;
}

I made a few changes in a fork of the fiddle here. You can read more about this from https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
I added a new javascript function, added a css property, and reorganized the css a little
You must define all the properties you will make subject to the transition using transition-property
One significant change is that my javascript function (as adapted from MDN) switches classes on a single div rather than switching the div itself.
Hope this helps!
html
<div id="container">
<div id="target" class="a">
</div>
</div>
javascript
//pretty much straight from the MDN doc...
function updateTransition() {
var el = document.querySelector("div.a");
if (el) {
el.className = "b";
} else {
el = document.querySelector("div.b");
el.className = "a";
}
return el;
}
css
#container{
height: auto;
}
#target{
transition: 2s;
transition-property: width height background-color;
}
.a {
height: 200px;
width: 200px;
background-color:blue;
}
.b {
height: 400px;
width: 300px;
background-color:red;
}

Related

dropDown function - When pressing multiple times and fast setTimeout deletes border when the height is 500px

First of all, no, I'm not going to use jQuery.
So, I have this project I'm working on, and I want to do a slide toggle element. Everything is nice and good until I press the button really fast. Then the borders dissapear and the element has reached its final height(500 px in this case).
Perhaps my explanation wasn't that accurate, but I'll give you the code.
var div = document.getElementById('div');
var btn = document.getElementById('button');
function clickFunction(){
if(div.style.height === "0px") {
div.style.height = "500px";
div.style.borderStyle = "solid";
} else {
div.style.height = "0px";
setTimeout(function(){div.style.borderStyle = "none";}, 500);
}
}
btn.onclick = clickFunction;
div#div {
transition: 500ms ease;
width: 100px;
height: 200px;
margin-top: 20px;
}
.container {
width: 120px;
background-color: red;
padding: 8px;
}
<button id="button">
Press me
</button>
<div class="container">
<div id="div" style="border-style: none; border-width: 2px; height: 0px;"></div>
</div>
I also tried using clearTimeout() but it wasn't working. Yes, I set setTimeout as a variable, but it doesn't do anything.
Any ideas? Cheers.
Your current code uses combinations of inline styles and an id selector in conjunction with the inline style being updated by JavaScript in an if/then as well as with a setTimeout() callback. All of these instructions, coupled with the speed at which the client can repaint the UI are all contributing to the problem.
By cleaning up the approach to toggling the styles and how the styles are applied in the first place, there is much less potential conflict in instructions and timing.
Remove all the static styles from the HTML and set up CSS classes for the normal and expanded states of the element. Then just use the element.classList.toggle() method to seamlessly toggle the use of the expanded class. No timers needed.
var div = document.getElementById('div');
var btn = document.getElementById('button');
btn.addEventListener("click", function(){
div.classList.toggle("expanded");
});
.container {
width: 120px;
background-color: red;
padding: 8px;
}
.normal {
transition: 500ms ease;
width: 100px;
margin-top: 20px;
border:0px solid black;
height: 0px;
}
.expanded {
height: 200px;
border:2px solid black;
}
<button id="button">Press me</button>
<div class="container">
<div id="div" class="normal"></div>
</div>
NOTE:
Be careful when setting up CSS selectors that are id based because they become very difficult to override later. I'm not saying never use them, but more often than not, CSS classes provided the most flexible solutions and help to avoid gobs and gobs of inline styles.

How to add and remove CSS code from classes with pseudo element?

function toggle(){
var button=document.querySelector('.toggle');
var bar=document.querySelector('.slide');
if(bar.className==='slide up'){
bar.className='slide down';
}else{
bar.className='slide up';
}
}
*{
margin:0px;
padding:0px;
height:100%;
width:100%;
}
.box{
overflow:hidden;
background-image: url('http://tombricker.smugmug.com/Travel/San-Francisco-California/i-jk2Z7D7/0/L/san-francisco-golden-gate-bridge-morning-sun-bricker-L.jpg');
background-size: cover;
background-position:center;
}
.slide{
position: relative;
left:39vw;
width: 55vw;
height: 75vh;
background: red;
}
.slide:before {
content: '';
position:absolute;
top:-3vh;
width: 0px;
height: 0px;
border-left:27.5vw solid transparent;
border-right:27.5vw solid transparent;
border-bottom:3vh solid white;
}
.slide.down{
transform:translateY(100vh);
}
.slide.up{
transform:translateY(25vh);
}
.slide{
transition:transform 0.4s ease-out;
}
<div class='box'>
<div class='slide up' onclick='toggle()'></div>
</div>
The white triangle on top of the red rectangle is made with pseudo element :before. What I am trying to do is when the sliding tag is up, the white triangle should be pointing down. To do that, I want to write a JS code that will add a transform CSS to that class with pseudo element that will translate triangle down by its height and rotate by 180deg.
I find on this developer blog the JS code to add, but it does not work and I don't know how to delete that code when the tag is down.
function toggle(){
var button=document.querySelector('.toggle');
var bar=document.querySelector('.slide');
if(bar.className==='slide up'){
bar.className='slide down';
//Here is where I need to add the line to delete CSS
}else{
bar.className='slide up';
//This is to add CSS
//3vh is the height of that white triangle
document.styleSheets[0].addRule('.slight:before','transform:translateY(3vh) rotateX(180deg)');
}
}
You can add the transformation to the CSS class, and simply toggle it.
CSS
.slide.up:before {
transform: translateY(3vh) rotateX(180deg);
}
JS
var bar = document.querySelector('.slide')
function toggle() {
var cl = bar.classList
cl.toggle('down', cl.contains('up'))
cl.toggle('up', !cl.contains('down'))
}
JSFiddle demo: https://jsfiddle.net/htq8ouyn/2/
Resources
Element.classList - Web APIs | MDN

Javascript - Multi-Usage of General Function

I have a example of a situation here, I want to change the color of a div when clicked. Do I have to have two different functions, one for each div? What if the functions that I wanted to apply to the div was very complex? What if I had hundereds of the div? Can I make a general function, that can be applied for every div? By this I do not mean for example document.getElementsByClassName(" ... "), I want to for example change the color of the separately.
To be clear, how can I apply the same function to different objects? Something like document.getElementThatIsClicked(" ... " ) Thank you.
function changeColor1() {
document.getElementById("div1").style.backgroundColor = "#21a9c9";
}
function changeColor2() {
document.getElementById("div2").style.backgroundColor = "#21a9c9";
}
<div id="div1" onClick="changeColor1()" style="position:absolute; top:10px; left: 10px; width:200px; height: 200px; background-color:#000000;"></div>
<div id="div2" onClick="changeColor2()" style="position:absolute; top: 10px; left: 220px; width:200px; height: 200px; background-color:#000000;"></div>
You can make a function that accepts the element you want to change the color and make the function change the background color for that element
function changeColor(elem) {
elem.style.backgroundColor = "#21a9c9"
}
<div id="div1" onClick="changeColor(this)" style="position:absolute; top:10px; left: 10px; width:200px; height: 200px; background-color:#000000;"></div>
<div id="div2" onClick="changeColor(this)" style="position:absolute; top: 10px; left: 220px; width:200px; height: 200px; background-color:#000000;"></div>
Copied from https://stackoverflow.com/a/32828729/227299 but:
Avoids setting handlers using inline HTML attributes in favor of unobtrusively setting handlers from JavaScript itself. See onclick="" vs event handler
Avoid setting CSS attributes from HTML attributes. See What's so bad about in-line CSS?
function changeColor(elem) {
elem.style.backgroundColor = "#21a9c9"
}
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', function(e) {
changeColor(this);
});
}
#div1,#div2 {
display: inline-block;
width: 200px;
height: 200px;
background-color:#000000;
}
<div id="div1"></div>
<div id="div2"></div>

How to slide images to the left using jquery

I tried sliding two images from right to left. The slide is working but only displaying the first image. Please what's the cause? This is my code:
<script type="text/javascript">
var n=0;
var nmax=2;
function timer()
{
window.setInterval(function ()
{
n+=1;
if(n>nmax)
{
n=0;
$('#slideImage').css('left','0');
}
$('#slideImage').css('left',(n)*(1366)*(-1)+'px');
},2500);
}
$(document).ready(function(e) {
timer();
});
</script>
css
.wn_p { height: 400px; width: 1366px; float: left; }
.w_n { height: 400px; width: 100%; overflow: hidden; background-color: #09C; }
.w_n2 { height: 400px; width: 2732px; margin-right: auto;
margin-left: auto; position: relative; display: inline-table;
transition: linear 0.75s 0.2s; -moz-transition: linear 0.75s 0.2s;
-webkit-transition: linear 0.75s 0.2s; }
and here is html
<div class="w_n">
<div class="w_n2" id="slideImage">
<div class="hd_p">
<img name="shift" src="image/bn2.jpg" class="wn_p" />
<div class="des_p">The company maintains high quality standard in all its operations. With high production capacity, the policy thrust is to continue to provide cost-effective, affordable, local alternatives of life saving drugs to the teaming population.
</div>
</div>
<img name="shift" src="image/bn3.jpg" class="wn_p" />
</div>
</div>
If you use jQuery anyway, why not use its animate function?
$(document).ready(function(e) {
$('.wn_p').animate({left: '-200px'}, {duration: 2500});
});
You can set a lot of options, so if you show some html and elaborate on your needs, we could better match the result you're expecting.
The fact only one image is shown could be a CSS thing. You're using an ID, but should use a class if there's more than one image.
Edit: I changed the selector to the class you added. You propably figured that out by now, but it should work this way.
For lots of cycle image effects it might be worthwhile checking out this jQuery Cycle Plugin: http://jquery.malsup.com/cycle2/
THis is a basic pager that might be of interest to start you off: http://jquery.malsup.com/cycle2/demo/pager.php
Here are lots of demos that might help: http://jquery.malsup.com/cycle2/demo/
use:
<html>
<head>
<title>Project</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
var n=0,switcher=1; // Note change
var nmax=2;
function timer()
{
window.setInterval(function ()
{
if(switcher){ // Note change
n+=1;
}
else{ // Note change
n--; // Note change
} // Note change
if(n>=nmax) // Note change
{
switcher=0; // Note change
}
if(n<=0) // Note change
{
switcher=1; // Note change
}
$('#slideImage').animate({left:''+(n)*(1366)*(-1)+'px'},500); // Note change
},2500);
}
$(document).ready(function(e) {
timer();
});
</script>
<style type="text/css">
.des_p{height: 400px; width: 1366px;float: left; }
.wn_p { height: 400px; width: 1366px; float: left; }
.w_n { height: 400px; width: 100%; overflow: hidden; background-color: #09C; }
.w_n2 { height: 400px; width: 2732px; margin-right: auto;
margin-left: auto; position: relative; display: inline-table;
transition: linear 0.75s 0.2s; -moz-transition: linear 0.75s 0.2s;
-webkit-transition: linear 0.75s 0.2s; }
</style>
</head>
<body>
<div class="w_n">
<div class="w_n2" id="slideImage">
<div class="hd_p">
<img name="shift" src="image/bn2.jpg" class="wn_p" />
<div class="des_p">The company maintains high quality standard in all its operations. With high production capacity, the policy thrust is to continue to provide cost-effective, affordable, local alternatives of life saving drugs to the teaming population.
</div>
</div>
<img name="shift" src="image/bn3.jpg" class="wn_p" style="position:absolute; top:0px; left:2732px;" /><!-- Note change -->
</div>
</div>
</body>
</html>
actually problem was not in your js but it was in your css due to low height overflow was hidden..
i fixed that by using positioning of element in css..
according to your last comment i've updated answer for sliding images in both direction.
please pay attention in the lines marked by Note change at end.
hope it'll help you. cheers !!
try it
$(document).ready(function() {
$('#slideImage').animate({left: '-200px'},2500);
});

Gradually apply styles ( transitions not seeming to work ) Possibly with js / jQuery?

I'm trying to gradually fade in the scroll-bar. Currently, how I am making the scroll-bar appear is by adding a class to the body that changes the overflow to auto, but it looks very jerky / abrupt.
Here is the JS code that abruptly adds the class that shows the scroll-bar:
var bodywidth = $('body').width();
var scrollwidth = 10;
$('body').mousemove(function(e){
var x = e.pageX - this.offsetLeft;
if(x>bodywidth-scrollwidth)
$('body').addClass("auto");
else
$('body').removeClass("auto");
});
And here is the CSS corresponding to those clases:
body
{
margin:0;
overflow:hidden;
}
.auto
{
overflow:auto;
}
How can I make this transition less abrupt? Is there a better way to do it that adding the class and removing the class.
The scrollbars can be customized via -webkit-scrollbar, but this can not be animated (or at least I didn't succeded at it), and support in other browser is poor.
An alternative is to set a div just over the scrollbar, make it the same color than the base div, and make it gradually transparent to show the scrollbar
the html is:
<div class="container">
<div class="base">
<p>aaa aaaaa aaaaa aaaaaaaa aaaa aaa aaa aaaa bbbbbb bbbbbb cccc cccc cccc
</p>
</div>
<div class="hide">
</div>
</div>
the CSS is:
.base {
width: 100px;
background-color: white;
top: 0px;
position: absolute;
height: 130px;
overflow: hidden;
padding-right: 20px;
}
.base.clipped {
overflow: auto;
}
.hide {
position: absolute;
width: 19px;
height: 100%;
right: 0px;
background-color: white;
top: 0px;
-webkit-transition: all 2s;
z-index: 10;
}
.hide.clipped {
background-color: transparent;
}
I am keeping the class of the elements all the time, but adding a second class clipped to both. I set a padding in the element that will have the scrollbars so that there space for it without rearranging the layout. The hide element can be transitioned with css, the overflow not.
the javascript is
$("*").click(function(){
var obj = $(".base");
var hid = $(".hide");
if (obj.hasClass("clipped")) {
hid.removeClass("clipped");
setTimeout(function() {
obj.removeClass("clipped");
}, 2000);
} else {
hid.addClass("clipped");
obj.addClass('clipped');
}
});
demo

Categories

Resources