Use $(el).addClass('example'); but don't add on load? - javascript

Sorry, I know the title might be strange. Basically, I have the code below:
jQuery(document).ready(function($) {
$('body.single article.project').addClass('grayscale');
});
The problem is that adding the class of grayscale on load initializes the plugin that corresponds to that class, which I don't want to do. I would like to add the class but not initialize the plugin.
Would I have to somehow add the class a few milliseconds after load? How would I go about this?

If the plugin has a self initialization script, then that will be running in dom ready handler. So one solution could be is to use a timer to delay your addClass() by few milliseconds
jQuery(function ($) {
setTimeout(function () {
$('body.single article.project').addClass('grayscale');
}, 100)
});

Using setTimeout you can add the desired class after page load (e.g 100 ms):
$(window).load(function(){
var t=setTimeout(
function(){$("body.single article.project").addClass("grayscale");}, 100)
})

Related

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');
}
});

Jquery/JS malfunction when window is not visible

I'm using JS to make a simple function that displays 3 items one at a time. Works well when you're looking at the page, but when you minimize or change tabs then return, all three items are shown.
Anyone know why? It's as if fadeIn(x) keeps running but hide() stops working. I even checked with different classes.
Here is the code:
$(document).ready(function () {
function start() {
$(".featured-items").hide();
$( ".item-1" ).fadeIn('slow');
setTimeout(one, 5000);
}
function one() {
$(".featured-items").hide();
$( ".item-2" ).fadeIn('slow');
setTimeout(two, 5000);
}
function two() {
$(".featured-items").hide();
$( ".item-0" ).fadeIn('slow');
setTimeout(start, 5000);
}
setTimeout(start, 5000);
});
Problem solved, check the best answer below and make sure to read comments to get a good understanding. Thanks to all
(Updated to provide complete answer)
Your original code is too complex, and a more flexible and simpler implementation is to have just one function, and an array of items in the gallery. Secondly, you should modify your code so the fadeIn animation starts immediately instead of getting queued. Having only one function instead of several makes alterations such as this easier.
Note that in the code below, as in your original code, the various gallery items are classes rather than single element ids and could fade in multiple items.
var gallery = [ '.item-1', '.item-2', '.item-3' ];
var i = 0;
function galleryEvent() {
$(".featured-items").hide();
$( gallery[i] ).fadeIn({duration: 'slow', queue: false});
i = (i + 1) % gallery.length;
setTimeout(galleryEvent, 5000);
}
// start everything off....
galleryEvent();

Change CSS class name dynamically

I need to change the CSS class name of all the elements in a page with a particular class name (.k-textbox). I tried the below code but it does not hit inside the .each() function
<script>
$(document).ready(function () {
$(".k-textbox").each(function () {
//alert("a");
$(this).removeClass("k-textbox");
$(this).addClass("input-medium");
});
});
</script>
In the page i have a 3rd party grid control. the CSS class i have mentioned is inside that third party grid control.
below is the DOM object:
You should try to use chaining API provided by jQuery library:
$(".k-textbox").removeClass("k-textbox").addClass("input-medium");
edit:
As long as the elements are created dynamically you could try to run this code after those elements are created. But if you don't know when they are inserted into the code and doesn't have control over them you could try write simple watch function, i.e:
var watchTimer = setInterval(function () {
var inputs = $('.k-textbox');
if (inputs.length) {
// clear interval
clearInterval(watchTimer);
// change class
inputs.removeClass("k-textbox").addClass("input-medium");
}
}, 100);
use addClass() and removeClass()
$(".k-textbox").removeClass("k-textbox").addClass("input-medium");

Animate.CSS Replay?

