My Jquery isn't working with the way I'm selecting the <p> and <img> elements. How could I get it to work?
function projectanim(x)
{
var Para = x.getElementsByTagName("p");
var Imgs = x.getElementsByTagName("img");
if ($(x).height() != 200)
{
$(x).animate({height:'200px'});
$(Para[0]).animate({display:'inline'});
$(Imgs[0]).animate({display:'inline'});
}
else
{
$(x).animate({height:'25px'});
$(Para[0]).animate({display:'none'});
$(Imgs[0]).animate({display:'none'});
}
}
Without the HTML this is just a shot in the dark but I assume you're trying to get the paragraph and image in a specific div?
Try this:
var Para = x.find("p");
var Imgs = x.find("img");
Although depending on what you're actually passing as x will determine whether it will actually work...
function projectanim (projectId) {
$('p, img', $('div#' + projectId)) // Select p/img tags children of <div id="projectId">
.slideDown(); // show using slideDown, fadeIn() or show('slow')
}
// Example
projectanim ('protflolio_project');
The idea with jQuery is:
Use the right selectors
With the right methods
Examples
Different ways to select all img and p tags under a div which id is my_div:
// The easy way
p_and_img = $('#my_div p, #my_div img');
// Using the context parameter
p_and_img = $('p, img', $('#my_div'));
// Using the context parameter and making sure my_div is a div
p_and_img = $('p, img', $('div#my_div'));
// only the first p and img
p_and_img = $('p:eq(0), img:eq(0)', $('#my_div'));
Your question is really, really vague, but from what I can gather, this is what you're looking at achieving:
function projectanim(x) {
var self = $(x);
if (self.height() === 200) {
self.animate({ height : '25px' })
.find('p,img').fadeOut()
;
} else {
self.animate({ height : '200px' })
.find('p,img').fadeIn()
;
}
}
That being said though, barring browser compatibility and all that shizz, you really should be doing something like this using CSS more than Javascript.
Depending on your parent element (say, a <div>), you can write up CSS like the following:
div {
height : 200px;
transition : height .5s linear;
}
div.active {
height : 25px;
}
div img,
div p {
display : inline;
opacity : 100;
transition : opacity .5s linear;
}
div.active img,
div.active p {
opacity : 0;
}
and just toggle a class on/off with your Javascript:
function projectanim(x) {
$(x).toggleClass('active');
}
and everything should be automatic. Your Javascript becomes waaaaaay simpler, less coupled, more maintainable, and your styles are right where they should be (in CSS files).
"what i'm trying to do is fade the and to inline from none."
Do you just want and to fade in? Or do you want it to go from display:none to inline and fade in?
I'll show you how to do both, and you can take away parts if you just want the fade in feature.
First off set p, and img as display:none; and opacity:0, in the css like so
p, img
{
display:none;
opacity:0;
}
Secondly your js has to alter the display of both , and tags and fade in/out like so.
function projectanim(x)
{
if ($(x).height() != 200)
{
$(x).animate({height:'200px'});
document.getElementsByTagName("p").style.display = 'inline';
document.getElementsByTagName("img").style.display = 'inline';
$("p").animate({"opacity": "1"}, 1000);
$("img").animate({"opacity": "1"}, 1000);
}
else
{
$(x).animate({height:'25px'});
$("p").animate({"opacity": "0"}, 500);
$("img").animate({"opacity": "0"}, 500);
document.getElementsByTagName("p").style.display = 'none';
document.getElementsByTagName("img").style.display = 'none';
}
}
Related
I am triggering CSS3 Keyframes with javascript but its working for with first call after that any call to that function doesn't animate my div.
Here the Javascript code
function animateShare (imgSrc){
var share = document.getElementById("shareTools");
share.style.animation = "testAnimate 1s ease-in-out 0s"
//shareTools.style.animationPlayState = "running";
}
Sample of the issue (Click red box to preview)
var box = document.getElementById("box");
function animateBox(){
box.style.animation = "box 1s ease-in-out 0s";
}
#box{
background:red;
width:100px;
height:100px;
}
#keyframes box {
50%{width:300px;}
}
<div id='box' onclick='animateBox()'><div>
JSFIDDLE
I want it to animate everytime i call this function.
You can use well known hack: destroy and create element to reset animation.
var box = document.getElementById("box");
function animateBox(){
//destroy and create hack
document.body.removeChild(box);
document.body.appendChild(box);
box.style.animation = "box 1s ease-in-out 0s";
}
#box{
background:red;
width:100px;
height:100px;
}
#keyframes box {
50%{width:300px;}
}
<div id='box' onclick='animateBox()'><div>
In case someone is still interested by this there is another trick that works:
Changing the dataset value to something it has never been, and then use a css matching on that data.
I used this technique when animating the collapsing/uncollapsing of a menu, which of course can happen multiple times. Here's how I did it:
#menu[data-closed^="1"]{
animation:menu_closing;
}
#menu[data-closed^="0"]{
animation:menu_opening;
}
So the animation is based on the first character of the dataset (1 or 0).
Then in the click event that wants to close/open the menu:
var closed = menu_ele.dataset.closed // closed right now
? parseInt( menu_ele.dataset.closed.substr(0,1) )
: 0; // assuming menu is initialized open
var counter = menu_ele.dataset.closed // nb of times the menu was closed or open
? parseInt( menu_ele.dataset.closed.substr(1) )
: 0;
menu_ele.dataset.closed = ''+(1-closed)+(counter+1);
This way the "closed" dataset variable changes like this at every click:
11 (closing for the first time)
02 (reopening for the first time)
13
04
15
06
...
The first digit indicates whether it is currently closed, while all the rest is a counter to make the value new every time.
Think about your code - after first call it does nothing, becouse it already changed animation property of that element.
According to this CSS-Tricks article:
function animateShare (imgSrc){
var share = document.getElementById("shareTools");
share.style.animation = "testAnimate 1s ease-in-out 0s";
shareTools.style.animationPlayState = "paused";
shareTools.style.animationPlayState = "running";
}
add this code in the body section after the element for which the animation is being played-
<script>
document.getElementById('shareTools').addEventListener("animationend", function () {
this.removeAttribute("style");
})
</script>
or if you dont want to remove style attribute ,because you have other css than animation then create a class and add class dynimacally and remove it as above code.
You can reset the animation by just removing the animation property from the styles of the element after the animation has complete - removing the element is unnecessary. In my example, I set the duration in JS, but you could just as easily add an animationend hook to keep it simpler.
JSFiddle
var duration = 1000;
document.getElementById('box').addEventListener('click', function onClick(ev) {
var el = this;
el.style.animation = 'box ' + (duration / 1000 + 's') + ' ease-in-out';
setTimeout(function() {
el.style.animation = ''
}, duration);
});
#box {
background: red;
width: 100px;
height: 100px;
}
#keyframes box {
50% {
width: 300px;
}
}
<div id='box'><div>
So I have a function that I'm trying to create the loops through an array to update a div's innerHTML with JavaScript. I was hoping to set the opacity to 0 and then 1 between setting the new data each time, without using jQuery's fadeIn() and fadeOut().
Here is what I have so far. I think I'm very close, but not sure what I'm doing that's slightly off.
Thanks!
slide(index, tweets, element) {
let self = this;
element.innerHTML = data[index].text;
element.style.opacity = 1;
setTimeout(() => {
index++;
element.style.opacity = 0;
setTimeout(self.slide(index, data, element), 2000);
}, 5000);
}
EDIT
I forgot to mention I'm banking on CSS3 for animation by adding a class to my div that changes with this:
transition: opacity 2s ease-in-out;
I don't know how the code you provided relates to the problem at hand, but here's a simple demo on how to fade out, change the text and then fade back in.
You should be able to expand on this for your needs.
var d = document.querySelector("div");
window.addEventListener("load", function() {
d.classList.add("hidden");
});
var i = 0;
d.addEventListener("transitionend", function() {
if (this.classList.contains("hidden")) {
i++;
this.innerHTML = "SUCCESS! ---> " + i;
}
this.classList.toggle("hidden");
});
div {
opacity: 1;
transition: opacity 2s;
}
div.hidden {
opacity: 0;
}
<div>LOADING...</div>
It just adds the hidden class to trigger the fade out and it binds a transitionend handler to change the text and remove the class for the fade in.
I'm new to html and javascript. Some days back someone provided me with javascript which basically opens a hidden DIV and when other DIV is opened, the first DIV which was opened will close automatically. But now I'm having another problem which does not allow me to have a transition effect. I want a transition within this code. Please help!!!
Here is the JAVASCRIPT:
var divs = ["div1", "div2", "div3", "div4", "div5", "div6", "div7", "div8"];
var visibleDivId = null;
function toggleVisibility(divId) {
if (visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for (i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if (visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
And the HTML goes something like this:
<div id="div1" onClick="toggleVisibility('div1');return false;">
<div id="div2" onClick="toggleVisibility('div2');return false;">
and so on.
I have tried every possible way I could find, but there is no perfect way of achieving the effect. I want the div to be hidden and when the navigation is clicked, the div should open with its contents inside with a transition. Thank you :)
Try using CSS transitions. For example, this will give your divs a transition from collapsed to open over two seconds:
#div1 {
transition: height 2s;
-moz-transition: height 2s; /* Firefox 4 */
-webkit-transition: height 2s; /* Safari and Chrome */
-o-transition: height 2s; /* Opera */
}
I don't know JavaScript, but you will use it to hide the div by default, then on hover or click or whichever action you decide, have it display/hide the divs relative to their respective statuses.
As TylerH noted in the comments, the best way is to use CSS transition:
#mydiv { transition: opacity 2s; }
.hidden { opacity: 0; }
the role of the javascript could be just toggle the class .hidden on the element you want to hide:
document.getElementById("mydiv").classList.toggle("hidden");
See working example on the fiddle
You can't achieve it by setting the display property, since there is no transition between none and block. You can iterate through all the divs like you do in your hideNonVisibleDivs() and put it together with the fiddle code.
you can use Jquery animate
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> <--- this will add Jquery
$("div").onclick(function(){
$(this.attr("id")).fadeIn(1000); <--- this is the animation
});
or if you want you can use the animate function
https://api.jquery.com/animate/
I made a menu on html (on the side and 100% heigth, expandeable as in android holo)
<div id="menu">
<button class="menubutton"></button>
<button class="menubutton"></button>
</div>
The menu normally remains transparent and with a short width:
#menu {
background-color: transparent;
width: 8%;
}
The idea was to expand and color it on hover. It was easy:
#menu:hover {
background-color: blue;
width: 90%;
}
There is no problem untill here. I need the same effect on focus. There is no way in css to change parent css on child focus (neither hover by the way, but it is not needed, cuase i can use the entire menu hover).
So i used a script:
var menubuttonfocus = document.getElementsByClassName("menubutton");
for (i=0; i<menubuttonfocus.length; i++) {
menubuttonfocus[i].addEventListener("focus", function() {
menu.style.backgroundColor = "blue";
menu.style.width = "90%";
});
menubuttonfocus[i].addEventListener("blur", function() {
menu.style.backgroundColor = "transparent";
menu.style.width = "8%";
});
}
The script works just fine, the problem is that when you trigger those events by focusing a button, the css of #menu:hover changes somehow and #menu does not change when hovering. I tried to solve this by doing something similar but with hover instead of focus:
menu.addEventListener("mouseenter", function(){
menu.style.backgroundColor = "blue";
menu.style.width = "90%";
});
menu.addEventListener("mouseout", function(){
menu.style.backgroundColor = "transparent";
menu.style.width = "8%";
});
This works somehow, but it is REALLY buggy.
I tried also to select "#menu:hover,#menu:focus", but it doesn't work because the focus is on the button elements and not in #menu.
Please avoid jquery if posible, and i know it's asking for too much but a pure css solution would be awesome.
Probably helpful info: html element are created dinamically with javascript.
I can show more code or screenshot, you can even download it (it is a chrome app) if needed: chrome webstore page
Thanks.
SOLVED: I did what #GCyrillus told me, changing #menu class on focus via javascript eventListener. .buttonbeingfocused contains the same css as "#menu:hover". Here is the script:
var menubuttonfocus = document.getElementsByClassName("menubutton");
for (i=0; i<menubuttonfocus.length; i++) {
menubuttonfocus[i].addEventListener("focus", function() {
menu.classList.add("buttonbeingfocused");
});
menubuttonfocus[i].addEventListener("blur", function() {
menu.classList.remove("buttonbeingfocused");
});
}
if the problem is what I think it is - you forgetting about one thing:
When you focusing / mouseentering the .menubutton - you are mouseleaving #menu and vice-versa - so your menu behaviour is unpredictible because you want to show your menu and hide it at the same time.
solution is usually setting some timeout before running "hiding" part of the script, and clearing this timeout (if exist) when running "showing" part.
it will be something like this:
var menuTimeout;
function showMenu() {
if (menuTimeout) clearTimeout(menuTimeout);
menu.style.backgroundColor = "blue";
menu.style.width = "90%";
}
function hideMenu() {
menuTimeout = setTimeout( function() {
menu.style.backgroundColor = "transparent";
menu.style.width = "8%";
}, 800);
}
//then add your listeners like you did - but put these functions as a handlers - like this:
menu.addEventListener("mouseenter", showMenu);
...
//in addition you need also "mouseenter" and "mouseleave" events handled on .menubuttons
I hope someone can help me with this, I have this javascript code that toggles my body background
function changeDivImage() {
imgPath = document.body.style.backgroundImage;
if (imgPath == "url(images/bg.jpg)" || imgPath == "") {
document.body.style.backgroundImage = "url(images/bg_2.jpg)";
} else {
document.body.style.backgroundImage = "url(images/bg.jpg)";
}
}
I activate it with this link:
change
my problem is that it works fine in IE and firefox, but in chrome, the links work twice then stop working, it basically switches to bg_2.jpg then once clicked again switches back to bg.jpg then it never works again :/
also, is there an easier way to accomplish this? css only maybe? basically i have two body background pictures and i want to be able to click on the link to toggle 1, then click again to toggle 2 instead, then back to 1, etc...
lastly, how can i make the two backgrounds fade in and out? instead of just switch between the two?
Use CSS classes!
CSS Rules
body { background-image: url(images/bg.jpg); }
body.on { background-image: url(images/bg_2.jpg); }
JavaScript:
function changeDivImage() {
$("body").toggleClass("on");
}
If you want to fade, you will end up having to fade the entire page. Use can use jQuery's fadeIn and fadeOut.
Here is your solution:
(This also supports additional images).
var m = 0, imgs = ["images/bg.jpg", "images/bg_2.jpg"];
function changeDivImage()
{
document.body.style.backgroundImage = "url(" + imgs[m] + ")";
m = (m + 1) % imgs.length;
}
Here is the working code on jsFiddle.
Here is the jQuery version on jsFiddle.
UPDATE: CROSS-FADING Version
Here is the cross-fading jQuery version on jsFiddle.
You wouldn't want the whole page (with all elements) to fade in/out. Only the bg should fade. So, this version has a div to be used as the background container. Its z-depth is arranged so that it will keep itself the bottom-most element on the page; and switch between its two children to create the cross-fade effect.
HTML:
<div id="bg">
<div id="bg-top"></div>
<div id="bg-bottom"></div>
</div>
<a id="bg-changer" href="#">change</a>
CSS:
div#bg, div#bg-top, div#bg-bottom
{
display: block;
position: fixed;
width: 100%;
/*height: 500px;*/ /* height is set by javascript on every window resize */
overflow: hidden;
}
div#bg
{
z-index: -99;
}
Javascript (jQuery):
var m = 0,
/* Array of background images. You can add more to it. */
imgs = ["images/bg.jpg", "images/bg_2.jpg"];
/* Toggles the background images with cross-fade effect. */
function changeDivImage()
{
setBgHeight();
var imgTop = imgs[m];
m = (m + 1) % imgs.length;
var imgBottom = imgs[m];
$('div#bg')
.children('#bg-top').show()
.css('background-image', 'url(' + imgTop + ')')
.fadeOut('slow')
.end()
.children('#bg-bottom').hide()
.css('background-image', 'url(' + imgBottom + ')')
.fadeIn('slow');
}
/* Sets the background div height to (fit the) window height. */
function setBgHeight()
{
var h = $(window).height();
$('div#bg').height(h).children().height(h);
}
/* DOM ready event handler. */
$(document).ready(function(event)
{
$('a#bg-changer').click(function(event) { changeDivImage(); });
changeDivImage(); //fade in the first image when the DOM is ready.
});
/* Window resize event handler. */
$(window).resize(function(event)
{
setBgHeight(); //set the background height everytime.
});
This could be improved more but it should give you an idea.
There's a cleaner way to do this. As a demo, see:
<button id="toggle" type="button">Toggle Background Color</button>
var togglebg = (function(){
var bgs = ['black','blue','red','green'];
return function(){
document.body.style.backgroundColor = bgs[0];
bgs.push(bgs.shift());
}
})();
document.getElementById('toggle').onclick = togglebg;
http://jsfiddle.net/userdude/KYDKG/
Obviously, you would replace the Color with Image, but all this does is iterate through a list that's local to the togglebg function, always using the first available. This would also need to run window.onload, preferably as a window.addEventListener/window.attachEvent on the button or elements that will trigger it to run.
Or with jQuery (as I notice the tag now):
jQuery(document).ready(function ($) {
var togglebg = (function () {
var bgs = ['black', 'blue', 'red', 'green'];
return function () {
document.body.style.backgroundColor = bgs[0];
bgs.push(bgs.shift());
}
})();
$('#toggle').on('click', togglebg);
});
http://jsfiddle.net/userdude/KYDKG/1/
And here is a DummyImage version using real images:
jQuery(document).ready(function ($) {
var togglebg = (function () {
var bgs = [
'000/ffffff&text=Black and White',
'0000ff/ffffff&text=Blue and White',
'ffff00/000&text=Yellow and Black',
'ff0000/00ff00&text=Red and Green'
],
url = "url('http://dummyimage.com/600x400/{img}')";
return function () {
document.body.style.backgroundImage = url.replace('{img}', bgs[0]);
bgs.push(bgs.shift());
}
})();
$('#toggle').on('click', togglebg);
});
http://jsfiddle.net/userdude/KYDKG/2/