animate jQuery attribute can't use variables? - javascript

After declaring height() variables for multiple loaded elements which have different variables for each, the animate() function doesn't seem to be loading the variable excHeight.
What would be the best way to use the value of excHeight for the animate() as below?
$(".exPand a").click(function (event) {
event.preventDefault();
var post_id = $(this).attr("rel");
var postHeight = $(this).closest('.boxy')
.find('.articleImageThumb')
.height();
var excHeight = $(this).closest('boxy')
.find('.articleImageThumb')
.find('.initialPostLoad')
.height();
$.ajaxSetup({cache:false});
$(this).closest('.boxy')
.animate({height: postHeight+excHeight}, 1000);
$(this).closest('.boxy')
.find('.articleImageThumb')
.animate({top: 0}, 1000);
$(this).closest('.boxy').find('.articleTitle')
.animate({bottom: excHeight}, 1000);
$(this).closest('.boxy').find('.postmetadata')
.animate({bottom: excHeight}, 1000);
});

Seems like it is not working because you forgot "dot" in boxy class name: var excHeight = $(this).closest('boxy') , must be like this: var excHeight = $(this).closest('.boxy')

Related

Can I use nested jquery.proxy

Can I use nested jquery.proxy?
var obj = {
init: function(element){
element.on('click.mynamespace',$.proxy(function (event) {
$(event.currentTarget).animate({
scrollLeft: scrollPos
}, width, $.proxy(this.myFunction,this));
},this))
},
myFunction: function(){
/*some code*/
}
}
This is what I need for my project. I have used the nested $.proxy to make the code work. Because I need this context in myFunction which is a callback function for jquery animate api.
Can I use in this way?
It should work, however I'd suggest that storing a reference to the object in the outer scope would be a more elegant solution. Note the definition and use of _obj in this example:
var scrollPos = 10;
var width = 20;
var obj = {
init: function($element) {
var _obj = this;
$element.on('click.mynamespace', function(e) {
$(this).animate({
scrollLeft: scrollPos
}, width, _obj.myFunction.call(this));
});
},
myFunction: function() {
// this function now executes within the context of the
// element which has been animated in the click handler
console.log(this.id);
}
}
var $foo = $('#foo');
obj.init($foo);
$foo.trigger('click.mynamespace');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo"></div>

Input field to change img attributes for multiple images

Issue: Cannot change attributes src and alt independently for multiple images. Any change made, affects all the other images that have previously had a change made.
Question: How can I optimize following JS/Jquery to allow attribute changes for multiple images?
See full code here: JS Fiddle
$(function () {
$("#editImage").hide();
$("img").click(function () {
var imgChange = this;
$('#imageAlt').val($(imgChange).attr('alt'));
$('#imageSrc').val($(imgChange).attr('src'));
$("#editImage").css({
top: $(this).offset().top - $('#editImage').height() - 5,
left: $(this).offset().left
}).show();
$("#imageEditDone").click(function () {
var imgSrc = $("#imageSrc").val();
var imgAlt = $("#imageAlt").val();
$(imgChange).attr('src', imgSrc).attr('alt', imgAlt);
});
});
});
$("#imageEditDone").click(function () {
$("#editImage").hide();
});
You're binding a click handler within another click handler repeatedly which is a no-no. Also, you need to change the scope of your imgChange variable. Try:
var imgChange;
$(function () {
$("#editImage").hide();
$("img").click(function () {
imgChange = this;
$('#imageAlt').val($(imgChange).attr('alt'));
$('#imageSrc').val($(imgChange).attr('src'));
$("#editImage").css({
top: $(this).offset().top - $('#editImage').height() - 5,
left: $(this).offset().left
}).show();
$("#imageSrc").text(imgChange.attr('alt', this));
});
});
$("#imageEditDone").click(function () {
$("#editImage").hide();
var imgSrc = $("#imageSrc").val();
var imgAlt = $("#imageAlt").val();
$(imgChange).attr('src', imgSrc).attr('alt', imgAlt);
});
jsFiddle example
I'm just not sure what you're trying to do with the line $("#imageSrc").text(imgChange.attr('alt', this));, although it doesn't affect the answer.

jquery add class to multiple elements with a delay

