Add one class at a time with Javascript? - javascript

I have a function that add a class (a animation) on the element, but it is not working as planned.
I want that the user add one class at a time. How verify this? I really don't know how to do that with raw Javascript. With jQuery would be easy, I think, because jQuery has the brilliant one() function.
I try to remove the class when the animation stops, but the user still can add multiple classes. And so, there will be several classes during the animation and will be removed only when the animations are gone. Look:
el.classList.add("test", anotherClass);
el.addEventListener("webkitAnimationEnd", function() {
el.classList.remove(anotherClass);
}, true);`
Basically, what im trying to do:
Button click > Add class > When finished or interrupted by another button (and, therefore, new class), remove class or add the new
Obs.: I'm noob with JavaScript, so, please, do not explain with difficult words.

Try something simple:
function setSingleClass(el, singleClass)
{
if (!el._isSingleClassSet) {
el.classList.add(singleClass);
el._isSingleClassSet = 1
el.addEventListener("webkitAnimationEnd", function () {
el.classList.remove(singleClass);
el._isSingleClassSet = 0
}, true);
}
}

Related

Using jquery to show and then hide div - memorygame

I'm trying to create a memory game using html ccs js and jquery.
The problem I'm having is that when I'm trying to show the div that states if the answer was correct, the div becomes visible like I want but it won't disappear.
I have tree conditions and the problem occurs with every one of them:
$(".wrong").show(function(){
$(this).hide(1000);
});
you can use setTimeout function to hide the element.
setTimeout(function () {
$(".wrong").hide()
}, 1000);

Add body class if class ".loading" active

I am using the lazyload for a project, it loads images progressively.
https://github.com/verlok/lazyload
When the images are loading, the "loading" class is activated in the <img class = "loading"> ... </ img>
and when it finishes loading, the "loading" class is replaced by the class "loaded"
I want to know if it would be possible to add a class to a div based on the activity of the "loading" class.
I made a rather rustic example, just to demonstrate my goal.
if ($('img').hasClass('loading')) {
$("body").addClass("images-is-loading");
$(".post-thumbnail").addClass("post-images-is-loading");
}
Could someone clarify me? Thanks
You'll need to continuously check for the condition on regular intervals using setInterval . Here is the sample code:
setInterval(function() {
if ($("img.loading").length) {//Checks if there is such element
$("body").addClass("images-is-loading");
$(".post-thumbnail").addClass("post-images-is-loading");
} else {
$("body").removeClass("images-is-loading");
$(".post-thumbnail").removeClass("post-images-is-loading");
}
}, 1000);
If you are using any framework like Angular, data binding takes care of continuously checking the classes being added or deleted.
In other case, you have to use "setInterval" function of JavaScript.
ex:
setInterval (function () {
// Your Code...
}, some frequency of time)
setInterval isnt great for this in my opinion, maybe it is better to look for the build in callback events like:
var lazyLoadInstance = new LazyLoad({
elements_selector: ".lazy",
class_loading: "loading-img",
callback_enter: function(el) {
$(body).addClass('loading');
},
callback_loaded: function(el) {
$(body).removeClass('loading');
}
});

Targeting multiple instances of the same class/ID with Javascript

I'm trying at the moment to target multiple instances of the same div class (.overlay) - the basic idea I'm trying to execute is that each div contains a HTML5 video inside another wrapped div which on mouseenter reveals itself, sets the video timeline to 0 and plays, and on mouseout resets the video to 0 again.
The problem I'm having is that only the first item of my grid works at the moment with nothing happening on the rollover of the others. This is my Javascript:
$(document).ready(function() {
$('.overlay').mouseenter(function(){
$('#testvideo').get(0).play();
}).mouseout(function() {
$('#testvideo').get(0).pause();
$('#testvideo').get(0).currentTime = 0;
})
});
I've also tried the following
$(document).ready(function() {
$('.overlay').mouseenter.each(function(){
$('#testvideo').get(0).play();
}).mouseout(function() {
$('#testvideo').get(0).pause();
$('#testvideo').get(0).currentTime = 0;
})
});
but that simply broke the functionality all together!
Here is a fiddle showing what should happen: http://jsfiddle.net/jameshenry/ejmfydfy/
The only difference between this and the actual site is that there are multiple grid items and thumbnails. I also don't want the behaviour to by asynchronous but rather individual - does anyone have any idea where I'm going wrong (I'm guessing my javascript!)
The problem is that you're using always $('#testvideo'), independent on the div you're entering the mouse. Since the HTML's id property must be unique, only the first element that you set the id testvideo will work the way you expect.
You should be using the video tag referenced by the div.overlay, or you could add a CSS class to the video tags, so you could use that class to find the video.
The code below will get the overlayed video, independent of which it is.
$(document).ready(function() {
$('.overlay').hover(function() {
$(this).parent().find('video').get(0).play();
}, function() {
var video = $(this).parent().find('video').get(0);
video.pause();
video.currentTime = 0;
});
});
Take a look at your updated fiddle.
The first way you did it should work, the second one not. But, you shouldn't use an id like #testvideo if there are a lot of videos (one on each .overley element). Having multiple instances of the same id produce unexpected behaviuor, like "only working on the first item".
You should change your #testvideo with .testvideo and change your code to something like this:
$(document).ready(function() {
$('.overlay').mouseenter(function(){
$(this).find('.testvideo').play();
}).mouseout(function() {
$(this).find('.testvideo').pause();
$(this).find('.testvideo').currentTime = 0;
})
});

Add automation to a jQuery Content Slider

I'm looking for some help to implent a timer for this script I'm linking to.
As it is now, it toggles different slides when hovering the list to the right, but I want the slider to automatically jump ahead to the next slide after a certain amount of time until it reaches the end and then goes back to the top.
The catch though is that it also needs to work as it is now, so that you can toggle via hovering and when you stop hovering it should remember the position and jump ahead to the next item.
I realize this is alot to ask for, but some pointer would be great, thanks alot!
DEMO: http://jsbin.com/acorah
Your code is taking a bit of a performance hit with that each() loop which I don't think you need. You're binding events inside the loop and you're limiting your possibilities by declaring your actions inside the bind() scope. You want to be able to call events on any object and not only a single element; $('.cn_item') in your case.
The idea is to keep track of your current slide with a class, let's say .cur.
Then you create an object where you declare all your methods. The main methods or actions are getCur() and goTo() and mostly everything else will use these. ie. next() is just a shortcut for goTo()
var actions = {
getCur: function(){ return idx; },
goTo: function(idx){
// The simplest case
$slides.hide().eq(idx).show();
},
next: function(){ this.goTo(this.getCur()+1); },
prev: function(){ this.goTo(this.getCur()-1); }
.
.
.
}
Now you can call actions on events by simply doing this:
$slides.click(function(){ actions.goTo($(this).index()); });
$next.click(function(){ actions.next(); });
And then you can setInterval() to add a timer.
setInterval(actions.next, 1000);
This tutorial might help. I basically cover everything involved in making a slider. I would change some things as of today, we learn new ways to code stuff everyday.

jQuery code critque

Thought I'd post here. My first hour on jQuery, actually first programing ever done. Would love to learn whats not right and how it could be better.
$(function() {
function hide_me()
//A place to specify which elements you want hidden, on page load.
{
$("li.credentials").hide();
}
function first_bow()
//The div right_column takes a bow on initial load.
{
$("div#right-column").show("drop");
}
function bigpeek()
//The third column toggles in/out. All elements under div right_column.
{
$("div#right-column").toggle("drop", "fast");
}
function smallpeek()
//Smaller snippets like credentials or user assignment flying in/out.
{
$("li.credentials").toggle("drop", "fast");
}
$(document).ready(function() {
$("*").ready(hide_me);
$("*").ready(first_bow);
$(".btn-new-email").click(bigpeek);
$(".button").click(smallpeek);
$(".icon-delete").mouseover(function() {
$(this).effect("bounce", "fast");
});
});
});
The best thing to learn about programming is how to effectively re-use code. In your code, you have set up some functions that you yourself claim will do a bunch of the same thing. So instead, you could make it better by only writing code to do the repeated task once.
For one example, instead of creating a function where you place a bunch of things that need to be hidden, I would add a class to the elements that should be hidden, and then hide all those elements:
function hide_me()
//Hides anything with the "hide-me-onload" class
{
$(".hide-me-onload").hide();
}
$(function () {
...
}
is the same as
$(document).ready(function() {
...
}
So you can move the method calls from inside your $(document).ready() to be inside your $(function(){}). Also try to use IDs instead of class names wherever possible. Something like this will go through the entire DOM to look for an element
$(".item")
Be more specific
$("#itemID") // use IDs instead of Classes
//If you have to use class name then you can speed up the selector by adding the element tag before it
$("div.item")
Using $("*").ready() within $(document).ready() is redundant... you already know using all of the elements are ready! Also, in general using the universal selector $('*') is very inefficient.
So, the first two lines of your $(document).ready() can just be:
hide_me();
first_bow();
Other than that and a couple of issues with organization and nomenclature you're off to a great start, keep it up!

Categories

Resources