Animate Add Border (grow then shrink) - javascript

I'm trying to build a little effect without using any plugins/libraries besides jquery. The goal is to make it so that when the user changes the value of a box, a border appears, grows to 8px and then shrinks back to 0px. Right now I have the following shell of a code:
$('#pastebox').on('input', function() {
$("#pastebox").css("border", "solid 1px green");
});
I know that I can animate using something like the following, but I'm having trouble getting it to work:
$("#pastebox").animate({border-width: '5px'}, 1000);
I know that if I could get the previous to work, I could then do something like:
$('#pastebox').on('input', function() {
$("#pastebox").css("border", "solid 1px green");
$("#pastebox").animate({border-width: '5px'}, 1000);
$("#pastebox").animate({border-width: '0px'}, 1000);
});
What am I doing wrong?

Object keys cannot contain a minus sign (border-width) - either camelCase it, or quote it:
$('#pastebox').on('input', function() {
$("#pastebox").css("border", "solid 1px green");
$("#pastebox").animate({"border-width": '5px'}, 1000);
$("#pastebox").animate({"border-width": '0px'}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="pastebox" />
Console is always helpful.

Related

Make .css repeat several times based on milliseconds - DRY

I'm trying to learn to improve my code and not repeat myself. I'm trying to use .css() to make an aesthetic design element "flash" before disappearing. I have the result working but I am sure there is a better/shorter way to write this.
At the moment I am setting four intervals which handle changing the CSS.
setTimeout( function(){
$(outputID).css('border-right','2px solid #fff');
},500);
setTimeout( function(){
$(outputID).css('border-right','2px solid #343434');
},1000);
setTimeout( function(){
$(outputID).css('border-right','2px solid #fff');
},1500);
setTimeout( function(){
$(outputID).css('border-right','2px solid #343434');
},2000);
What would be the best way to do this, using the DRY principle? Loop through a 500 millisecond interval and then cancel based on 2000 milliseconds? Using .delay() somehow?
You can use a data-driven approach
var objA = [{
duration: 500,
style: '2px solid #fff'
}, {
duration: 1000,
style: '2px solid #343434'
}, {
duration: 1500,
style: '2px solid #fff'
}, {
duration: 2000,
style: '2px solid #343434'
}];
for (var i = 0; i < objA.length; i++) {
(function(i) {
setTimeout(function() {
$(outputID).css('border-right', objA[i].style);
}, objA[i].duration);
})(i);
}
Make sure to make a closure in the loop by using an IIFE to preserve the i variable
Pure CSS can handle this kind of task via Keyframe Animations. I created a fiddle to get you started, but it needs to be adjusted (especially as I left out vendor prefixes).
It basically boils down to this:
#keyframes borderblink {
0% {
border: 2px solid blue;
}
49% {
border: 2px solid blue;
}
50% {
border: 2px solid white;
}
100% {
border: 2px solid white;
}
}
.mybox.border-animated {
border: 2px solid blue;
animation-name: borderblink;
animation-duration: 0.4s;
animation-iteration-count: 10;
}
If you want to support browsers which do not include this feature (IE8+9, Opera Mini), you could use Modernizr for feature detection and only call your javascript solution if needed. But as it is only a visual goodie, I would probably not go that far if you don't already have Modernizr included.
To elaborate on my comment for jquery animate:
$(outputID)
.delay(500)
.animate({ borderColor: "#fff" }, 10)
.delay(500)
.animate({ borderColor: "#343434" }, 10)
.delay(500)
.animate({ borderColor: "#fff" }, 10)
.delay(500)
.animate({ borderColor: "#343434" }, 10)
You can use variables of course for delay times, the 500 matches the question timeouts and the 10 reduces the animation 'effect' so to flashes rather than pulses.
There are a lot of ways of achieving this. With "pure" JavaScript with a little bit of jQuery, you would do something like:
// flash an element and call the callback when done
var flash = function(element, cb) {
var counter = 0;
var max = 4;
var state = false;
var animate = function() {
// assume we have to css classes "off" and "on"
if (state)
element.removeClass("on").addClass("off");
else
element.removeClass("off").addClass("on");
state = !state;
counter++;
if (counter<max)
setTimeout(animate, 500);
else {
// make sure we end up in "off" state
element.removeClass("on").addClass("off");
if (cb instanceof Function) cb();
}
}
animate();
}
// use it like
flash(myElement, function () {
// we can even do stuff when flashing has stopped, how cool is that!
});
Hello if you consider best way, then according to me you can use css animation keyframes. http://www.w3schools.com/cssref/css3_pr_animation-keyframes.asp
But if you want only to do the job via javascript then you can go with ammarcse' answer.

CSS transitions & timing seem off

First I am open to any ideas / suggestions. I desire to keep the home page as is as far as using the variety of scenic images. The problem I run into is of course what is readable font color on one image is not very readable on another. So I googled some ideas and found a darkened area / backdrop to be the most professional. Great now it works well for all light images but not dark images. So I came up with the idea of switching font color and background depending on the image (dark or light). The trouble I am having is that the font / background switch about 1-2 seconds before the image does??? Further I think I would like to add a cross fade or some animation effect to make the switch soother. Here is the site:
http://alexandredairy.com/staging/
Again I am open to any ideas / suggestions
So the first thing I did was to name the images with a dark or light prefix so the css can switch accordingly. So I have twenty or so images named like so:
Dark_Cover1_PastrDairy.jpg or Light_Cover1_PastrPoultry.jpg
My CSS is:
/*Back ground shading so we can read text*/
.lighttextbackground
{
color:#000;
background-color:rgba(255, 255, 255, 0.35);
box-shadow:0px 0px 10px 10px rgba(255, 255, 255, 0.35);
}
.lighttextbackground a
{
color:#000;
}
.lighttextbackground p
{
color:#000;
}
.darktextbackground
{
color:#fff;
background-color:rgba(0, 0, 0, 0.35);
box-shadow:0px 0px 10px 10px rgba(0, 0, 0, 0.35);
}
.darktextbackground a
{
color:#fff;
}
.darktextbackground p
{
color:#fff;
}
A typical HTML element that I want the effect on is:
<div id="pageslogan" class="slogan lighttextbackground">
....code...
</div>
As for the jquery I am posting just the function(s) I think relevant. I can definately post more if needed or you can browse the site and get everything using developer tools (F12).
function changeImageHandler(){
var imgSRC;
$("#inner ul>li").eq(currImg).addClass("active");
$("#inner ul>li").eq(prevImg).removeClass("active");
loadComplete = false;
image.addClass("topImg").css({"z-index":1});
imgSRC = imageSRCLink.eq(currImg).attr("href");
imageHolder.append("<img class='bottomImg' src="+imgSRC+" alt=''>");
$(".bottomImg").css({display:"none", "z-index":0}).bind("load", loadImageHandler);
$("#imgSpinner").css({display:"block"}).stop().animate({opacity:1}, 500, "easeOutCubic");
imgName = imageSRCLink.eq(currImg).attr("href").split('/')[2];
TextReadabilityHandler(imgName.substring(0, 5));
discription.eq(currImg).css({left:$(document).width()*dragDirection, display:"block"}).animate({left:0}, 1000, "easeInOutCubic");
discription.eq(prevImg).animate({left:$(document).width()*dragDirection*-1}, 1000, "easeInOutCubic", function(){
discription.eq(prevImg).css({display:"none"})
});
}
About 3/4 the above function you see TextReadabilityHandler which is where the switch takes place:
function TextReadabilityHandler(_imgNameSwitch)
{
if(_imgNameSwitch == 'Light')
{
$("#pagetitle").attr('class', 'sitetitle lighttextbackground');
$("#pagemenu").attr('class', 'sf-menu lighttextbackground');
$("#pageslogan").attr('class', 'slogan lighttextbackground');
}
else if (_imgNameSwitch == 'Dark_')
{
$("#pagetitle").attr('class', 'sitetitle darktextbackground');
$("#pagemenu").attr('class', 'sf-menu darktextbackground');
$("#pageslogan").attr('class', 'slogan darktextbackground');
}
else
{ alert(_imgNameSwitch); }
}
So I was thinking to do a crossfade while the image switches. Where I am stumped is how to implement. As I have it written the html element is updated with a new class and that change is applied instantly. How / where would I implement a .fadeOut() / .fadeIn()??
Thank You
As a side note I tried submitting my site to csscreator.com for critical review / suggestions on the design with no feedback. Any suggestion where I can get the design critiqued would be helpful.
Edit
Thank you user3037493 and Zeaklous.
You both broke through the road block I was up against. Here is what your answers triggered in my brain.
I added a custom namespace (for readability)
/* Text Readability switching */
var txtread =
{
onReady: function(_imgname)
{
txtread.fadeoutText(_imgname);
txtread.fadeinText();
},
fadeoutText: function(_imgname)
{
$("#pagetitle").fadeOut(1250);
$("#pagemenu").fadeOut(1250);
$("#pageslogan").fadeOut(1250);
$("#sitecopy").fadeOut(1550, txtread.TextReadabilityHandler(_imgname));
},
fadeinText: function()
{
$("#pagetitle").fadeIn(1250);
$("#pagemenu").fadeIn(1250);
$("#pageslogan").fadeIn(1250);
$("#sitecopy").fadeIn(1250);
},
TextReadabilityHandler: function(_imgNameSwitch)
{
if(_imgNameSwitch == 'Light')
{
$("#pagetitle").attr('class', 'sitetitle lighttextbackground');
$("#pagemenu").attr('class', 'sf-menu lighttextbackground');
$("#pageslogan").attr('class', 'slogan lighttextbackground');
}
else if (_imgNameSwitch == 'Dark_')
{
$("#pagetitle").attr('class', 'sitetitle darktextbackground');
$("#pagemenu").attr('class', 'sf-menu darktextbackground');
$("#pageslogan").attr('class', 'slogan darktextbackground');
}
else
{ alert(_imgNameSwitch); }
}
}
and then I modified the these two lines in ChangeImageHandler.
imgName = imageSRCLink.eq(currImg).attr("href").split('/')[2];
TextReadabilityHandler(imgName.substring(0, 5));
to
imgName = imageSRCLink.eq(currImg).attr("href").split('/')[2];
txtread.onReady(imgName.substring(0, 5));
So the whole thing looks like this:
function changeImageHandler(){
var imgSRC;
$("#inner ul>li").eq(currImg).addClass("active");
$("#inner ul>li").eq(prevImg).removeClass("active");
loadComplete = false;
image.addClass("topImg").css({"z-index":1});
imgSRC = imageSRCLink.eq(currImg).attr("href");
imageHolder.append("<img class='bottomImg' src="+imgSRC+" alt=''>");
$(".bottomImg").css({display:"none", "z-index":0}).bind("load", loadImageHandler);
$("#imgSpinner").css({display:"block"}).stop().animate({opacity:1}, 500, "easeOutCubic");
imgName = imageSRCLink.eq(currImg).attr("href").split('/')[2];
txtread.onReady(imgName.substring(0, 5));
discription.eq(currImg).css({left:$(document).width()*dragDirection, display:"block"}).animate({left:0}, 1000, "easeInOutCubic");
discription.eq(prevImg).animate({left:$(document).width()*dragDirection*-1}, 1000, "easeInOutCubic", function(){
discription.eq(prevImg).css({display:"none"})
});
}
and now I have my fade in / out effect and while the text blocks are faded out I do a quickie class change by making the copyright fadeout take a bit longer (ensuring vast majority of content is gone) then executing the return function to switch classes as seen in my custom namespace here:
$("#sitecopy").fadeOut(1550, txtread.TextReadabilityHandler(_imgname));
Of course nothing works perfectly and for some reason I haven't figured out yet one element is not fading in / out?? That is off topic here so I posted a new SO question here for that one.
Element refusing to fade out or in
sorry, i dont have enough reputation to comment on your question, and this answer is really just a comment.... white text with black background is going to be easier to read. here is a JSfiddle http://jsfiddle.net/Kyle_Sevenoaks/ZnfED/1/
basically, the css for your .slogan p you would make the color to be white and add this text shadow
{text-shadow:
-1px -1px 0 #000,
1px -1px 0 #000,
-1px 1px 0 #000,
1px 1px 0 #000;}
edited to add: to have the textbackground change before the image, call TEXTREADABILITYHANDLER at the beginning of the changeImageHandler function and maybe try putting a delay on the imgSpinner.animate per http://api.jquery.com/delay/
You could try doing it yourself as this SO answer and corresponding example describe, but depending on the image it is liable to be incorrect more so than if you went with an actual plugin
Background Check is what I would likely recommend. It's not exactly what you are requesting, but it changes the background of elements as well as the text on top of it. One added, you can use it simply by declaring
BackgroundCheck.init({
targets: '.ui', // Select the divs to have the background changed
images: '.thumbnail' // Select the list of images to be analyzed
});

Using jQuery to bump list item to right on hover

I am trying to bring a little more attention to the list item being hovered by "bumping" the text a little to the right then back again when hovered over. This is what I have:
$('.ipro_menu ul li a').hover(function(){
$(this).animate({
'padding-left':'20px'},100,function(){
$(this).animate({
'padding-left':'15px'});
});
});
The padding is originally 15px, so when you hover over a link in the list, the padding increases by 5px, then quickly goes back to 15px again. The problem is that it is moving more than one element at a time. Sometimes it moves not only itself, but also the item above or below it.
Any suggestions?
I made a quick jsfiddle of what I think you are looking to do.
http://jsfiddle.net/tuXcA/
The code is basically:
$('ul').find('li').hover(function() {
$(this).animate({
'padding-left':'20px'
},100);
}, function() {
$(this).animate({
'padding-left':'0px'
},100);
});
Slides right on hover, then slides back to normal position when not hovered.
The padding is originally 15px, so when you hover over a link in the list, the padding increases by 5px, then quickly goes back to 15px again
So basically you want a bounce effect? If so:
var cssOver = { 'padding-left': '25px' },
cssOut = { 'padding-left': '15px' },
overDuration = 100,
outDuration = 100,
selector = '.ipro_menu ul li';
$(selector).mouseover(function(){
var _this = $(this);
_this
.clearQueue()
.animate(cssOver, overDuration, function(){
_this.animate(cssOut, outDuration);
});
});
Live example: http://bl.ocks.org/3077195
Personally I would suggest using this plugin: http://ricostacruz.com/jquery.transit/

Firefox not setting css style from JavaScript?

I need to respond to a hover over a table cell. This css code works fine:
#dialog-date-picker td {
border-style: outset !important;
border : 2px solid #606060;
cursor: pointer;
...etc
}
#dialog-date-picker td:hover {
border-style: inset !important;
border : 2px solid #6060b0;
}
However, I need a more complex hover response that I can't get in css, and I've started as follows:
$('#dialog-date-picker td').hover(function () {
$(this).css('border-style', 'inset !important');
$(this).css('border', '2px solid #6060b0');
}, function() {
$(this).css('border-style', 'outset !important');
$(this).css('border', '2px solid #606060');
}
);
The jQuery equivalent works in Chrome and Opera, but not FF. Firebug shows that the code is executed, but nothing happens. Any ideas why this should be? Thanks.
EDIT
Folks - I understand that this isn't elegant, and I should be using css and JS, and adding a class, but that's not the issue. I just took a working css solution and, as a first step, just put it in the JS above. At that point I found out that the JS equivalent worked in Opera and Chrome, but not FF. Combining the two css calls, and converting 'border-style' to 'borderStyle', didn't make a difference; it still doesn't work in FF.
Is it relevant that the dialog (jQuery UI) is dynamic? I've got a table within the dialog. Thanks for all the input.
EDIT2
Simplified the code to:
$('#dialog-date-picker td').hover(
function() { $(this).css('border', '2px inset #6060b0 !important'); },
function() { $(this).css('border', '2px outset #606060 !important'); }
);
with no change (works in IE8, Opera, Chrome, Safari, but not FF 3.6 or 8.0).
EDIT3
Ok, given up on this. All the alternative (and better) stylesheet versions work in FF, so it seems a bit pointless worrying about why this particular code doesn't work in FF...
The problem is because the second css() call is overwriting the first. Try this:
$('#dialog-date-picker td').hover(
function () {
$(this).css({
'border-style': 'inset !important',
'border': '2px solid #6060b0'
});
},
function() {
$(this).css({
'border-style': 'outset !important',
'border': '2px solid #606060'
});
}
);
Example fiddle
EDIT
Here's an extra fiddle thanks to PPvG and ptriek with a much more elegant solution which uses classes and solves the issue of setting an outset border, then immediately making it solid.
Updated Fiddle
$('#dialog-date-picker td').hover(function () {
$(this).css({
'border-style' : 'inset !important',
'border' : '2px solid #6060b0'
});
}, function() {
$(this).css({
'border-style' : 'outset !important',
'border' : '2px solid #6060b0'
});
});
Thats also a little clean up in code for you too! Try not too use so many CSS functions, as your just essentially 're-dipping' when there's no reason too!
Also is your #dialog-date-picker being created by jQuery, if so you need to nest this function inside the function that creates that td.
i guess the id dialog-date-picker is created dynamically so better to use on with events mouseover and mouseout.
$('#dialog-date-picker td').on('mouseover' :
function () {
$(this).css('border-style', 'inset !important');
$(this).css('border', '2px solid #6060b0');
},
'mouseout' :function() {
$(this).css('border-style', 'outset !important');
$(this).css('border', '2px solid #606060');
}
);
You should preferably change both your CSS and JS and add a class to the TD on hover, and define this in your CSS. This reduces JS and keeps things where they belong:
http://jsfiddle.net/bDBWE/3/
$('#dialog-date-picker td').hover(function () {
$(this).addClass('hover');
}, function() {
$(this).removeClass('hover');
});
jquery css() uses inline style sets to set the property. The API it's using doesn't allow !important in the string.
See also https://bugs.webkit.org/show_bug.cgi?id=73941 for the WebKit bug on this; the existence of that bug (which they only recently fixed) is what allowed your script to work in Chrome and Safari.

jquery fading border not working

I just want some simple links where if it's hovered over, instead of having a line appear under it suddenly, it should fade. I'm trying this, but to no avail:
$(document).ready(function(){
$('#footer a').mouseover(function(){
$(this).animate({
border-bottom: 'border-bottom: 1px solid #D8D8D8'
}, 1000, function() {
// Animation complete.
});
});
});
What should I be doing?
Thanks.
You need a few changes here, first you should animate only the color, like this:
$(function(){
$('#footer a').mouseover(function(){
$(this).animate({
borderBottomColor: '#D8D8D8'
}, 1000, function() {
});
});
});​
Also, give the border an initial size so it doesn't just "appear" (when changing from 0 to 1px), like this:
​​#footer a { border-bottom: solid 1px transparent; }​
You can see a working demo here, to make this work you need either the color plugin or jQuery UI so the colors can animate...core doesn't handle colors, or transitioning anything that's not a number.
Here's a more complete demo, probably what you're ultimately after:
$(function(){
$('#footer a').hover(function(){
$(this).animate({ borderBottomColor: '#D8D8D8' });
}, function() {
$(this).animate({ borderBottomColor: 'transparent' });
});
});
​

Categories