How do I call this function that's within a jquery plugin? - javascript

I'm using a jquery plugin on my page, vTicker, "for easy and simple vertical news automatic scrolling". I'm using it in combination with an rss jquery plugin. It's working fine, but I need to create a button that will do a manual scroll. Can anyone tell me how to do this? I'm guessing I need to call the moveUp function from the vTicker file, but because of the way the function is created, as well as how the vticker itself is created, I'm not really sure how to do it.
I create my vTicker like this:
$('#ticker1').rssfeed(uRL).ajaxStop(function() {
$('#ticker1 div.rssBody').vTicker();
})
And here is the vTicker code:
/*
* Tadas Juozapaitis ( kasp3rito#gmail.com )
*/
(function($){
$.fn.vTicker = function(options) {
var defaults = {
speed: 700,
pause: 15000,
showItems: 3,
animation: '',
mousePause: true,
isPaused: false
};
var options = $.extend(defaults, options);
moveUp = function(obj2, height){
if(options.isPaused)
return;
var obj = obj2.children('ul');
var iframe = $('#iFrame2');
first = obj.children('li:first').clone(true);
second = obj.children('li:odd:first').clone(true);
iframe.attr('src', (second.children('h4').children('a').attr("href")));
obj.animate({top: '-=' + height + 'px'}, options.speed, function() {
$(this).children('li:first').remove();
$(this).css('top', '0px');
});
if(options.animation == 'fade')
{
obj.children('li:first').fadeOut(options.speed);
obj.children('li:last').hide().fadeIn(options.speed);
}
first.appendTo(obj);
};
return this.each(function() {
var obj = $(this);
var maxHeight = 0;
obj.css({overflow: 'hidden', position: 'relative'})
.children('ul').css({position: 'absolute', margin: 0, padding: 0})
.children('li').css({margin: 0, padding: 0});
obj.children('ul').children('li').each(function(){
if($(this).height() > maxHeight)
{
maxHeight = $(this).height();
}
});
obj.children('ul').children('li').each(function(){
$(this).height(maxHeight);
});
obj.height(maxHeight * options.showItems);
var interval = setInterval(function(){ moveUp(obj, maxHeight); }, options.pause);
if(options.mousePause)
{
obj.bind("mouseenter",function(){
options.isPaused = true;
}).bind("mouseleave",function(){
options.isPaused = false;
});
}
});
};
})(jQuery);
Thanks for reading.

