.directive('scrollWatch', function($rootScope) {
return function(scope, elem, attr) {
var start = 0;
var threshold = 150;
elem.bind('scroll', function(e) {
if(e.detail.scrollTop - start > threshold) {
$rootScope.slideHeader = true;
} else {
$rootScope.slideHeader = false;
}
console.log('e'+ e.detail.scrollTop);
if ($rootScope.slideHeaderPrevious >= e.detail.scrollTop - start) {
$rootScope.slideHeader = false;
}
console.log($rootScope.slideHeader);
$rootScope.slideHeaderPrevious = e.detail.scrollTop - start;
$rootScope.$apply();
});
};
})
This give me e.detail.scrollTop
But I want e.detail.scrollBottom. I cannot get about this.
help me
Simple! basic formula for scrollbottom is
$(document).height() - $(#element).scrollTop() - $(#element).height();
since i do not have your entire code i can not give exact solution. But with some trail you can get it. Just simply follow the formula.
that is
document height - current element position - current element window
height
and your code will be like this.
.directive('scrollWatch', function($rootScope) {
return function(scope, elem, attr) {
var start = 0;
var threshold = 150;
elem.bind('scroll', function(e) {
if(e.detail.scrollTop - start > threshold) {
$rootScope.slideHeader = true;
} else {
$rootScope.slideHeader = false;
}
console.log('e'+ e.detail.scrollTop);
if ($rootScope.slideHeaderPrevious >= e.detail.scrollTop - start) {
$rootScope.slideHeader = false;
}
console.log($rootScope.slideHeader);
$rootScope.slideHeaderPrevious = $(document).height()-e.detail.scrollTop - e.detail.height();
$rootScope.$apply();
});
};
})
Related
I have this code I'm using for sticky header some other things.
function stickyHeader(index) {
$('.worship-items .collapse').eq(index).on('hidden.bs.collapse', function() {
shouldReturn = true;
var header = $('.card-header').eq(index);
header.removeClass('fixed-top');
header.css('z-index', 0);
// The return here is not ending the function?
return false;
});
var shouldReturn = false;
$(window).scroll(function() {
if (shouldReturn == false) {
var header = $('.card-header').eq(index);
var scroll = $(window).scrollTop();
if (scroll >= $('.card').eq(index).offset().top) {
header.addClass('fixed-top');
header.css('z-index', 10);
} else {
header.removeClass('fixed-top');
header.css('z-index', 0);
}
} else {
// return here is not ending the function.
return false;
}
});
}
For some reason, the return is not ending the function. I've learned that return does not end the function if it's in a while, for, foreach, or loop but I'm not using that here.
Is there anything I'm doing wrong?
I decided to take off jQuery library and to do my own functions.
I started with Animation because I need it.
So, I store the interval ID and other datas on Element Object, in animate function I can see the property, but in another function, with same element, I can't see my property.
How I can make them global or something?
https://jsbin.com/yeqawuzoxu/edit?html,output
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var app = angular.module( "test", [] );
app.run(function () {
angular.element.prototype.animate = function (data,duration,transition,complete) {
if ( ! this.length ) return false;
if ( data.height === undefined ) return false;
if ( Math.floor(duration) !== duration || typeof duration !== "number" ) return false;
if ( duration <= 0 ) return false;
var act_height = this[0].offsetHeight;
var new_height = parseFloat(data.height.replace( /[^\d\.]*/g, ''));
var element = this;
element.Animation = [];
element.Animation.start = new Date;
console.log ( element );
element.Animation.interval = setInterval(function() {
var timePassed = new Date - element.Animation.start
var progress = timePassed / duration;
if (progress > 1) progress = 1;
var trans = ( Function.prototype.isPrototypeOf(complete) ) ? transition(progress) : progress;
element.css('height', (trans * (new_height-act_height)) + act_height + 'px');
if (progress == 1) {
console.log ( element );
if ( Function.prototype.isPrototypeOf(complete) ) complete();
clearInterval(element.Animation.interval);
element.Animation = null;
delete element.Animation;
}
}, 10 );
}
angular.element.prototype.stop = function () {
if ( ! this.length ) return false;
console.log ( this );
}
});
app.directive('cacat', function() {
return {
restrict: 'E',
link: function (scope, element, attrs) {
element.css('float', 'left');
element.css('height', '100px');
element.css('width', '100px');
element.css('background-color', 'black');
scope.anim = function ($event) {
if (! angular.element($event.target).hasClass('progress') ) {
angular.element($event.target).addClass('progress');
angular.element($event.target).animate({
height: '280px'
}, 2000, function(t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 }, function(){
angular.element($event.target).removeClass('progress');
});
} else {
angular.element($event.target).stop();
}
}
}
};
});
</script>
</head>
<body ng-app="test">
<cacat ng-click="anim($event)"></cacat>
<cacat ng-click="anim($event)"></cacat>
<cacat ng-click="anim($event)"></cacat>
<cacat ng-click="anim($event)"></cacat>
</body>
</html>
Press on one box, wait a while (to the middle maybe) and click again. After this wait to animation stop.
You will see in console the same element, but when you clicked in animation progress you will not see the property Animation.
I'm trying to use the jQuery appear plugin. I'm having trouble making it work. I tried to attach it to the (window).scroll event but it makes the page slow. If I don't use the scroll, it only fires once. I need it to work again whenever the element becomes visible. Can you give me some tips on how to make it work.
Here's my code:
jQuery('.home-section-1').appear(function(){
jQuery('.page-scroll-indicator .fa.fa-circle').removeClass('active-ind');
jQuery('.page-scroll-indicator .section-1').addClass('active-ind');
});
As ɴ-ᴀ-ᴛ-ʜ said in his comment, you need to be using .on to listen for the appear event.
jQuery('.home-section-1').on('appear', function(){
jQuery('.page-scroll-indicator .fa.fa-circle').removeClass('active-ind');
jQuery('.page-scroll-indicator .section-1').addClass('active-ind');
});
Here's a code snippit showing it working, you'll notice that your method (Method 1) doesn't fire, while the method above (Method 2) does:
/*
* jQuery appear plugin
*
* Copyright (c) 2012 Andrey Sidorov
* licensed under MIT license.
*
* https://github.com/morr/jquery.appear/
*
* Version: 0.3.4
*/
(function($) {
var selectors = [];
var check_binded = false;
var check_lock = false;
var defaults = {
interval: 250,
force_process: false
}
var $window = $(window);
var $prior_appeared;
function process() {
check_lock = false;
for (var index = 0, selectorsLength = selectors.length; index < selectorsLength; index++) {
var $appeared = $(selectors[index]).filter(function() {
return $(this).is(':appeared');
});
$appeared.trigger('appear', [$appeared]);
if ($prior_appeared) {
var $disappeared = $prior_appeared.not($appeared);
$disappeared.trigger('disappear', [$disappeared]);
}
$prior_appeared = $appeared;
}
}
// "appeared" custom filter
$.expr[':']['appeared'] = function(element) {
var $element = $(element);
if (!$element.is(':visible')) {
return false;
}
var window_left = $window.scrollLeft();
var window_top = $window.scrollTop();
var offset = $element.offset();
var left = offset.left;
var top = offset.top;
if (top + $element.height() >= window_top &&
top - ($element.data('appear-top-offset') || 0) <= window_top + $window.height() &&
left + $element.width() >= window_left &&
left - ($element.data('appear-left-offset') || 0) <= window_left + $window.width()) {
return true;
} else {
return false;
}
}
$.fn.extend({
// watching for element's appearance in browser viewport
appear: function(options) {
var opts = $.extend({}, defaults, options || {});
var selector = this.selector || this;
if (!check_binded) {
var on_check = function() {
if (check_lock) {
return;
}
check_lock = true;
setTimeout(process, opts.interval);
};
$(window).scroll(on_check).resize(on_check);
check_binded = true;
}
if (opts.force_process) {
setTimeout(process, opts.interval);
}
selectors.push(selector);
return $(selector);
}
});
$.extend({
// force elements's appearance check
force_appear: function() {
if (check_binded) {
process();
return true;
};
return false;
}
});
})(jQuery);
// Your method
jQuery('.home-section-1').appear(function(){
alert('Method 1');
});
// Using .on
jQuery('.home-section-1').on('appear', function(){
alert('Method 2');
});
.home-section-1 {
margin-top: 2000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="home-section-1">Hello World</div>
I am having trouble getting my scroll to top button to work. I know its a problem with another animation but I am not able to see what is causing the issue. The problem is when the other animation "starts when scroll hits 500" the scroll to top button will no longer fade out and disappear.
$.chain = function() {
var promise = $.Deferred().resolve().promise();
jQuery.each( arguments, function() {
promise = promise.pipe( this );
});
return promise;
};
function scrollTop(){
if(typeof pageYOffset!= 'undefined'){
return pageYOffset;
}
else{
var b = document.body; //IE 'quirks'
var d = document.documentElement; //IE with doctype
d = (d.clientHeight)? d : b;
return d.scrollTop;
}
}
$(window).on("scroll", function(){
if(scrollTop() >= 600){
$(window).off("scroll");
var animations = $.chain(function() {
return $('#animate1 img').fadeIn('slow').delay(400);
}, function() {
return $('#animate2 img').fadeIn('slow').delay(400);
}, function() {
return $('#animate3 img').fadeIn('slow');
});
};
});
jQuery(document).ready(function() {
var offset = 300;
var duration = 500;
jQuery(window).scroll(function() {
if (jQuery(this).scrollTop() > offset) {
jQuery('.scroll-top').fadeIn(duration);
} else {
jQuery('.scroll-top').fadeOut(duration);
}
});
});
Thank you for any help.
$(window).off("scroll"); is indeed removing scroll event which you're listening to fadeIn and fadeOut.
Although i havent tried it but an alternative would be to use event namespacing?
something like below:
$.chain = function() {
var promise = $.Deferred().resolve().promise();
jQuery.each( arguments, function() {
promise = promise.pipe( this );
});
return promise;
};
function scrollTop(){
if(typeof pageYOffset!= 'undefined'){
return pageYOffset;
}
else{
var b = document.body; //IE 'quirks'
var d = document.documentElement; //IE with doctype
d = (d.clientHeight)? d : b;
return d.scrollTop;
}
}
$(window).on("scroll.foranimations", function(){ // event name
if(scrollTop() >= 600){
$(window).off("scroll.foranimations"); // event name
var animations = $.chain(function() {
return $('#animate1 img').fadeIn('slow').delay(400);
}, function() {
return $('#animate2 img').fadeIn('slow').delay(400);
}, function() {
return $('#animate3 img').fadeIn('slow');
});
};
});
jQuery(document).ready(function() {
var offset = 300;
var duration = 500;
jQuery(window).on("scroll.forfading", function() { // event name
if (jQuery(this).scrollTop() > offset) {
jQuery('.scroll-top').fadeIn(duration);
} else {
jQuery('.scroll-top').fadeOut(duration);
}
});
});
notice different event names scroll.foranimations and scroll.forfading
I am trying to implement column resizing using jQuery like below(Please see http://jsbin.com/uduNUbo/1/edit)
Here is my JS code
function resizeEvents(selector) {
function XY(e, ele) {
var parentOffset = ele.parent().offset();
return e.pageX - parentOffset.left;
}
var checkPos;
$(selector).on('mousedown', function () {
$(this).attr('init', true);
return false;
});
$(selector).on('mouseup', function () {
$(this).attr('init', false);
});
$(selector).closest('div').on('mousemove', function (e) {
var inits = $(this).find('.resize').filter(function(){
return $(this).attr('init') == true;
});
if (inits.length > 0) {
var pos = XY(e, inits.first());
if (!checkPos) {
checkPos = pos;
return false;
} else {
var moved = checkPos - pos, a = moved > 0 ? 1 : -1 ;
th.prevAll().each(function () {
if (!$(this).hasClass('.resize')) {
$(this).width($(this).width() + a);
}
});
th.nextAll().each(function () {
if (!$(this).hasClass('.resize')) {
$(this).width($(this).width() - a);
}
});
}
}
});
}
resizeEvents('.resize');
But this is not working, My Question is Is mousemove is written properly, to define properly on correct element or not.
I fixed the code for you:
function resizeEvents(selector) {
var selected;
$(selector).on('mousedown', function () {
selected = $(this);
return false;
});
$(document).mouseup(function () {
selected = null;
}).mousemove(function(e) {
var target = $(e.target);
var table = target.parents('.table');
if (table.length && selected) {
var x = e.pageX - table.offset().left;
var splitter_x = selected.offset().left;
var prev = selected.prev();
var next = selected.next();
prev.width(prev.width() + (x - splitter_x));
next.width(next.width() - (x - splitter_x));
}
});
}
http://jsbin.com/uduNUbo/5/edit