Reputation: 653
I am learning to write a mini jQuery Plugin Tools.
My plugin is helping user to check if user mousewheel whether scroll up or scroll down to trigger the callback function.
I have a four divs, when my mouse pointer hover it and scroll up with mouse wheel, the plugin callback will change this div 's background color.
Unfortunately, my callback 's $this is not working to point this element. I need some help.
Style
body {background: #2A2B30;}
.wrapper {margin-top: 100px;}
.wrapper div.content {border-radius: 7px; border: 1px solid #000; min-height: 300px; margin-top: 30px; background: #ededed; padding: 30px; font-size: 20px;}
Html
<div class="container">
<div class="wrapper clearfix">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
<div class="blk content"> </div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
<div class=" content"> </div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
<div class="blk content"> </div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
<div class=" content"> </div>
</div>
</div>
</div>
Call Plugin
$(function() {
$('.blk').scroll({
lastAnimation : 0,
quietPeriod : 500,
animationTime : 800,
ScrollUp : function() {
$(this).css('background', 'red');
},
ScrollDown : function() {
alert('Scroll Down');
}
});
});
My Plugin
(function($) {
$.fn.scroll = function( options ) {
var settings = $.extend({
// selector : $(this),
lastAnimation : null,
quietPeriod : null,
animationTime : null,
ScrollUp : null,
ScrollDown : null
}, options);
return this.each( function() {
var lastAnimation = settings.lastAnimation;
var quietPeriod = settings.quietPeriod;
var animationTime = settings.animationTime;
function init(event, delta) {
deltaOfInterest = delta;
var timeNow = new Date().getTime();
if( timeNow - lastAnimation < quietPeriod + animationTime ) {
event.preventDefault();
return;
}
if ( deltaOfInterest < 0 ) {
// Call Back
if ( $.isFunction( settings.ScrollUp ) ) {
settings.ScrollUp.call(this);
}
} else {
// Call Back
if ( $.isFunction( settings.ScrollDown ) ) {
settings.ScrollDown.call(this);
}
}
lastAnimation = timeNow;
}
$(this).bind('mousewheel DOMMouseScroll', function(event) {
event.preventDefault();
var delta = event.originalEvent.wheelDelta || -event.originalEvent.detail;
init(event, delta);
});
});
}
}(jQuery));
Upvotes: 1
Views: 135
Reputation: 3679
See if this helps.
I use jQuery .hover() to store which div the mouse is over.
Then just use that variable (var hoverDiv) instead of "this"
<style>
body {background: #2A2B30;}
.wrapper {margin-top: 100px;}
.wrapper div.content {border-radius: 7px; border: 1px solid #000; min-height: 120px; margin-top: 30px; background: #ededed; padding: 30px; font-size: 20px;}
</style>
<div class="container">
<div class="wrapper clearfix">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
<div class="blk content"> </div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
<div class=" content"> </div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
<div class="blk content"> </div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
<div class=" content"> </div>
</div>
</div>
</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
/*
@see http://stackoverflow.com/questions/31340479/jquery-plugin-callback-this-cant-return-element
*/
(function($) {
$.fn.scroll = function( options ) {
var settings = $.extend({
// selector : $(this),
lastAnimation : null,
quietPeriod : null,
animationTime : null,
ScrollUp : null,
ScrollDown : null
}, options);
return this.each(function() {
var lastAnimation = settings.lastAnimation;
var quietPeriod = settings.quietPeriod;
var animationTime = settings.animationTime;
function init(event, delta) {
deltaOfInterest = delta;
var timeNow = new Date().getTime();
if( timeNow - lastAnimation < quietPeriod + animationTime ) {
event.preventDefault();
return;
}
if ( deltaOfInterest < 0 ) {
// Call Back
if ( $.isFunction( settings.ScrollUp ) ) {
settings.ScrollUp.call(this);
}
} else {
// Call Back
if ( $.isFunction( settings.ScrollDown ) ) {
settings.ScrollDown.call(this);
}
}
lastAnimation = timeNow;
}
$(this).bind('mousewheel DOMMouseScroll', function(event) {
event.preventDefault();
var delta = event.originalEvent.wheelDelta || -event.originalEvent.detail;
init(event, delta);
});
});
}
}(jQuery));
$(function() {
var hoverDiv = null;
$('.blk').hover(function(e) {
hoverDiv = $(this);
},
function(e) {
hoverDiv = null;
}
);
$('.blk').scroll({
lastAnimation : 0,
quietPeriod : 500,
animationTime : 800,
ScrollUp : function() {
if(hoverDiv) {
hoverDiv.css('background', 'red');
}
},
ScrollDown : function() {
if(hoverDiv) {
hoverDiv.css('background', 'blue');
}
}
});
});
</script>
Upvotes: 0
Reputation: 10683
This is because settings.ScrollUp.call(this);
here this
is not refer to div its inside function so this
is becomes something else inside of the init
inner function try this:-
return this.each( function() {
var $this=this; // create variable here
.....
.....
settings.ScrollUp.call($this); //use it here like this in init function
Upvotes: 3