i have 3 div elements with class name gridbox
i want to add a class into all 3 elements with delay.
for example:
new class should be added to all 3 div elements with a delay between each of them.
i triel following code which is not working.
$('.gridbox').addClass('animation').delay(1500);
What is wrong here?
You could try something like this:
var divs = $( '.gridbox' );
var index = 0;
var delay = setInterval( function(){
if ( index <= divs.length ){
$( divs[ index ] ).addClass( 'animation' );
index += 1;
}else{
clearInterval( delay );
}
}, 1500 );
What I'm doing here is this:
Extract all of the elements and store them in the divs variable.
Save an index of the element you are currently working with.
Initiate a setTimeout function with a delay of 1.5 seconds.
If we are not at the end of the list of elements, add the class to the relevant element after converting it to a jQuery element.
Increment our index variable.
Stop the setTimeout once we have iterated over all of the elements.
$('.gridbox').each(function(i) {
(function(self, j) {
setTimeout(function() {
$(self).addClass('animation');
},(j*1500)+1500);
})(this, i);
});
FIDDLE
$('.gridbox').each(function(index) {
var that = this;
setTimeout(function() {
$(that).addClass('animation');
}, 1500 * index);
});
if you want to apply a delay on a jquery function such as addClass you need to use a javascript setTimeout because as described here .delay() is limited and should be used for jQuery effects
You can try combination of .each() and setTimeout
$('.gridbox').each(function (index) {
var $this = $(this);
setTimeout(function () {
$this.addClass('animation');
}, 1500 * index );
});
Fiddle DEMO
a nicer solution :)
var st = setInterval(function(){
var gb = $('.gridbox:not(.animation):eq(0)');
gb.length > 0 ? gb.addClass('animation') : clearInterval(st);
},1500)
http://jsfiddle.net/jR984/
You can do this without jQuery
function addClass () {
var div = document.getElementsByClassName("aaa");
div[0].className = "bbb";
setTimeout(addClass, 1000);
}
window.onload = function () {
addClass();
}
http://jsfiddle.net/khGCv/
Although setTimeout/Interval kinda "works", jquery provides a much cleaner way to do custom animations: queue, for example:
$(".gridbox").each(function() {
var box = this;
$("body").queue(function(next) {
$(box).addClass("animation");
next();
}).delay(1000)
});

setInterval() inside plugin function not being called

I have a jQuery slideshow plugin that I am making though it has a setInterval() inside it which is not being called though if I move the contents of the setInterval() outside of the it then it works though it only runs once.
var gap = 3;
var duration = 0.5;
(function ($) {
$.fn.slideshow = function () {
return this.each(function () {
g = gap * 1000;
d = duration * 1000;
$(this).children().css({
'position': 'absolute',
'display': 'none'
});
$(this).children().eq(0).css({
'display': 'block'
});
setInterval(function () {
slide();
}, g);
function slide() {
$(this)
.children()
.eq(0)
.fadeOut(d)
.next()
.fadeIn()
.end()
.appendTo($(this).children().eq(0).parent());
}
});
};
})(jQuery);
$('.slideshow').slideshow();
HTML:
<div class='slideshow'>
<a>1</a>
<a>2</a>
<a>3</a>
<a>4</a>
</div>
Here is a fiddle with my plugin:
http://jsfiddle.net/Hive7/GrtLC/
The problem is this inside the slider function does not point to the object you think it points to.
setInterval($.proxy(function () {
slide.call(this);
}, this), g);
Demo: Fiddle
or better
setInterval($.proxy(slide, this), g);
Demo: Fiddle
Your problem is that this is always locally defined; by the time you get into the setInterval(), you've lost your original this (it's reset to the window object).
There are a few ways to get around this; the simplest is probably to copy this into a local variable.
http://jsfiddle.net/mblase75/GrtLC/5/
var gap = 3;
var duration = 0.5;
(function ($) {
$.fn.slideshow = function () {
return this.each(function () {
g = gap * 1000;
d = duration * 1000;
$this = $(this); // caches the jQuery object as a further optimization
$this.children().css({
'position': 'absolute',
'display': 'none'
});
$this.children().eq(0).css({
'display': 'block'
});
setInterval(function () {
slide($this); // pass $this into the function
}, g);
function slide($obj) {
$obj.children()
.eq(0)
.fadeOut(d)
.next()
.fadeIn()
.end()
.appendTo($obj.children().eq(0).parent());
}
});
};
})(jQuery);
$('.slideshow').slideshow();
Your code cannot work, because your callback is not bound to the this; try instead
var that = this;
setInterval(function () {
slide();
}, g);
function slide() {
$(that) ....
this inside slide function is not the slideshow. I make it work caching the object inside the each loop: http://jsfiddle.net/x7Jk8/

Make lingering hover repeat action in jQuery

$('#test').hover(
function () {
$(this).append('Blah');
}
);
How can I make the jQuery repeatedly append Blah in #test based on how long you are hovering over #test?
For instance, how can I append Blah once every second you are hovering over #test?
You could use setInterval like this :
var myInterval = false;
$('#test').hover(
function(){
$that = $(this);
// need to save $(this) as 'this' will be different within setInterval
myInterval = setInterval(function(){
$that.append('Blah');
}, 100); // repeat every 100 ms
},function() {
clearInterval(myInterval); // clear the interval on hoverOut
}
);
Working example here
(function() {
var intv;
$('#test').hover(
function () {
var $this = $(this);
intv = setInterval(function() {
$this.append('Blah');
}, 1000);
},
function() {
clearInterval(intv);
}
);
}());
I've enclosed all the code inside a anonymous scoped function so to not pollute global scope, and I cached a reference to $(this) to avoid a new evaluation every second, inside the timeout
You can use setInterval to do so:
var appending; //var to store the interval
$('#test').hover(function(){ //on mouseenter
var $this = $(this); //store the context, i.e. the element triggering the hover
appending = setInterval(function(){ //the following function gets executed every second until the interval is cleared
$this.append('<p>Blah</p>'); //append content to context
},1000); //1000 meaning the repetition time in ms
},function(){ //on mouseleave
clearInterval(appending); //clear the interval on mouseleave
});
use setInterval()
$('#test').hover(
function () {
setInterval(function() {
$(this).append('Blah');
},1000)
}
);

Categories