I want to set #first and #second as $(this) to use element id only when function is calling.
is it possible?or any other way?
(function( $ ){
$.fn.showCircle = function(top,right) {
$timeout(function () {
$(this).css({
right:right,
top:top,
});
});
};
})( jQuery );
$('#first').showCircle(300,200);
$('#second').showCircle(800,200);
You can use jQuery.proxy() to set this at a function call
$timeout($.proxy(function () {
$(this).css({
right:right,
top:top,
});
}, this));
thanks to #panther comment inside $timeout this refer to window so as #panther said I changed the function :
(function ($) {
$.fn.showCircle = function (top, right) {
var self = this;
$timeout(function () {
$(self.selector).css({
right: right,
top: top,
});
});
};
})(jQuery);
Related
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>
When the blue button is clicked it affects both buttons
http://jsfiddle.net/umbriel/Lwvukzhy/1/
My setup looks like this
var
$window = $(window),
$body = $('body'),
$buttonRight = $('.button .right')
;
$buttonRight.on('click', function( ) {
buttonReveal( $( this ) );
});
function buttonReveal() {
$buttonLeft.css({'width':'25%'});
$buttonRight.css({'width':'75%'});
}
I want to to only affect one of buttons I clicked
Thank you
Use .siblings() to get siblings. Try this:
$buttonRight.on('click', function( ) {
buttonReveal($(this)); //$(this) refers to current clicked element (button)
});
$buttonLeft.on('click', function() {
buttonHide($(this)); //$(this) refers to current clicked element (button)
});
function buttonReveal(element) {
element.siblings($buttonLeft).css({'width':'25%'}); //to apply css to siblings use .siblings()
element.css({'width':'75%'});
}
function buttonHide(element) {
element.css({'width':'0%'});
element.siblings($buttonRight).css({'width':'100%'});
}
DEMO
You need to target the left/right buttons which is related to the clicked button. So you need to pass the clicked button to buttonReveal() and buttonHide().
So
(function (window, $) {
var
$window = $(window),
globalTimeout = null,
$body = $('body'),
$buttonRight = $('.button .right'),
$buttonLeft = $('.button .left');
$buttonRight.on('click', function () {
buttonReveal(this);
});
$buttonLeft.on('click', function () {
buttonHide(this);
});
function buttonReveal(button) {
var $btn = $(button).css({
'width': '75%'
});
$btn.prev('.left').css({
'width': '25%'
});
}
function buttonHide(button) {
var $btn = $(button).css({
'width': '0%'
});
$btn.next('.right').css({
'width': '100%'
});
}
}(window, $));
Demo: Fiddle
Here I tried to run some code after height animation
<button id="btn1">Animate height</button>
<div id="box"style="background:#98bf21;height:100px;width:100px;margin:6px;"></div>
$(document).ready(function () {
$("#btn1").click(function () {
$("#box").animate({height:"300px"});
});
var x = $('#box').height();
if(x == 300){alert('animation is finished');}
});
I can't place the code which I want to run after height animation into animate method callback cause the animating box script is placed in one document and code which I want to run in other.
use jquery .promise().done
$(document).ready(function () {
$("#btn1").click(function () {
$("#box").animate({
height: "300px"
}).promise().done(function () {
alert('animation is finished');
});;
})
});
or separately like this:
$(document).ready(function () {
$("#btn1").click(function () {
$("#box").animate({
height: "300px"
});
$("#box").promise().done(function () {
alert('animation is finished');
});
})
});
Fixed Fiddle
Event-driven JavaScript a la jQuery:
//file 1
$("#box").animate({height:"300px"},function() {
$(this).trigger('myBoxFinishedAnimatingHeight');
});
//file 2
$('#box').on('myBoxFinishedAnimatingHeight',function() {
//your code
});
You can simply use the complete property as a callback function:
.animate( properties [, duration ] [, easing ] [, complete ] )
From http://api.jquery.com/animate
Here's a demo
$("#adjest").animate({"height":"300px"},1000);
$("#adjest").promise().done(
function() {
alert("done");
}
);
i would use promise and done, if you can't run it inside animate().
see here
http://jsfiddle.net/5p8Ww/
You could name space your file and call the fucntion...
var NameSpace = Namespace || {};
NameSpace.yourFunction() {
//Do stuff...
}
Then in your html/other_file
.animate( properties , 1000, ease, NameSpace.yourFunction())
I am creating the function Bricks(). It works the first time it is called, but when I call it later with another event, I get an error saying that Bricks() hasn't be defined. What could I be doing wrong?
Function Created:
<script>
$(document).ready(function(){
function Bricks() {
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded( function(){
$container.masonry({
itemSelector:'.post-wrap'
});
});
}
Bricks();
});
</script>
Called Upon later:
<script>
$(document).ready(function() {
$(".comment-button").click(function() {
$(this).parents(".post-bottom").find(".commenting-area").toggle();
Bricks();
});
});
</script>
Because the function Bricks is defined in closure scope(the dom ready handler) so it will be available inside that dom ready handler only.
If you want to use it in a different scope, you need to define the function in a shared scope, in this case you can use the global scope(window scope), that is define the function outside the dom ready handler
function Bricks() {
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: '.post-wrap'
});
});
}
$(document).ready(function () {
Bricks();
});
Another solution as suggested by #AlienArrays is to move the contents of both document ready handlers to one so that both of them will share the same closure scope
$(document).ready(function () {
function Bricks() {
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: '.post-wrap'
});
});
}
Bricks();
$(".comment-button").click(function () {
$(this).parents(".post-bottom").find(".commenting-area").toggle();
Bricks();
});
});
To be able to reference your function globally, you must define it globally:
$(document).ready(function(){
window.Bricks = function () {
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded( function(){
$container.masonry({
itemSelector : '.post-wrap'
});
});
};
Bricks();
});
Note: there are better, cleaner ways to write the above code, but this serves as an answer to the question at hand.
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/