jquery animate dont fire unless value is changed - javascript

I have a grid width dynamic boxes where on parent mouseleave if input value is changed the boxes resize. Equal resize is not complete but for the purpose of this question it works.
in boxes add anything that equals to 100 eg: 40 10 10 10 30 or 50 50 0 0 0
http://jsfiddle.net/MT4Fp/16/
$('ul').on('mouseleave', function (event) {
var elems = $(this).find('input');
elems.each(function (el, i) {
$(this).parent().parent().animate({
width: $(this).val() + '%'
}, 500);
if ($(this).val() <= 1) {
$(this).parent().parent().addClass('hidden');
} else if ($(this).val() > 1) {
$(this).parent().parent().removeClass('hidden');
}
});
});
problem i have is that on mouseleave even if you dont change anything the animate starts animating , you can see this when you enter/leave the grid , the size of grid will change for few sec.
how can i run animate only if the input is changed? I have tried , keyup , change and few other methods but could not get it to work. The main thing is that the animation fires only on grid leave and if something is changed.
any help is appreciated. Thank you!

OK, a comment is not to big.
var i = $("#inputid").val();
$('ul').on('mouseleave', function (event) {
if ($("#inputid").val() == i){return true;}
EDITED: i = $("#inputid").val();
var elems = $(this).find('input');
elems.each(function (el, i) {
$(this).parent().parent().animate({
width: $(this).val() + '%'}, 500);
if ($(this).val() <= 1) {
$(this).parent().parent().addClass('hidden');
} else if ($(this).val() > 1) {
$(this).parent().parent().removeClass('hidden');
}
});
});
Also, you may consider targeting elements like $('ul').on('mouseleave','.i',....)
Sorry, I edited. If it is a change, addit to the value of i var.

You want to animate for value change, not for 'mouseleave'. So bind value change with this method.
jQuery('input[type="text"]').on('input', function() {
// do work such as animate ...
console.log($(this).val()); // i tried with this and get value
})

Related

Change transition type depending on screen size