I have an animation using Animate.CSS that I would like to have replay if the user would like but what I have attempted does not work. Here is the code:
HTML:
<div class="img-center">
<img src="path.jpg" class="feature-image animated rotateInDownRight" />
</div>
<p class="textcenter"> </p>
<div class="img-center">
Replay
</div>
JS:
var $j = jQuery.noConflict();
$j("#replay").click(function() {
$j('.feature-image').removeClass('animated rotateInDownRight').addClass('animated rotateInDownRight');
});
I do know the script itself works as I can see it happen in Firebug however that animation doesn't animate again. How do I achieve this with Animate.CSS?
This is just a guess but it appears that jQuery isn't "finished" removing the class before it adds it back in. I know this makes NO sense, but it's how JavaScript works. It can call the next function in the chain before all the stuff from the first one is finished. I poked around the code on Animate.CSS's site and saw that they use a timeout in their animation function. You might try the same. Here's their code:
function testAnim(x) {
$('#animateTest').removeClass().addClass(x);
var wait = window.setTimeout( function(){
$('#animateTest').removeClass()},
1300
);
}
What this is doing is exactly like what you are doing except that it waits for the animation to finish, then removes the classes. That way when the other class is added back in, it is truely "new" to the tag. Here is a slightly modified function:
function testAnim(elementId, animClasses) {
$(elementId).addClass(animClasses);
var wait = window.setTimeout( function(){
$(elementId).removeClass(animClasses)},
1300
);
}
Notice two things: First this code would allow you to change what element gets the animation. Second, you remove the classes you added after 1300 milliseconds. Still not 100% there, but it might get you further down the road.
It should be noted that if there is already some animation classes on the object it might break this JS.
found the right answer at animate.css issue#3
var $at = $('#animateTest').removeClass();
//timeout is important !!
setTimeout(function(){
$at.addClass('flash')
}, 10);
Actually a simpler version can avoid using JQuery too.
el.classList.remove('animated','flash');
//timeout is important !!
setTimeout(function(){
el.classList.add('animated','flash');
}, 10);
I believe the issue here is that when I remove the class it was adding the class to quickly. Here is how I solved this issue:
(HTML is same as above question).
JS:
var $j = jQuery.noConflict();
window.setTimeout( function(){
$j('.feature-image').removeClass('animated rotateInDownRight')},
1300);
$j("#replay").click(function() {
$j('.feature-image').addClass('animated rotateInDownRight');
});
What I believe is happening is the jQuery code is removing and adding the class to quickly. Regardless of the reason this code works.
If you wish you can also give a try to this javaScript side development that support animate.css animations. Here is an example of usage.
//Select the elements to animate and enjoy!
var elt = document.querySelector("#notification") ;
iJS.animate(elt, "shake") ;
//it return an AnimationPlayer object
//animation iteration and duration can also be indicated.
var vivifyElt = iJS.animate(elt, "bounce", 3, 500) ;
vivifyElt.onfinish = function(e) {
//doSomething ...;
}
// less than 1500ms later...changed mind!
vivifyElt.cancel();
Take a look here
My answer is a trick to add/remove the css class with a tint delay:
$('#Box').removeClass('animated').hide().delay(1).queue(function() {
$(this).addClass('animated').show().dequeue();
});
Also you can test it without hide/show methods:
$('#Box').removeClass('animated').delay(1).queue(function() {
$(this).addClass('animated').dequeue();
});
I fill it works smooth in chrome but it works with more unexpected delay in FF, so you can test this js timeout:
$('#Box').removeClass('animated');
setTimeout(function(){
$('#Box').addClass('animated');
}, 1);
This solution relies on React useEffect, and it's rather clean, as it avoids manipulating the class names directly.
It doesn't really answers the OP question (which seems to be using jQuery), but it might still be useful to many people using React and Animate CSS library.
const [repeatAnimation, setRepeatAnimation] = useState<boolean>(true);
/**
* When the displayedFrom changes, replay the animations of the component.
* It toggles the CSS classes injected in the component to force replaying the animations.
* Uses a short timeout that isn't noticeable to the human eye, but is necessary for the toggle to work properly.
*/
useEffect(() => {
setRepeatAnimation(false);
setTimeout(() => setRepeatAnimation(true), 100);
}, [displayedFrom]);
return (
<div
className={classnames('block-picker-menu', {
'animate__animated': repeatAnimation,
'animate__pulse': repeatAnimation,
})}
...
)

Using Jquery to slowly hide a div

I'm trying to make some code which finds if a div exists, and if it does then have it fade away slowly. I have this to determine whether or not the div exists
if($('#error').length != 0)
{
$('#error').hide(500);
}
And that does work but only on a refresh, I've been attempting to put it in a timer like this:
var refreshId = setInterval(function()
{
if($('#error').length != 0)
{
$('#error').hide(500);
}
}, 500);
But its not getting rid of the innerHTML! I have some code which on hover alters the innerHTML of the error div so I can fill it up, but for some reason this isn't working, any advice would help!
Thank you!
$("#error").fadeOut(500);
Update:
If you are looking to check for existence:
var msg = $("#error");
if(msg.length) {
msg.fadeOut(500);
}
If you want to empty it:
$("#error").empty();
If you just want to delay 500ms then fade out, do this:
$("#error").delay(500).fadeOut();
To also empty the element, provide a callback to .fadeOut() like this:
$("#error").delay(500).fadeOut(function() {
$(this).html('');
});
There's no need to check .length, if an element that matches the selector isn't present, nothing happens :)
The div you're trying to hide likely hasn't loaded by the time your script runs. Try this; it will defer execution until the DOM is loaded:
$(document).ready(function() {
// put your code here
});
This is a good practice when using jQuery anyway.
Reference: http://docs.jquery.com/Tutorials:Introducing_$(document).ready()

Categories

Resources