The short answer is, you can't. The moveUp function is totally isolated within the scope of the plugin, and you cannot call it directly.
To modify the plugin so that you can manually scroll, add this just before the line return this.each(function() {:
$.fn.extend({
vTickerMoveUp: function() {
var obj = $(this);
var maxHeight = 0;
obj.children('ul').children('li').each(function(){
if($(this).height() > maxHeight) maxHeight = $(this).height();
});
moveUp(obj, maxHeight);
}
});
Then, to scroll, do this:
var ticker = $('#ticker1 div.rssBody').vTicker();
ticker.vTickerMoveUp();

Since the moveup declaration is missing a var that means moveup() would be statically defined as a property of window (ie, global) once vTicker has been called. And thus I would think you could call moveup() from anywhere after that.

Related

Unable to access variable and apply certain CSS using object literal module pattern

I'm unable to access my DOM selectors even though I cached "this" before the window event.
If I were to change it to just $('.banner') it works.
Before in my code, I had scrolltop on the window event set the variable scrolled which I was able to use in my scrollEvent() method using module.scrolled.
Also, the opacity rule in the CSS is not working.
The top and relative position is though.
var parallax = {
init: function() {
this.cacheDom();
this.scrollEvent();
},
cacheDom: function() {
var $window = $(window),
banner = $('.banner'),
callout = $('.callout'),
bannerHeight = Math.round(banner.outerHeight()),
hideElem = false,
hasScrolled = false,
scrolled;
},
scrollEvent: function() {
var module = this;
$(window).on('scroll', function() {
var scrollTop = $(this).scrollTop();
module.banner.css("background-position", '50%' + (scrollTop / 1.75) + "px");
module.callout.css({'position': 'relative', 'top' : scrollTop * 0.75, 'opacity' : 1 - (scrollTop / module.bannerHeight * 2)});
});
}
};
parallax.init();
The cacheDom() function is setting local variables, not object properties. Change it to:
cacheDom: function() {
this.$window = $(window);
this.banner = $('.banner');
this.callout = $('.callout'),
this.bannerHeight = Math.round(this.banner.outerHeight());
this.hideElem = false;
this.hasScrolled = false;
this.scrolled = null;
},

$.each animation running separately

I'm trying to run each animation function one after the other instead of all at once.
This is what I've got so far:
$(document).ready(function(){
var bars = $('.bar');
bars.each(function(){
var widthpercent = $(this).attr("data-percent");
$(this).fadeIn();
$(this).animate({width:widthpercent},500);
});
});
I've tried using .delay() and setTimeout() in various combinations to no avail.
Could anyone point me in the right direction? Thank you!
It sounds to me like you're looking for animate's complete function. You can write a recursive function to keep calling the function in the complete function until all the items have been animated. To simplify: every time one element is animated, a callback is fired that animates the next element. That is the purpose of the complete parameter, so I'm certain that is what you're looking for.
Here's an example you can adapt to your specific needs.
Live demo here (click).
var $divs = $('div');
function animate(element) {
$(element).animate({height: '30px'}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
}
var current = 0;
animate($divs[current]);
Further, this same logic can be applied to your fadeIn. Just wrap fadeIn's callback around that logic, like this:
Live demo here (click).
var $divs = $('div');
function animate(element) {
$(element).fadeIn(function() { //now the animation is a callback to the fadeIn
$(element).animate({height: '70px'}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
});
}
var current = 0;
animate($divs[current]);
And here's your code: live demo here (click).
$(document).ready(function(){
var $divs = $('.bar');
function animate(element) {
$(element).fadeIn(function() { //you could unwrap this depending on what you're looking for
var widthpercent = $(element).attr("data-percent");
$(element).animate({
width:widthpercent,
duration: '500ms'
}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
}); //end fadeIn callback
}
var current = 0;
animate($divs[current]);
});
Try this:
var animate = function (el) {
return function () {
var widthpercent = el.data('percent');
el.fadeIn();
el.animate({
width: widthpercent
}, 500);
}
}
var bars = $('.bar');
bars.each(function (index) {
var $this = $(this);
setTimeout(animate($this), index * 500);
});
Fiddle
$(document).ready(function(){
var bars = $('.bar');
bars.each(function(i){
var widthpercent = $(this).attr("data-percent");
$(this).delay(i*800).animate({width:widthpercent,opacity:1,},500);
});
});
This will animate after delaying 800 * i milliseconds.
See this JSFiddle example.

IE9 Defaulting to IE7, javascript bug

I have this javascript that seems to be forcing IE9 into computability mode and forcing it to IE7. There are other areas of the website working properly that do not have this javascript code working on them, which leads me to believe something in this script is not compatible with IE9/IE7.
Basically, the code creates a pop up box when your mouse hovers over it. However if the pop up box displays over an image, the image shows through the pop up box as if it has precedence. I have tried changing the z-index on that div but no luck.
Any suggestions?
jQuery('.bubbleInfo').each(function () {
if(jQuery.trim(jQuery(this).find('#dpop').html()) != ''){ // start
var totalHeight = jQuery(this).height();
var distance = 15;
var time = 250;
var hideDelay = 150;
var hideDelayTimer = null;
var beingShown = false;
var shown = false;
var trigger = jQuery('.trigger', this);
var info = jQuery('.popup', this).css('opacity', 0);
jQuery([trigger.get(0), info.get(0)]).mouseover(function () {
if (hideDelayTimer) clearTimeout(hideDelayTimer);
if (beingShown || shown) {
// don't trigger the animation again
return;
} else {
// reset position of info box
beingShown = true;
info.css({
top: (totalHeight+38),
left: -77,
display: 'block'd
}).animate({
top: '-=' + distance + 'px',
opacity: 1
}, time, 'swing', function() {
beingShown = false;
shown = true;
});
}
return false;
}).mouseout(function () {
if (hideDelayTimer) clearTimeout(hideDelayTimer);
hideDelayTimer = setTimeout(function () {
hideDelayTimer = null;
info.animate({
top: '-=' + distance + 'px',
opacity: 0
}, time, 'swing', function () {
shown = false;
info.css('display', 'none');
});
}, hideDelay);
return false;
});
} // end
IE < 10 have issue in the jquery library version although IE10 supports all the version's of jquery.

JavaScript is being triggered before its time, *only on Chrome & IE

I have a gallery of three Grids with images. The grid sizes changes depending on the screen size, and I have achieved that using Media-Query - ie, on desktop the grid's width will be 33% to make three columns view next to each other, and on tablet it will be 50% to make two columns view, and on phone it will be a 100% for each grid making one column view.
The reason I did this is to create a tiled gallery with images of different heights - and if I did it the normal way it will generate White-empty-spaces when floating.
So to fix this problem, and with the help of few members on this website, we have created a JavaScrip function that will MOVE all of the images that are inside Grid3 equally to Grid1 & Grid2 when screen size is tablet, so we get rid of the third grid making a view of fine two columns. Everything is working great!
Now, the problem is - on Chrome & IE - The function is being fired before its time for some reason that I need your help to help me find it! Please try it your self here: [http://90.195.175.51:93/portfolio.html][2]
Slowly on Chrome or IE - (try it on Firefox as well) - try to re-size the window from large to small, you will notice that BEFORE the top header changes to be a responsive Header (which indicate that you are on a small screen) the images have been sent to Grid1 and Grid 2! but a few px before the time. As on the function it says to fire it on <770.
Hope my question is clear enough for you to help me solve this issue which is stopping me from launching my website. Thanks.
Here is the JavaScrip:
//Gallery Grid System//
var testimonial = $(".testimonial, .galleryItem", "#grid3");
(function () {
$(document).ready(GalleryGrid);
$(window).resize(GalleryGrid);
})(jQuery);
function GalleryGrid() {
var grid3 = $('#grid3');
var width = $(window).width();
if (width < 1030 && width > 770) {
var grid1 = $('#grid1');
var grid2 = $('#grid2');
for (var i = 0; i < testimonial.length; i++) {
if (i < testimonial.length / 2) {
grid1.append(testimonial[i]);
} else {
grid2.append(testimonial[i]);
}
}
} else {
grid3.append(testimonial);
}
}
Note: The following is the whole page with all the functions:
$(document).ready(function () {
//Prevent clicking on .active links
$('.active').click(function (a) {
a.preventDefault();
});
//Allow :active on touch screens
document.addEventListener("touchstart", function () {}, true);
//Hide toolbar by default
window.addEventListener('load', function () {
setTimeout(scrollTo, 0, 0, 0);
}, false);
//Scroll-up button
$(window).scroll(function () {
if ($(this).scrollTop() > 100) {
$('.scrollup').fadeIn();
} else {
$('.scrollup').fadeOut();
}
});
$('.scrollup').click(function () {
$("html, body").animate({
scrollTop: 0
}, 600);
return false;
});
//StickyBox
$(function () {
$.fn.scrollBottom = function () {
return $(document).height() - this.scrollTop() - this.height();
};
var $StickyBox = $('.detailsBox');
var $window = $(window);
$window.bind("scroll resize", function () {
var gap = $window.height() - $StickyBox.height() - 10;
var footer = 288 - $window.scrollBottom();
var scrollTop = $window.scrollTop();
$StickyBox.css({
top: 'auto',
bottom: 'auto'
});
if ($window.width() <= 770) {
return;
$StickyBox.css({
top: '0',
bottom: 'auto'
});
}
if (scrollTop < 50) {
$StickyBox.css({
bottom: "auto"
});
} else if (footer > gap - 100) {
$StickyBox.css({
top: "auto",
bottom: footer + "px"
});
} else {
$StickyBox.css({
top: 80,
bottom: "auto"
});
}
});
});
//Change items location depending on the width of the screen//
$(function () { //Load Ready
function myFunction() {
var insert = $(window).width() <= 770 ? 'insertBefore' : 'insertAfter';
$('#home-sectionB img')[insert]($('#home-sectionB div'));
$('#home-sectionD img')[insert]($('#home-sectionD div'));
}
myFunction(); //For When Load
$(window).resize(myFunction); //For When Resize
});
//Contact Form//
$(".input").addClass('notSelected');
$(".input").focus(function () {
$(this).addClass('selected');
});
$(".input").focusout(function () {
$(this).removeClass('selected');
});
$(document).ready(function () {
GalleryGrid();
$(window).resize(GalleryGrid);
});
//Gallery Grid System//
var testimonial = $(".testimonial, .galleryItem", "#grid3");
(function () {
$(document).ready(GalleryGrid);
$(window).resize(GalleryGrid);
})(jQuery);
function GalleryGrid() {
var grid3 = $('#grid3');
var width = $(window).width();
if (width < 1030 && width > 770) {
var grid1 = $('#grid1');
var grid2 = $('#grid2');
for (var i = 0; i < testimonial.length; i++) {
if (i < testimonial.length / 2) {
grid1.append(testimonial[i]);
} else {
grid2.append(testimonial[i]);
}
}
} else {
grid3.append(testimonial);
}
}
//Testimonials Animation//
$(".testimonial").hover(function () {
$(".testimonial").addClass('testimonialNotActive');
$(this).removeClass('testimonialNotActive').addClass('testimonialActive');
},
function () {
$(".testimonial").removeClass('testimonialNotActive');
$(this).removeClass('testimonialActive');
});
//Portfolio Gallery Filter//
(function () {
var $portfolioGallerySection = $('#portfolio-sectionB'),
$filterbuttons = $('#portfolio-sectionA a');
$filterbuttons.on('click', function () {
var filter = $(this).data('filter');
$filterbuttons.removeClass('portfolio-sectionAClicked');
$(this).addClass('portfolio-sectionAClicked');
$portfolioGallerySection.attr('class', filter);
$('.galleryItem').removeClass('selectedFilter');
$('.galleryItem.' + filter).addClass('selectedFilter');
});
}());
});
Your problem is that CSS media queries and jQuery's $(window).width() do not always align.
function getCSSWidth() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return e[ a+'Width' ];
}
Use this instead of $(window).width()
modified from http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
I think this could solve your problem (but I'm not quite sure)
//Put that before the document ready event
(function($,sr){
// debouncing function from John Hann
// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
var debounce = function (func, threshold, execAsap) {
var timeout;
return function debounced () {
var obj = this, args = arguments;
function delayed () {
if (!execAsap)
func.apply(obj, args);
timeout = null;
};
if (timeout)
clearTimeout(timeout);
else if (execAsap)
func.apply(obj, args);
timeout = setTimeout(delayed, threshold || 100);
};
}
// smartresize
jQuery.fn[sr] = function(fn){ return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };
})(jQuery,'smartresize');
// Here you call GalleryGrid (replace $(window).resize(GalleryGrid) with that):
$(window).smartresize(GalleryGrid);
http://www.paulirish.com/2009/throttled-smartresize-jquery-event-handler/
The reason is your vertical scrollbar. Your content is fixed at width=1030, but when the window size is 1030, the size of the viewport is actually: window size (1030) - vertical scroll bar
Try setting
<body style="overflow:hidden">
You will see that it works correctly when the scrollbar is removed. Or try setting:
<link href="assets/css/tablets-landscape.css" rel="stylesheet" type="text/css" media="screen and (max-width : 1045px)"/>
Set max-width:1045px to make up for scrollbar, you will see that it works correctly.
Your javascript should be like this:
var width = $(window).width() + verticalscrollbarWidth;

jQuery: The 'body' element is activating the scroll event twice

I've implemented an animation for my photo blog. I still have big problem because the 'body' element is activating the animation twice.
I think the problem stems from the $('body').animate. Because I think that when the body is animating, the scroll event would be activated again and thus triggering the event twice.
The problem of my code is scrolling the page up. When I scroll the page upwards. The scrollAnimatePrev will trigger and then $('body') element will animate itself. After the animation the animating variable is set to false. But the $('body') element triggers the scroll event because I guess when I set the scrollTop the scroll event is triggered. So once again currentPos is set to the $(window).scrollTop() then currentPos > previousPos returns true and !animating returns true so it will trigger the scrollAnimate.
Now I want to fix this. How?
$(function() {
var record = 0;
var imgHeight = $(".images").height();
var offset = $(".images").eq(0).offset();
var offsetHeight = offset.top;
var previousPos = $(window).scrollTop();
var animating = false;
var state = 0;
$(window).scroll(function() {
var currentPos = $(window).scrollTop();
console.log(currentPos);
if(currentPos > previousPos && !animating) {
record++;
scrollAnimate(record, imgHeight, offsetHeight);
animating = true;
} else if (currentPos < previousPos && !animating) {
record--
scrollAnimatePrev(record, imgHeight, offsetHeight);
animating = true;
}
previousPos = currentPos;
console.log(previousPos)
})
function scrollAnimate(record, imgHeight, offsetHeight) {
$('body').animate(
{scrollTop: (parseInt(offsetHeight) * (record+1)) + (parseInt(imgHeight) * record)},
1000,
"easeInOutQuart"
)
.animate(
{scrollTop: (parseInt(offsetHeight) * (record)) + (parseInt(imgHeight) * (record))},
1000,
"easeOutBounce",
function() {
animating = false;
}
)
}
function scrollAnimatePrev(record, imgHeight, offsetHeight) {
$('body').animate(
{scrollTop: ((parseInt(imgHeight) * record) + (parseInt(offsetHeight) * record)) - offsetHeight},
1000,
"easeInOutQuart"
)
.animate(
{scrollTop: ((parseInt(imgHeight) * record) + (parseInt(offsetHeight) * record))},
1000,
"easeOutBounce",
function() {
animating = false;
}
)
}
})
I think it might be firing that callback twice. I had a similar problem recently.
I had something similiar to
$('#id, #id2').animate({width: '200px'}, 100, function() { doSomethingOnceOnly(); })
It was calling my doSomethingOnceOnly() twice, and I thought it must have been the dual selectors in the $ argument. I simply made it 2 different selectors and it worked fine. So like this
$('#id').animate({width: '200px'}, 100);
$('#id2').animate({width: '200px'}, 100, function() { doSomethingOnceOnly(); );
Using a flag to control the trigger did the trick for me.
var targetOffset = 0;
var allow_trigger = true;
$('html,body').animate({scrollTop: targetOffset}, 'slow', function() {
if (allow_trigger) {
allow_trigger = false;
doSomethingOnlyOnce();
}
});

Categories

Resources