Basically what code should do - if website size is greater than 750 px then dropdown slides down with hover effect, but if its less than 750 px dropdown works on click toggle.
I check if media query has changed with (greater than 750px float == left) and if (less than 750 px float == none)
It works onclick toggle if i start with 650 px web width, but when i resize it to full screen and then go back to 650 px, it shows as hover and as onclick toggle not only on click toggle.
Anyone can explain what i am doing wrong? I am quite new to jquery.
Thanks in advance!
$(document).ready(function() {
checkSize();
$(window).resize(checkSize);
});
//Function to the css rule
function checkSize() {
if ($("#drop > li").css("float") == "none") {
$('#dropdown-btn').click(function() {
$('.dropdown').slideToggle(200);
});
} else if ($("#drop > li").css("float") == "left") {
$('#dropdown-btn').hover(
function() {
$('.dropdown').slideDown(200);
},
function() {
$('.dropdown').slideUp(200);
}
);
}
};
I think your problem is the fact, that your checkSize function binds an event every single time it triggers, which is quite a lot on resize. A better way is to get rid of your resize function and use the if statement right in your event like so:
$(document).ready(function() {
$('#dropdown-btn').on('click',function() {
if($("#drop > li").css("float") == "none"))
$('.dropdown').slideToggle(200);
});
$('#dropdown-btn').on({
mouseenter: function () {
//stuff to do on mouse enter
if ($("#drop > li").css("float") == "left")
$('.dropdown').slideDown(200);
},
mouseleave: function () {
//stuff to do on mouse leave
if ($("#drop > li").css("float") == "left")
$('.dropdown').slideUp(200);
}
});
You should also use jQuerys on() function instead of hover() or click().
Reference: http://api.jquery.com/on/

Textarea disappears after animation

I am using the following code to animate the disappearing of a textarea once the control is out of focus and the textarea is empty.
$(this).blur(function ()
{
var value = $(this).val().trim();
if (value == "")
{
// empty; make it disappear
$(this).animate({
width: 0,
height: 0
}, 1000,'linear',
function ()
{$(this).parent().css("display", "none")});
}
});
The box disappears without animation. But if i run the following code the animation is still there:
$(this).blur(function ()
{
var value = $(this).val().trim();
if (value == "")
{
// empty; make it disappear
$(this).animate({
width: 0,
height: 0
}, 1000);
}
});
I am not sure why the display:none code is executing before the completion of the animation.
JSFiddle: https://jsfiddle.net/7pbuxtkz/
Give this a try. It utilizes the promise() and done() instead of using it directly from the callback itself. Although your original code works for me, it's worth trying. Promise() will ensure that all of the animations are done.
$('.notesArea').each(function () {
$(this).blur(function () {
var value = $(this).val().trim();
if (value == "") {
// empty; make it disappear
$(this).animate({
width: 0,
height: 0
}, 1000).promise().done(function () {
$(this).parent().css("visibility", "hidden")
});
}
});
});
Let me know how it goes and we'll go from there. As I mentioned before, if this doesn't work, then I feel it's something taking place from your CSS. If that's the case, I'll poke around and see what I can find out for you.
More information on promise(): https://api.jquery.com/promise/
I know you said you're using multiple CSS files, which is why you didn't post it here. I would go through those CSS files and see if there is anything that's setting the transition-duration on it to something lower than what you're setting your animation's duration to.

jQuery: Hide element after scrollTop value is passed

I want to hide a div once my slider passes a scrollTop() value of 200px. I've looked at this article and tried using it as a template for what I want. I have the following code, but its not hiding the element. Live site
function removeArrow() {
$(window).scroll(function() {
if($('.portfolio-sliders:first-child').scrollTop() > 100) { //use `this`, not `document`
$('.scrl-dwn').css({
'display': 'none'
});
}
});
}
UPDATE
I've updated by code:
function removeArrow() {
$(window).scroll(function() {
var slider = $('.portfolio-sliders:first-child').position.top;
if(slider >= 10) {
$('.scrl-dwn').hide();
}
});
}
which should work, but its not...
Position is a function, not a property. You need to call the function with ():
var slider = $('.portfolio-sliders:first-child').position().top;
Replace your whole removeArrow function with this code.
(If you open your live site, and run this in the console, you can see it's working).
The scroll event never fired, so I handled theese mousewheel events instead.
$(window).bind('DOMMouseScroll mousewheel', function() {
var div = $(".portfolio-sliders:first-child"),
top = div.position().top,
display = top < 400 ? 'none' : '';
$('.scrl-dwn').css({ 'display': display });
});
Use This :
$(window).scroll(function(){
if ($(window).scrollTop() > 660)
{
$(".Left-Section").css("position", "fixed");
$(".Center-Content").css("margin-top", "0");
$(".Right-Nav img").css("transform", "rotate(360deg)");
}
;)

Trying to animate with on change

I am trying to animate the width of something when the .change() function is called, but it doesn't seem to be working.
Any idea why?
Here is my code:
$(document).ready(function(){
$('#code').change(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
Here is a js fiddle with the issue recreated: http://jsfiddle.net/BUSSX/
If you really want a change event for input controls, then here's a jQuery plug-in method I wrote a little while ago that does this and works for nearly all ways that the content of the input control can be changed including drag/drop, copy/paste, typing, etc... It takes advantage of newer events that help with this if they exist, otherwise it falls back to listening for lots of other events and looking to see if the data has changed.
(function($) {
var isIE = false;
// conditional compilation which tells us if this is IE
/*#cc_on
isIE = true;
#*/
// Events to monitor if 'input' event is not supported
// The boolean value is whether we have to
// re-check after the event with a setTimeout()
var events = [
"keyup", false,
"blur", false,
"focus", false,
"drop", true,
"change", false,
"input", false,
"textInput", false,
"paste", true,
"cut", true,
"copy", true,
"contextmenu", true
];
// Test if the input event is supported
// It's too buggy in IE so we never rely on it in IE
if (!isIE) {
var el = document.createElement("input");
var gotInput = ("oninput" in el);
if (!gotInput) {
el.setAttribute("oninput", 'return;');
gotInput = typeof el["oninput"] == 'function';
}
el = null;
// if 'input' event is supported, then use a smaller
// set of events
if (gotInput) {
events = [
"input", false,
"textInput", false
];
}
}
$.fn.userChange = function(fn, data) {
function checkNotify(e, delay) {
var self = this;
var this$ = $(this);
if (this.value !== this$.data("priorValue")) {
this$.data("priorValue", this.value);
fn.call(this, e, data);
} else if (delay) {
// The actual data change happens aftersome events
// so we queue a check for after
// We need a copy of e for setTimeout() because the real e
// may be overwritten before the setTimeout() fires
var eCopy = $.extend({}, e);
setTimeout(function() {checkNotify.call(self, eCopy, false)}, 1);
}
}
// hook up event handlers for each item in this jQuery object
// and remember initial value
this.each(function() {
var this$ = $(this).data("priorValue", this.value);
for (var i = 0; i < events.length; i+=2) {
(function(i) {
this$.on(events[i], function(e) {
checkNotify.call(this, e, events[i+1]);
});
})(i);
}
});
}
})(jQuery);
Then, your code would look like this:
$(document).ready(function(){
$('#code').userChange(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
In looking at your code, you are increasing the width of the input control by 16px on every change. You probably should be looking at the number of characters in the control and assessing what to do about the width based on that because this will make things wider event if the user hits the backspace key. I'd probably do something like this that grows the item as content is added, but doesn't shrink it:
$(document).ready(function(){
$('#code').userChange(function(){
// on change animate width as chars are added
// only grow it when the width needs to be larger than it is currently
var item = $(this);
var origWidth = item.data("initialWidth");
var curWidth = item.width();
if (!origWidth) {
origWidth = curWidth;
item.data("initialWidth", origWidth);
}
var newWidth = origWidth + (8 * item.val().length);
if (newWidth > curWidth) {
item.stop(true, true).animate({width: newWidth}, 500);
}
});
});
Working code example: http://jsfiddle.net/jfriend00/BEDcR/
If you want the userChange method to execute when you programmatically set the value with .val(), then you can make your own method for that:
$(document).ready(function(){
function updateWidth() {
// on change animate width as chars are added
// only grow it when the width needs to be larger than it is currently
var item = $(this);
var origWidth = item.data("initialWidth");
var curWidth = item.width();
if (!origWidth) {
origWidth = curWidth;
item.data("initialWidth", origWidth);
}
var newWidth = origWidth + (8 * item.val().length);
if (newWidth > curWidth) {
item.stop(true, true).animate({width: newWidth}, 500);
}
}
$('#code').userChange(updateWidth);
$.fn.valNotify = function(value) {
this.val(value);
this.each(function() {
updateWidth.call(this);
});
return this;
}
});
Then, you can change your values with this and it will automatically resize too:
$("#code").valNotify("foo");
If based on your previous question HTML markup :
<button class="I button">I</button>
<button class="O button">O</button>
<input id="code" type="text" disabled />
So if you want to animate the width of the textbox, you need to animate it when click the button:
$('.button').click(function(event) {
var text = $(this).text();
$('input:text').val(function(index, val) {
return val + text;
});
$('#code').animate({width: '+=16'});
});
Working Demo
If based on your above question HTML markup, you need to use keyup instead of change as well as include the jQuery library in the jsFiddle:
$(document).ready(function(){
$('#code').keyup(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
Updated Demo
You just need to check which key was pressed:
$(document).ready(function(){
$('#code').keyup(function(e){
//on change animate a width of +16px increase.
if(e.keyCode == 8) { // Backspace pressed
$(this).animate({width: '-=16'});
} else {
$(this).animate({width: '+=16'});
}
});
});
Updated Demo
You forgot to load jQuery, working fine here http://jsfiddle.net/BUSSX/13/ - also you need the click event. Or even better use the keyup event so that as soon as something is typed, the textbox increases in width - http://jsfiddle.net/BUSSX/15/
you have a bad implementation check http://jsfiddle.net/3dSZx/ and you need add jquery to fiddle
JS
$(document).ready(function(){
$('#push').click(function(){
//on change animate a width of +16px increase.
$('#code').animate({ width: '+=16'});
});
});
IrfanM, instead of incrementing by a fixed amount, you might consider incrementing by just the right amount to accommodate each character as it is typed.
Unless I've overcomplicated things (not completely unknown), this is moderately tricky.
In the following jQuery plugin :
text input fields are each given a hidden <span> with the same font-family and font-size as its respective input element.
the <span> elements act as "measuring sticks" by accepting a copy of their input field's entire text every time a character is typed.
the width of the <span> plus one generous character width is then used to determine the width of the input field.
Here's the code :
(function ($) {
var pluginName = 'expandable';
$.fn[pluginName] = function () {
return this.each(function (i, input) {
var $input = $(input);
if (!$input.filter("input[type='text']").length) return true;
// Common css directives affecting text width
// May not be 100% comprehensive
var css = {
fontFamily: $input.css('fontFamily'),
fontSize: $input.css('fontSize'),
fontStyle: $input.css('fontStyle'),
fontVariant: $input.css('fontVariant'),
fontWeight: $input.css('fontWeight'),
fontSizeAdjust: $input.css('fontSizeAdjust'),
fontStretch: $input.css('fontStretch'),
letterSpacing: $input.css('letterSpacing'),
textTransform: $input.css('textTransform'),
textWrap: 'none'
};
var $m = $("<span/>").text('M').insertAfter($input).css(css).text('M').hide();
var data = {
'm': $m,
'w': $m.width()
};
$input.data(pluginName, data).keyup(function (e) {
$this = $(this);
var data = $this.data(pluginName);
var w = data.m.html($this.val().replace(/\s/g, " ")).width();
$this.css({
'width': w + data.w
});
}).trigger('keyup');
});
};
})(jQuery);
$(document).ready(function () {
$('input').expandable();
});
DEMO
This works because a <span> element automatically expands to accommodate its text, whereas an <input type="text"> element does not. A great feature of this approach is that the keystrokes don't need to be tested - the plugin automatically responds to character deletions in the same way it responds to character strokes.
It works with proportional and monospaced fonts and even responds appropriately to cut and paste.
The only precaution necessary is to convert spaces to non-breaking spaces, $nbsp;, otherwise HTML renders multiple spaces as a single space in the <span> element.
Of course, it you really want exactly 16px growth for every keystroke, then stick with what you already have.

Jquery show and hide elements according to position

I am trying to make a carousel of sorts. I am kind of stuck with hiding and displaying the next and precious buttons once a div moves to the far left and right of its container.
I think i have everything correct regarding calculating the widths but for some reason when you click the buttons, elements stay hidden irrespective of the conditional comments which should dictate when they should be hidden or shown.
Here is a link to what i have thus far. Click the MoveLeft and MoveRight buttons. http://www.ehbeat.com/test/
<script type="text/javascript">
$(document).ready(function () {
//Check width of Gallery div
var galleryWidth = $("#Gallery").innerWidth();
//Check width of GalleryItem
var galleryItemWidth = $(".GalleryItem").innerWidth();
//Check distance from left
var position = $('.GalleryItem').position();
var galleryItemLeft = position.left;
$(".MoveRight").click(function () {
$(".GalleryItem").animate({
"left": "+=50px"
}, "slow");
$(".GalleryItem2").animate({
"left": "+=100px"
}, "slow");
});
$(".MoveLeft").click(function () {
$(".GalleryItem").animate({
"left": "-=50px"
}, "slow");
$(".GalleryItem2").animate({
"left": "-=100px"
}, "slow");
});
$(".Controls").live('click', function () {
if (galleryItemLeft >= "0") {
$('.MoveRight').hide();
}
else {
$('.MoveRight').show();
}
});
if (galleryItemWidth == galleryWidth - galleryItemWidth) {
$('.MoveLeft').hide();
}
});
</script>
It looks like you setup all of your variables inside the $(document).ready() call.
This means that while they're being set on load, they're not getting updated with each click.
Your galleryItemLeft, galleryItemWidth and galleryItemWidth variables need to be updated on each click, so I'd recommend re-assigning the values in each click (by moving the assignment into the live functions)
Edit Also, as your last if statement is excluded from any click function, it'll need to be relocated to inside the live click events as well.
-Chris
Chris is right, code should look like this:
$(".Controls").live('click', function() {
position = $('.GalleryItem').position();
galleryItemLeft = position.left;
if(galleryItemLeft > "0") {
$('.MoveRight').hide();}
else{
$('.MoveRight').show();
}
if(galleryItemWidth == galleryWidth - galleryItemWidth) {
$('.MoveLeft').hide();
}
});

Categories