css3 animation on click with javascript - javascript

I need to animate several items at the same time, several times on click. I'm not allowed to use Jquery so I'm working with native javascript and CSS3.
Array.prototype.forEach.call(els, function(el) {
elemId = el.getAttribute("id");
var toWidth = boxPos[thisId][elemId].width;
var toHeight = boxPos[thisId][elemId].height;
var toTop = boxPos[thisId][elemId].top;
var toLeft = boxPos[thisId][elemId].left;
var from = "0% {width:"+currPos[elemId].width+"; height:"+currPos[elemId].height+"; top:"+currPos[elemId].top+"; left:"+currPos[elemId].left+";}";
var to = "100% { width:"+toWidth+"; height:"+toHeight+"; top:"+toTop+"; left:"+toLeft+";}";
currPos[elemId].width = toWidth;
currPos[elemId].height = toHeight;
currPos[elemId].top = toTop;
currPos[elemId].left = toLeft;
var styleSheets = document.styleSheets;
for (var i = 0; i < styleSheets.length; ++i) {
for (var j = 0; j < styleSheets[i].cssRules.length; ++j) {
if (styleSheets[i].cssRules[j].type == window.CSSRule.WEBKIT_KEYFRAMES_RULE && styleSheets[i].cssRules[j].name == elemId){
keyframes = styleSheets[i].cssRules[j];
}
}
}
keyframes.deleteRule("0%");
keyframes.deleteRule("100%");
keyframes.insertRule(from);
keyframes.insertRule(to);
el.style.webkitAnimationName = elemId;
});
I've searched around the site and have tried using some of the code. The animation will run once, all the elements but just the first time :'(
Here's a non working example code http://jsfiddle.net/kR384/2/

The animation will run once, all the elements but just the first time
You seem to be looking for the animation-iteration-count CSS property, which specifies how often an animation will run. You can set it to infinite or any numerical (positive) value.
The problem you have with your animations is that they are only started on the first click. After that, you don't change the element's styles (reassigning the animation-name doesn't help) - so no animation will get triggered (even if you changed the keyframes rules). The article at http://css-tricks.com/restart-css-animation/ discusses this and a few solutions.
In your case it would even make sense to change the name of animation to something containing the "state":
if( …cssRules[j].name.split("-")[0] == elemId)
keyframes = styleSheets[i].cssRules[j];
…
var newname = elemId+"-"+thisId;
keyframes.name = newname;
…
el.style.animationName = newname;
(Demo with standard properties and a few bugfixes, updated demo with webkit prefixes)

I was able to fix it just by adding a setTimeout(0) to call the animation after the animation name was set to none.
Here's the fixed code http://jsfiddle.net/kR384/3/:
function resetAndRun(o){
one.style.webkitAnimationName = "none";
…
ten.style.webkitAnimationName = "none";
setTimeout(function(){o.animateBox();}, 0);
}
I hope it's useful for someone.

Related

How do I make an Array of Buttons out of this in JS? And How do I set Random Images with this?

So I`m trying to make a Memory Game. At the moment I´m trying to set the Image of the card randomly but my code just changes to top Image.
var images = ["url(IMG1.jpg)","url(IMG2.jpg)"...];
var randomIMG =0;
var card = "<div class='flip-card'><div class='flip-card-inner'><div class='flip-card-front'><button id='button'onclick='Flipfront(this)'style='width:300px;height:300px; marign:50px; background-image:url(Frontpage.jpg);'></button></div><div class='flip-card-back'><button id='button2'onclick='Flipback(this)'style='width:300px;height:300px; marign:50px; background-image:images[randomIMG];background-repeat:no-repeat;background-size:contain;'></button></div></div></div>"
for (let i = 0; i < level; i++) {
document.querySelector("#container").innerHTML +=card;
}
function RandomBG(){
for (let i = 0; i<level;i++){
randomIMG = Math.floor(Math.random()*9)+0;
document.getElementById("button2").style.backgroundImage = images[randomIMG];
}
}
function Flipfront(el){
RandomBG();
el.closest('.flip-card').classList.add('flipped');
flipped++;
}
And Also for later on, how do I put all my Buttons into an array?
In this line
document.getElementById("button2").style.backgroundImage = images[randomIMG];
you are setting the background of button2. You need to ensure that you get the correct element:
function RandomBG(el){
for (let i = 0; i<level;i++){
randomIMG = Math.floor(Math.random()*9)+0;
el.style.backgroundImage = images[randomIMG];
}
}
and that you pass it:
function Flipfront(el){
RandomBG();
el.closest('.flip-card').classList.add('flipped');
flipped++;
}
If all you are trying to do is get all the buttons in the page:
let btns = document.querySelectorAll("button");
And if you want a few specific ones, change the css selector.

Adding Next & Previous Buttons to modal with JavaScript

I have made a clean modal to use on a website to open images, everything works fine and is pretty nice.
Now I want to make a next image and previous image button for a better user experience.
I have a plan, so I find the index of the current image that is in the modal and I increment it by one on the next button, and decrement it by one on the previous button, HM ok seems easy enough. So how do I go about doing this?
this is my Modal code
window.onload = function() {
var imgArr = document.getElementsByClassName("myImg");
var modalWindow = document.getElementById("myModal");
var modalImg = document.getElementById("img01");
var caption = document.getElementById("caption");
var span = document.getElementById("close");
var modalBlock = document.getElementById("modalBlock");
for (i = 0; i < imgArr.length; i++) {
var picture = imgArr[i];
var list = Array.from(imgArr);
picture.onclick = function() {
openImg(this);
var index = list.indexOf(this);
console.log(index);
};
}
function openImg(pic) {
modalWindow.style.display = "block";
modalBlock.style.transform = "translateY(0%)";
modalImg.src = pic.src;
modalImg.alt = pic.alt;
caption.innerHTML = modalImg.alt;
imgIndex = picture[i];
bodyScrollLock.disableBodyScroll(myModal);
}
};
Now I have the open image that I've clicked on and its index, and I'm stuck on what to do next. I've found the w3 lightbox tutorial, but it's so different from my code I need to swap everything. Does anyone have an idea how I can do this with my own code?
A jsFiddle how it looks at the moment
https://jsfiddle.net/superVoja/eoyda1vh/15/
If you insist on building this from scratch then you will need to start thinking about what you should control with HTML and CSS and leave the rest to do with JavaScript.
I would use Modal window set with Html and hide it with CSS, then when image link and trigger fires I would bring modal to front. Using fadein fadeout, opacity and z-index to make sure that is on the front. Set background to black in order to get the Modal effect.
The faster way is to use library like Lightbox js
Then overwrite using CSS and maybe some js if need to in order to adjust to your liking.
Well, here is the answer I got myself if anyone reads this give yourself some time, you'll find the answer yourself!
I followed my code and did exactly the thing I was trying to do, I found the index of the image that is clicked, and then I just incremented it by one like this.
var next = this.document.getElementById("next");
var slideIndex = "";
for (i = 0; i < imgArr.length; i++) {
var picture = imgArr[i];
var list = Array.from(imgArr);
picture.onclick = function() {
var index = list.indexOf(this);
slideIndex = index;
openImg(imgArr[index]);
console.log(index);
};
}
next.addEventListener("click", function(event) {
openImg(imgArr[(slideIndex += 1)]);
});
It may not look pretty, but it's mine and I am proud of it!
And here is a link How it looks!

javascript getComputedStyle, but not inherited ones (in chrome)

I want to get only the computed styles of the elements on a page, without all the inherited styles
var allElements = document.querySelectorAll( '*' );
for (var i=0;i<allElements.length;i++){
var element = allElements[i];
var css = getComputedStyle(element);
}
this obviously gets a gigantic list of all the styles.
I need only the 'computed styles' that would show up in Chrome's inspector thing when the "show inherited" checkbox is disabled.
What's the JS for this?
EDIT:
I'm basically looking to save all the css I've modified in Chrome inspector. I'm laying out things on a page and I'm playing with fonts and elements placement (dragging jquery draggables around). I want to save the positions and CSS of everything.
Maybe I went way too complex and there's a simple way to save all the modified styles in Chrome inspector?
Try getting computed styles of an element and its parent element, then remove identical properties:
var elems = document.getElementsByTagName('*');
var data = '';
for(var n=0;n<elems.length;n++){
if(elems[n].parentNode.tagName){
data+=elems[n].tagName + ': ' + elems[n].className+'\n';
var style = [];
var prStyle = [];
var result = [];
var css = window.getComputedStyle(elems[n], null);
var prCss = window.getComputedStyle(elems[n].parentNode, null);
for(var i=0;i<css.length;i++){
if(css.getPropertyValue(css[i])){
style[i] = css[i]+':'+css.getPropertyValue(css[i]);
}
}
for(var i=0;i<prCss.length;i++){
if(prCss.getPropertyValue(prCss[i])){
prStyle[i] = prCss[i]+':'+prCss.getPropertyValue(prCss[i]);
}
}
for(var i=0;i<style.length;i++){
if(style[i]!=prStyle[i]){
result.push(style[i]);
}
}
for(var i=0;i<result.length;i++) data+=i+':'+result[i]+'\n';
}
data+='-----------------------\n';
}
return data;

JavaScript - Toggle function

Im trying to hide/show a JS function I have defined in a chrome extension.
What I have so far:
The span classes I am trying to hide are label:
dspan.className = "cExtension";
//Create toggle button:
function createToggleButton(){
var toggleButton = document.createElement("button");
toggleButton.innerHTML = "Toggle Overlay";
toggleButton.id = "Toggle"
var header = document.getElementById("header");
header.appendChild(toggleButton);
toggleExtension();
}
// find all spans and toggle display:
function toggleExtension(){
var spans = document.getElementsByTagName('span');
var toggle = function() {
for (var i = 0, l = spans.length; i < l; i++) {
if (spans[i].getAttribute('class') == 'cExtension')
if (spans[i].style.display == 'none') spans[i].style.display = '';
else spans[i].style.display = 'none';
}
}
document.getElementById('Toggle').onclick = toggle;
}
The button shows on the header, however it is unclickable. If I change document.getElementById('Toggle').onclick = toggle; to document.getElementById('Toggle').onclick = alert{"Hello"); the alert is triggered on page load on not onclick. I am trying to get this done in pure JS. Where am I going wrong?
First of all, document.getElementById("Toggle").onclick = alert("Hello"); will set the onclick event to whatever the alert function returns, not the alert function itself. So the alert function happens at page load so it can figure out what to return. So you could do this: document.getElementById("Toggle").onclick = function(){alert("Hello");}; and that might work.
Edit: Scratch everything that was here: I missed that toggle variable set to a function in toggleExtension.
I haven't tested all this so I can't guarantee that it'll all work in your specific case.
if visible is set remove it, otherwise add it
div.classList.toggle("visible");
add/remove visible, depending on test conditional, i less than 10
div.classList.toggle("visible", i < 10 );
Make sure browser support: http://caniuse.com/#feat=classlist
Why not use jQuery?
It will do all hard job for you.
http://api.jquery.com/toggle/
Cheers!

simple hover and hover out issue in javascript

I am trying to create hover and hover out via javascript.
I have
test.prototype.build = function(){
other codes...
link.href = '#';
link.innerHTML += 'test'
link.onmouseover = hover
link.onmouseout = hoverOut
other codes...
}
function hover(){
var div = document.createElement('div');
div.class='testDiv';
div.innerHTML = 'test';
$(this).prepend(div);
}
function hoverOut(){
var div = document.getElementsByClassName('testDiv');
div.style.display='none';
}
My task is to create a hover and hover out function. My problem is I am not sure how to hide the testDiv when the user hover out of the link.
getElementsByClassName doesn't seem to work in my case. Are there better way to do this in javascript? Thanks a lot!
document.getElementsByClassName('testDiv') returns an collection, not a single object, but you can probably just use this to refer to the current object. Since you showed some jQuery in your original code, I assume that is OK here.
function hoverOut(){
$(this).find(".testDiv").hide();
}
or, in plain javascript, it could be:
function hoverOut(){
var elems = this.getElementsByClassName("testDiv");
for (var i = 0; i < elems.length; i++) {
elems[i].style.display = "none";
}
}
Your hover and hoverOut code don't match though because you're creating a new div on hover every time in hover and then only hiding it in hoverOut so they will accumulate.
If you want to remove the div you added in hoverOut(), you can do that like this:
function hoverOut(){
$(this).find(".testDiv").remove();
}
or in plain javascript:
function hoverOut(){
var elems = this.getElementsByClassName("testDiv");
for (var i = 0; i < elems.length; i++) {
elems[i].parentNode.removeChild(elems[i]);
}
}

Categories