I was using jquery/jquery-ui's slideDown() animation function for a particular task. It now transpires that I will not be able to use jQuery in this project. I also cant use YUI or any other libraries. So I wondering is there a way to perform a slideDown style animation using pure javascript?
Edit: I have to do it without jQuery because I am using selenium to control a webpage and on this particular site adding jQuery to the page breaks event handlers for some reason.
You can do slides and animations using CSS3, e.g.
.slidable {
position: relative;
-webkit-animation: Slider 2s ease-in-out;
}
#-webkit-keyframes Slider {
from {
top: 0px;
}
to {
top: 100px;
}
}
Use -moz- for Firefox. Javascript can do movements as well, just put them in timers, e.g.
var top = 0;
window.Timeout(MoveSomething, 10);
function MoveSomething {
var el = document.getElementById('moveme');
top += 2;
el.style.top = top + 'px';
if (top < 100) window.Timeout(MoveSomething, 10);
}
Just takes coding!
The obvious answer is yes...quick question...couldn't you just do an ASYNC load of jQuery into the document and then use it after the fact, or can you not use it because of other limitations?
Worst case you could rip out the part you needed, but that doesn't make much sense. If you can edit any of the JS you could easily paste jQuery just above your code.
Related
I am trying to understand the DOM through JS.
When I click on the button (named collapse all, I want the section below to be collapsed (disappear), but slowly and smoothly ( a transition?), and then when I click again on the same button, I want it to appear again, and so forth...
how can I achieve this through JS?
I wrote this code, but still not working repeatedly , it is working only once :
btn_all.addEventListener("click", funct1);
function funct1(e) {
section2.style.transition = "all ease 5s";
section2.style.display = "none";
for (let i = 0; i < 100; i++) {
btn_all.addEventListener("click", funct2);
function funct2(e1) {
section2.style.display = "block";
}
}};
the transition is not working...
display: none is instant - you'll want to change some attribute (like height or opacity) and then set display: none when it's done, and put the transition in the base style.
Also, accessibility guidelines (and good taste) generally state that transitions should be fast - give the impression of motion, without making them sit through an animation. 250ms is a pretty good speed
E.g.
.section {
transition: opacity ease-in .25s;
}
.section.fade-out {
opacity: 0;
}
Also, jquery has some simple transitions that generally work unless you're going supernuts in the styles, if that is available. e.g.
$(".section2").fadeOut(250);
It negates the need for a lot of nullchecking, browser compatibility workarounds, etc. and has a lot of easy shortcuts. Great for quick development and easy to approach for beginner developers.
I am relatively new to web design and am not yet ready to dive into JQuery but I am beginning to use Javascript as needed. I am unable to figure out how to change the background color of a div menubar at a certain scroll position.
CSS
.mainMenu {
position: fixed;
top: 0px;
left: 0px;
height: 80px;
padding: 20px;
transition: all 0.2s;
}
Javascript
var scrollHeight = window.pageYOffset;
if (scrollHeight >= 100) {
document.getElementById("mainMenu").style.backgroundColor = "green";
}
From what I can tell as a noob, the if statement only runs on load and the var scrollHeight isn't updating as the user scrolls. I appreciate any help making this work! I will get around to learning JQuery but I would like to understand the language better before dabbling in libraries.
Right – you need to setup something that continues to check the scroll position and update accordingly:
function checkPosition() {
// Continue calling this function:
requestAnimationFrame(checkPosition);
// Check your position here
}
// Initial Call:
checkPosition();
Better yet, read up on Scroll Events.
Edit:
Also, instead of manipulating styles directly, I'd recommend adding or removing classes:
element.classList.add("newClass");
(By the way, jQuery is actually easier than 'regular' javascript.)
Any one know a good library for elements entering animation while page scrolling. I have used animate it library, its awesome, lite and easy to handle but not working with newest version of jQuery(3.x).
Somebody suggest me a good free library.
You may try animate-on-scroll:
https://michalsnik.github.io/aos/
Or if you need a more advanced library with lot more control in your hands, try ScrollMagic:
http://scrollmagic.io/
you can use Animate.css and Wow.js
You could use the onscroll event handler.
window.onscroll - function() {
var el = document.getElementById('animateMe');
el.addClass('anime');
}
where you have the animation included in the .anime class.
CSS
.anime {
animation: yourAnimation 2s ease-out;
}
#keyframes animation {
0% {
background: blue;
}
100% {
backgroudn: red;
}
}
If you need the animation to stop when not scrolling, see How do I know when I've stopped scrolling Javascript.
As jQuery.fadeIn is not very smooth on mobile devices I try to use CSS but it doesn't work as expected. How to create a smooth CSS animation using Javascript?
In general this is what I'm trying:
$('div')
.css('opacity', 0) // at first, set it transparent
.css('display', 'block') // make it appear
.css('transition', 'opacity 1000ms linear') // set a transition
.css('opacity', 1); // let it fade in
https://jsfiddle.net/8xa89y04/
EDIT1:
I'm not searching a solution using static CSS classes. The point is: I need to set this dynamically in Javascript code - a replacement for jQuerys fadeIn() for example.
Your logic isn't quite right. Firstly you cannot animate display, so to achieve what you require the element has to always be rendered in the DOM (ie. anything but display: none). Secondly, the transition property should be placed within the CSS styling itself. Finally you can make this much more simple by setting all the rules in CSS classes and just turning the class on/off. Try this:
div {
position: absolute;
width: 100px;
height: 100px;
background-color: black;
opacity: 0;
transition: opacity 1000ms linear;
}
.foo {
opacity: 1;
}
$('div').addClass('foo');
Working example
Use this code.
CSS
div {
width: 100px;
height: 100px;
background-color: black;
transition:opacity 2s;
}
JavaScript
$('div').hover(function(){
$(this).css('opacity','0');
})
Without using CSS properly, you are going the long way about it. You'll need to emulate what you would normally do in CSS, using JavaScript, so you'll be setting all your CSS properties, transitions etc, then applying them with js.
I can't personally see any benefit in doing this. Using actual CSS would be cleaner, more efficient, more maintainable, and simply a plain better solution to what you need.
I think this is what you are looking for.
$('div').css({"display":"block", "opacity":"0"}) //Make div visible and opacity as "0"
$('div').animate({opacity :1}, 1000); //Animate div to opacity "1"
Take a look at this Demo
Found the cause here: CSS transitions do not work when assigned trough JavaScript
To give this attention I need to give the browser some time - or better: a working slot to activate the transition as the time seems not to be a problem.
The following code cuts the process in two by using setTimeout()... and it works!
var div = $('div');
// first process
div
.css('opacity', 0) // initial opacity
.css('display', 'block') // make it appear (but still transparent)
.css('transition', 'opacity 1s linear'); // set up a transition for opacity
// break - start the transition in a new "thread" by using setTimeout()
window.setTimeout(function(){
div.css('opacity', 1); // start fade in
}, 1); // on my desktop browser only 1ms is enough but this
// may depend on the device performance
// maybe we need a bigger timeout on mobile devices
This is currently happening in chrome, in firefox I haven't had this issue (yet).
Here is a VERY simplified version of my problem.
HTML:
<div class="thumbnail">
Click me!
</div>
CSS:
div {
width: 200px;
height: 300px;
background-color: purple;
}
a {
position: absolute;
}
#media (max-width: 991px) {
div {
height: 200px;
}
}
Javascript:
$(document).ready(function () {
var $parent = $('#clickMe').parent();
function resize() {
$('#clickMe').offset({
top: $parent.offset().top + $parent.height()-$('#clickMe').height()
});
}
$(window).on('resize', resize);
resize();
});
The problem:
So what does this give when I resize (without dragging)? Well javascript launches first and sets the position of the <a></a> , then CSS applies the height change if we are < 992 px.
Logically the button is now visually at the outside of the div and not on the border like I had originally defined it to be.
Temporary solution proposed in this post.
jQuery - how to wait for the 'end' of 'resize' event and only then perform an action?
var doit;
$(window).on('resize', function(){ clearTimeout(doit); doit = setTimeout(resize, 500); });
Temporary solution is not what I'm looking for:
However, in my situation I don't really need to only call 'resize' when the resizing event is actually done. I just want my javascript to run after the css is finished loading/ or finished with it's changes. And it just feels super slow using that function to 'randomely' run the JS when the css might be finished.
The question:
Is there a solution to this? Anyone know of a technique in js to wait till css is completely done applying the modifications during a resize?
Additional Information:
Testing this in jsfiddle will most likely not give you the same outcome as I. My css file has many lines, and I'am using Twitter Bootstrap. These two take up a lot of ressources, slowing down the css application (I think, tell me if I'm wrong).
Miljan Puzović - proposed a solution by loading css files via js, and then apply js changes when the js event on css ends.
I think that these simple three steps will achieve the intended behavior (please read it carefully: I also suggest to read more about the mentioned attributes to deeply understand how it works):
Responsive and fluid layout issues should always be primarily (if not scrictly) resolved with CSS.
So, remove all of your JavaScript code.
You have positioned the inner a#clickMe element absolutely.
This means that it will be positioned within its closest relatively positioned element. By the style provided, it will be positioned within the body element, since there is no position: relative; in any other element (the default position value is static). By the script provided, it seems that it should be positioned within its direct parent container. To do so, add position: relative; to the div.thumbnail element.
By the script you provided, it seems that you need to place the a#clickMe at the bottom of div.thumbnail.
Now that we are sure that the styles added to a#clickMe is relative to div.thumbnail, just add bottom: 0px; to the a#clickMe element and it will be positioned accordingly, independently of the height that its parent has. Note that this will automatically rearrange when the window is resized (with no script needed).
The final code will be like this (see fiddle here):
JS:
/* No script needed. */
CSS:
div {
width: 200px;
height: 300px;
background-color: purple;
position: relative; //added
}
a {
position: absolute;
bottom: 0px; //added
}
#media (max-width: 991px) {
div {
height: 200px;
}
}
If you still insist on media query change detection, see these links:
http://css-tricks.com/media-query-change-detection-in-javascript-through-css-animations/
http://css-tricks.com/enquire-js-media-query-callbacks-in-javascript/
http://tylergaw.com/articles/reacting-to-media-queries-in-javascript
http://davidwalsh.name/device-state-detection-css-media-queries-javascript
Twitter Bootstrap - how to detect when media queries starts
Bootstrap: Responsitive design - execute JS when window is resized from 980px to 979px
I like your temporary solution (I did that for a similar problem before, I don't think half a second is too long for a user to wait but perhaps it is for your needs...).
Here's an alternative that you most likely have thought of but I don't see it mentioned so here it is. Why not do it all through javascript and remove your #media (max-width.... from your css?
function resize() {
var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
if(width<992){
$("div").each(function(e,obj){$(obj).height(200);});
}
$('#clickMe').offset({
top: $parent.offset().top + $parent.height()-$('#clickMe').height()
});
}
In the html page, put the link to css file in head section; next, put the link to js file just before the /body tag and see what happens. In this way css will load always before js.
Hope this help you.
Did you try to bind the resize handler not to the window but to the object you want to listen to the resize ?
Instead of
$(window).on('resize', resize);
You can try
$("#clickMe").on('resize', resize);
Or maybe
$("#clickMe").parent().on('resize', resize);
var didResize = false;
$(window).resize(function() {
didResize = true;
});
setInterval(function() {
if (didResize) {
didResize = false;
console.log('resize');
}
}, 250);
I agree with falsarella on that you should try to use only CSS to do what you are trying to do.
Anyway, if you want to do something with JS after the CSS is applied, I think you can use requestAnimationFrame, but I couldn't test it myself because I wasn't able to reproduce the behavior you explain.
From the MDN doc:
The window.requestAnimationFrame() method tells the browser that you
wish to perform an animation and requests that the browser call a
specified function to update an animation before the next repaint. The
method takes as an argument a callback to be invoked before the
repaint.
I would try something like this:
var $parent = $('#clickMe').parent();
function resize(){
$('#clickMe').offset({
top: $parent.offset().top + $parent.height()-$('#clickMe').height()
});
}
window.onresize = function(e){
window.requestAnimationFrame(resize);
}
window.requestAnimationFrame(resize);
Anyone know of a technique to wait till css is completely done loading?
what about $(window).load(function() { /* ... */ } ?
(it executes the function only when the page is fully loaded, so after css loaded)