flip the tooltip when approaching the margin using "Collision" - javascript

My tooltips are going outside of the boundaries of my page. I am using a jquery plugin called aToolTip. Here is my code:
(function($) {
$.fn.aToolTip = function(options) {
/**
setup default settings
*/
var defaults = {
// no need to change/override
closeTipBtn: 'aToolTipCloseBtn',
toolTipId: 'aToolTip',
// ok to override
fixed: false,
clickIt: false,
inSpeed: 200,
outSpeed: 100,
tipContent: '',
toolTipClass: 'defaultTheme',
xOffset: 5,
yOffset: 5,
onShow: null,
onHide: null,
},
// This makes it so the users custom options overrides the default ones
settings = $.extend({}, defaults, options);
return this.each(function() {
var obj = $(this);
/**
Decide weather to use a title attr as the tooltip content
*/
if(obj.attr('title')){
// set the tooltip content/text to be the obj title attribute
var tipContent = obj.attr('title');
} else {
// if no title attribute set it to the tipContent option in settings
var tipContent = settings.tipContent;
}
/**
Build the markup for aToolTip
*/
var buildaToolTip = function(){
$('body').append("<div id='"+settings.toolTipId+"' class='"+settings.toolTipClass+"'><p class='aToolTipContent'>"+tipContent+"</p></div>");
if(tipContent && settings.clickIt){
$('#'+settings.toolTipId+' p.aToolTipContent')
.append("<a id='"+settings.closeTipBtn+"' href='#' alt='close'>close</a>");
}
},
/**
Position aToolTip
*/
positionaToolTip = function(){
$('#'+settings.toolTipId).css({
top: (obj.offset().top - $('#'+settings.toolTipId).outerHeight() - settings.yOffset) + 'px',
left: (obj.offset().left + obj.outerWidth() + settings.xOffset) + 'px'
})
// added delay() call...
.stop().delay(1000).fadeIn(settings.inSpeed, function(){
if ($.isFunction(settings.onShow)){
settings.onShow(obj);
}
});
},
/**
Remove aToolTip
*/
removeaToolTip = function(){
// Fade out
$('#'+settings.toolTipId).stop().fadeOut(settings.outSpeed, function(){
$(this).remove();
if($.isFunction(settings.onHide)){
settings.onHide(obj);
}
});
};
/**
Decide what kind of tooltips to display
*/
// Regular aToolTip
if(tipContent && !settings.clickIt){
// Activate on hover
obj.hover(function(){
// remove already existing tooltip
$('#'+settings.toolTipId).remove();
obj.attr({title: ''});
buildaToolTip();
positionaToolTip();
}, function(){
removeaToolTip();
});
}
// Click activated aToolTip
if(tipContent && settings.clickIt){
// Activate on click
obj.click(function(el){
// remove already existing tooltip
$('#'+settings.toolTipId).remove();
obj.attr({title: ''});
buildaToolTip();
positionaToolTip();
// Click to close tooltip
$('#'+settings.closeTipBtn).click(function(){
removeaToolTip();
return false;
});
return false;
});
}
// Follow mouse if enabled
if(!settings.fixed && !settings.clickIt){
obj.mousemove(function(el){
$('#'+settings.toolTipId).css({
top: (el.pageY - $('#'+settings.toolTipId).outerHeight() - settings.yOffset),
left: (el.pageX + settings.xOffset)
});
});
}
}); // END: return this
};
})(jQuery);
How do I modify my tooltips to flipfit flip when approaching the right margin? Right now I they disappear off into the right and top margins. I also need them to wrap after 350px.
I tried adding the following to the function with no results:
max-width: 350px,
collision: "flipfit flip",
What am I doing wrong?

your issue is right here:
positionaToolTip = function(){//this is not toggling between the two.
$('#'+settings.toolTipId).css({
top: (obj.offset().top - $('#'+settings.toolTipId).outerHeight() - settings.yOffset) + 'px',
left: (obj.offset().left + obj.outerWidth() + settings.xOffset) + 'px'
})
// added delay() call...
.stop().delay(1000).fadeIn(settings.inSpeed, function(){
if ($.isFunction(settings.onShow)){
settings.onShow(obj);
}
});
},
maybe adding something like this would work:
var $tooltip = $('#' + settings.toolTipId),
$win = $(window),
winLeft = $win.scrollLeft(),
objWidth = obj.outerWidth(),
tipWidth = $tooltip.outerWidth(),
offset = $obj.offset(),
ttWidth = $tooltip.outerWidth(),
ttHeight = $tooltip.outerHeight();
$win.width() < (offset.left - winLeft + objWidth + tipWidth + ttWidth) ?
$tooltip//reversed (to left)
.addClass("reversed")
.css({
left: offset.left - winLeft - tipWidth - ttWidth,
top: offset.top - $win.scrollTop() + $obj.outerHeight() / 2 + ttHeight
})
:
$tooltip//standard (to right)
.css({
left: offset.left - winLeft + objWidth + ttWidth,
top: offset.top - $win.scrollTop() + $obj.outerHeight() / 2 + ttHeight
});

Related

Script only works properly on page refresh

I have a function that makes a side panel (.link-panel) stop when it reaches (.footer), inside (.link-panel) is (.cover). (.cover) is the div that contains all the elements of the (.link-panel) so it is fixed and technically it is the one that stops when it reaches the (.footer). My function first initializes if .control_panel is at position: inline-block. If it isn't (meaning it's display: block and the page width is <= 750px), then an else statement initializes and makes .cover's position relative.
This function is working properly only on page refresh. For example, let's say my page's size is at: 1300px. The display works correctly, but when I shrink the window size to below <= 750px, the side-menu stays fixed even if I change the css property using jQuery. The problem can only be solved if I refresh the page. Then if I start at <= 750px and resize back up, the side menu does not display correctly and I have to refresh the page again for it to display correctly.
My code
$(document).ready(function(){
var panel = $(".control_panel").css("display");
if(panel == "inline-block"){
fixedScrollBar();
}else{
$(".link-panel").css("position", "relative");
}
});
function fixedScrollBar(){
var windw = this;
$.fn.followTo = function ( elem ) {
var $this = this,
$window = $(windw),
$bumper = $(elem),
bumperPos = $bumper.offset().top + -40,
thisHeight = $this.outerHeight(),
setPosition = function(){
if ($window.scrollTop() > (bumperPos - thisHeight)) {
$this.css({
position: 'absolute',
top: (bumperPos - thisHeight)
});
} else {
$this.css({
position: 'fixed',
top: 60
});
}
};
$window.resize(function()
{
thisHeight = $this.outerHeight();
setPosition();
});
$window.scroll(setPosition);
setPosition();
};
$('.cover').followTo('.footer');
}
Wrap your code in a resize event, test in your scroll event if the panel is inline-block and disable the css functions if its not:
$(document).ready(function() {
$(window).resize(function() {
var panel = $(".control_panel").css("display");
if (panel == "inline-block") {
fixedScrollBar();
} else {
$(".cover").css({"position":"relative","top":0});
}
}).trigger('resize');
});
function fixedScrollBar() {
var windw = this;
$.fn.followTo = function(elem) {
var $this = this,
$window = $(windw),
$bumper = $(elem),
bumperPos = $bumper.offset().top + -40,
thisHeight = $this.outerHeight(),
setPosition = function() {
if($(".control_panel").css("display") == "inline-block") {
if ($window.scrollTop() > (bumperPos - thisHeight)) {
$this.css({
position: 'absolute',
top: (bumperPos - thisHeight)
});
} else {
$this.css({
position: 'fixed',
top: 60
});
}
};
}
$window.scroll(setPosition);
setPosition();
};
$('.cover').followTo('.footer');
}
https://jsfiddle.net/e9dcmL2q/4/

Not working javascript codes when rotating page

I found a javascript file which I used it for making a carousel in my website. But I want to make it responsive. So, I changed it. When you refresh page, it works well but when you rotate the page in mobile or tablet it could not match itself by new width and height. what is the problem?
$(".website_carousel").jCarouselLite({
btnNext: ".nexts",
btnPrev: ".prev",
visible:(($(window).width() > 481) ? "3" : "2")
})
here is the plugin I used for carousel
(function ($) { // Compliant with jquery.noConflict()
$.jCarouselLite = {
version: '1.1'
};
$.fn.jCarouselLite = function(options) {
options = $.extend({}, $.fn.jCarouselLite.options, options || {});
return this.each(function() { // Returns the element collection. Chainable.
var running,
animCss, sizeCss,
div = $(this), ul, initialLi, li,
liSize, ulSize, divSize,
numVisible, initialItemLength, itemLength, calculatedTo, autoTimeout;
initVariables(); // Set the above variables after initial calculations
initStyles(); // Set the appropriate styles for the carousel div, ul and li
initSizes(); // Set appropriate sizes for the carousel div, ul and li
attachEventHandlers(); // Attach event handlers for carousel to respond
function go(to) {
if(!running) {
clearTimeout(autoTimeout); // Prevents multiple clicks while auto-scrolling - edge case
calculatedTo = to;
if(options.beforeStart) { // Call the beforeStart() callback
options.beforeStart.call(this, visibleItems());
}
if(options.circular) { // If circular, and "to" is going OOB, adjust it
adjustOobForCircular(to);
} else { // If non-circular and "to" is going OOB, adjust it.
adjustOobForNonCircular(to);
} // If neither overrides "calculatedTo", we are not in edge cases.
animateToPosition({ // Animate carousel item to position based on calculated values.
start: function() {
running = true;
},
done: function() {
if(options.afterEnd) {
options.afterEnd.call(this, visibleItems());
}
if(options.auto) {
setupAutoScroll();
}
running = false;
}
});
if(!options.circular) { // Enabling / Disabling buttons is applicable in non-circular mode only.
disableOrEnableButtons();
}
}
return false;
}
function initVariables() {
running = false;
animCss = options.vertical ? "top" : "left";
sizeCss = options.vertical ? "height" : "width";
ul = div.find(">ul");
initialLi = ul.find(">li");
initialItemLength = initialLi.size();
// To avoid a scenario where number of items is just 1 and visible is 3 for example.
numVisible = initialItemLength < options.visible ? initialItemLength : options.visible;
if(options.circular) {
var $lastItemSet = initialLi.slice(initialItemLength-numVisible).clone();
var $firstItemSet = initialLi.slice(0,numVisible).clone();
ul.prepend($lastItemSet) // Prepend the lis with final items so that the user can click the back button to start with
.append($firstItemSet); // Append the lis with first items so that the user can click the next button even after reaching the end
options.start += numVisible; // Since we have a few artificial lis in the front, we will have to move the pointer to point to the real first item
}
li = $("li", ul);
itemLength = li.size();
calculatedTo = options.start;
}
function initStyles() {
div.css("visibility", "visible"); // If the div was set to hidden in CSS, make it visible now
li.css({
overflow: "hidden",
"float": options.vertical ? "none" : "left" // Some minification tools fail if "" is not used
});
ul.css({
margin: "0",
padding: "0",
position: "relative",
"list-style": "none",
"z-index": "1"
});
div.css({
overflow: "hidden",
position: "relative",
"z-index": "2",
});
// For a non-circular carousel, if the start is 0 and btnPrev is supplied, disable the prev button
if(!options.circular && options.btnPrev && options.start == 0) {
$(options.btnPrev).addClass("disabled");
}
}
function initSizes() {
var width_1 = div.width();
width_2=width_1/numVisible;
li.css({'width':width_2+'px'});
liSize = options.vertical ? // Full li size(incl margin)-Used for animation and to set ulSize
li.outerHeight(true) :
width_2;
ulSize = liSize * itemLength; // size of full ul(total length, not just for the visible items)
// Size of the entire UL. Including hidden and visible elements
// Will include LI's (width + padding + border + margin) * itemLength - Using outerwidth(true)
ul.css(sizeCss, ulSize+"px")
.css(animCss, -(calculatedTo * liSize));
// Width of the DIV. Only the width of the visible elements
// Will include LI's (width + padding + border + margin) * numVisible - Using outerwidth(true)
}
function attachEventHandlers() {
if(options.btnPrev) {
$(options.btnPrev).click(function() {
return go(calculatedTo - options.scroll);
});
}
if(options.btnNext) {
$(options.btnNext).click(function() {
return go(calculatedTo + options.scroll);
});
}
if(options.btnGo) {
$.each(options.btnGo, function(i, val) {
$(val).click(function() {
return go(options.circular ? numVisible + i : i);
});
});
}
if(options.mouseWheel && div.mousewheel) {
div.mousewheel(function(e, d) {
return d > 0 ?
go(calculatedTo - options.scroll) :
go(calculatedTo + options.scroll);
});
}
if(options.auto) {
setupAutoScroll();
}
}
function setupAutoScroll() {
autoTimeout = setTimeout(function() {
go(calculatedTo + options.scroll);
}, options.auto);
}
function visibleItems() {
return li.slice(calculatedTo).slice(0,numVisible);
}
function adjustOobForCircular(to) {
var newPosition;
// If first, then goto last
if(to <= options.start - numVisible - 1) {
newPosition = to + initialItemLength + options.scroll;
ul.css(animCss, -(newPosition * liSize) + "px");
calculatedTo = newPosition - options.scroll;
console.log("Before - Positioned at: " + newPosition + " and Moving to: " + calculatedTo);
}
// If last, then goto first
else if(to >= itemLength - numVisible + 1) {
newPosition = to - initialItemLength - options.scroll;
ul.css(animCss, -(newPosition * liSize) + "px");
calculatedTo = newPosition + options.scroll;
console.log("After - Positioned at: " + newPosition + " and Moving to: " + calculatedTo);
}
}
function adjustOobForNonCircular(to) {
// If user clicks "prev" and tries to go before the first element, reset it to first element.
if(to < 0) {
calculatedTo = 0;
}
// If "to" is greater than the max index that we can use to show another set of elements
// it means that we will have to reset "to" to a smallest possible index that can show it
else if(to > itemLength - numVisible) {
calculatedTo = itemLength - numVisible;
}
console.log("Item Length: " + itemLength + "; " +
"To: " + to + "; " +
"CalculatedTo: " + calculatedTo + "; " +
"Num Visible: " + numVisible);
}
function disableOrEnableButtons() {
$(options.btnPrev + "," + options.btnNext).removeClass("disabled");
$( (calculatedTo-options.scroll<0 && options.btnPrev)
||
(calculatedTo+options.scroll > itemLength-numVisible && options.btnNext)
||
[]
).addClass("disabled");
}
function animateToPosition(animationOptions) {
running = true;
ul.animate(
animCss == "left" ?
{ left: -(calculatedTo*liSize) } :
{ top: -(calculatedTo*liSize) },
$.extend({
duration: options.speed,
easing: options.easing
}, animationOptions)
);
}
});
};
$.fn.jCarouselLite.options = {
btnPrev: null, // CSS Selector for the previous button
btnNext: null, // CSS Selector for the next button
btnGo: null, // CSS Selector for the go button
mouseWheel: false, // Set "true" if you want the carousel scrolled using mouse wheel
auto: null, // Set to a numeric value (800) in millis. Time period between auto scrolls
speed: 200, // Set to a numeric value in millis. Speed of scroll
easing: null, // Set to easing (bounceout) to specify the animation easing
vertical: false, // Set to "true" to make the carousel scroll vertically
circular: true, // Set to "true" to make it an infinite carousel
visible: 3, // Set to a numeric value to specify the number of visible elements at a time
start: 0, // Set to a numeric value to specify which item to start from
scroll: 1, // Set to a numeric value to specify how many items to scroll for one scroll event
beforeStart: null, // Set to a function to receive a callback before every scroll start
afterEnd: null // Set to a function to receive a callback after every scroll end
};
})(jQuery);
The jquery library may be not working.Make sure you did include javascript Jquery library is correctly.
From the official documentation:
https://github.com/kswedberg/jquery-carousel-lite#responsive-carousels
Responsive Carousels
The responsive option is set to false by default. Once you set it to
true, you may want to set a few other options to get the desired
effect:
Everything automatic (autoCSS is true by default, so no need to add
it)
$('div.carousel').jCarouselLite({
// autoCSS: true,
autoWidth: true,
responsive: true
});
Everything manual (autoWidth is false by default, so no need to add
it)
Your best bet in this situation is to use CSS media queries.
$('div.carousel').jCarouselLite({
autoCSS: false,
// autoWidth: false,
responsive: true
});
// Bind your own handler to the refreshCarousel custom event, //
which is triggered when the window stops resizing
$('div.carousel').on('refreshCarousel', function() {
// do something
});

Jquery not recognize on click function second time

I really need help.
Here's what I'm trying to do: I wanna create 3 div elements which are flying from top to bottom of div (#lang_flying_objects) and when i click "the right one" (by Id), I need to create three more. When I create them I assign them all class "snowflakes".
But I am only able to click on the first group and my onclick function recognize the right id, but when other group is created it won't trigger the onclick function.
PLEASE HELP ME.
Here is the code I'm using:
<script>
function fallingStuff() {
var $snowflakes = $(),
createFallingStuff = function () {
var $snowflake = $('<div class="snowflakes" id="first"></div>');
$snowflake.css({
'left': (Math.random() * ($('#lang_flying_objects').width()/3 - offset)) + 'px',
'top': (-(20 + offset)) + 'px'
});
// add this snowflake to the set of snowflakes
$snowflakes = $snowflakes.add($snowflake);
var $snowflake2 = $('<div class="snowflakes" id="second" ></div>');
$snowflake2.css({
'left': (Math.random() * ($('#lang_flying_objects').width()/3 - offset) + $('#lang_flying_objects').width()/3) + 'px',
'top': (-(20 + offset)) + 'px'
});
// add this snowflake to the set of snowflakes
$snowflakes = $snowflakes.add($snowflake2);
var $snowflake3 = $('<div class="snowflakes" id="third"></div>');
$snowflake3.css({
'left': (Math.random() * ($('#lang_flying_objects').width()/3 - offset) + 2*$('#lang_flying_objects').width()/3) + 'px',
'top': (-(20 + offset)) + 'px'
});
// add this snowflake to the set of snowflakes
$snowflakes = $snowflakes.add($snowflake3);
$('#falling_zone').prepend($snowflakes);
},
runFalling = function() {
$snowflakes.each(function() {
var singleAnimation = function($flake) {
$flake.animate({
top: "500px",
opacity : "0"
}, 10000);
};
singleAnimation($(this));
});
};
createFallingStuff();
runFalling();
}
fallingStuff();
</script>
And here is my onclick function:
<script>
$('.snowflakes').on('click', function() {
var idInputed = $(this).attr('id');
if(idInputed == "first") //for example
{
fallingStuff();
}
});
</script>
Why it won't recognize the onclick function for second group of created divs?
Since the elements are created dynamically, you should use event delegation:
$(document).on('click', '.snowflakes', function() {
var idInputed = $(this).attr('id');
if(idInputed == "first") {
fallingStuff();
}
});

How to stop and reset few animated elements in object? (several separate animations)

I have created a few animations and each of them should be a separate slide on the main site slider.
Thats why, I've got from my boss an object structure (code below) and he said I should use it to those animations.
var RDAnimation = function(o){
var f = $.extend({
start: function() {
return true;
},
pause: function() {
return true;
},
reset: function() {
return true;
},
stop: function() {
if (this.pause()) {
return this.reset();
}
},
vars: {}
},o);
this.start = f.start;
this.pause = f.pause;
this.reset = f.reset;
this.stop = f.stop;
this.vars=f.vars;
};
But because I don't have a much of experience with working on objects, I just paste all of the animating function into 'start', just to see what will happen (code below).
var anim3=new RDAnimation({
start: function() {
var $this = this;
function bars() {
var barHeight = 0;
$('.chart-bar').each(function () {
barHeight = Math.floor(Math.random() * 100);
$(this).delay(1000).animate({
'height': barHeight + '%',
'min-height': '20px'},
700, function(){
bars();
});
});
}
var count = 0;
function badgeClone() {
var badge1 = $('.badge');
var badge2 = $('.badge').clone();
var badgeWidth = badge1.width();
var badgeHeight = badge1.height();
//badge1.text(count);
badge1.after(badge2);
badge2.css({
'line-height': '180px',
'text-align': 'center',
'font-size': '70px',
'font-weight': 'bold',
'color': '#fff',
'opacity':'0'
});
badge2.animate({
'width': badgeWidth * 2 + 'px',
'height': badgeHeight *2 + 'px',
'line-height': '360px',
'font-size': '140px',
'top': '-150px',
'right': '-100px'
},
100, "linear", function() {
if(count >= 9) {
count = 1
} else {
count++
}
badge2.text(count);
badge2.delay(300).animate({
'width': badgeWidth + 'px',
'height': badgeHeight + 'px',
'line-height': '180px',
'font-size': '70px',
'top': '-60px',
'right': '-40px',
'opacity': '1'},
100, "linear", function(){
badge1.fadeOut(600, function(){
$(this).remove();
});
});
});
}
bars();
var chartbars = $('.chart-bar');
$(chartbars).each(function(i) {
chartbar = chartbars[i];
var leftPos = i * 24 + 4;
$(chartbar).css({'left': leftPos + 'px'});
});
// ppl animations
var height = $('.person').height();
$('.person').css({'top': -height + 'px'});
var female = function(){
$('.female').fadeIn(300).animate({'top': '0px'}, 2500, function(){
male();
badgeClone();
$(this).delay(1000).fadeOut(500, function() {
$(this).css({'top': -height + 'px'});
});
});
};
var male = function(){
$('.male').fadeIn(300).animate({'top': '0px'},2500,function(){
badgeClone();
female();
$(this).delay(1000).fadeOut(500, function() {
$(this).css({'top': -height + 'px'});
});
});
};
male();
},
pause: function() {
var $this = this;
$('.chart-bar').stop();
},
reset: function() {
var $this = this;
$this.count = 0;
},
vars: {
}
});
And it's working! Animation will start when I run anim3.start. But now.. How can I stop it? Because I have to stop it when user chose another animated slide, and start it from beginning when user again chose this slide.
I've wrote a simple code, just for test.. But it doesnt work.
In code above I've wrote $('.chart-bar').stop(); in pause, to check if this will stop at least one chart-bar animation but it doesnt.
In reset I've wrote $this.count = 0; to reset number on the .badge element - but it doesnt work as well..
Obviously, to run those lines of code I've put a simple code on the bottom of script (code below).
$('#slider-2, #slider-3').hide();
$('.tour-slider').on('click', 'li a', function(e){
e.preventDefault();
$(this).closest('.slider').hide();
var sliderHref = $(this).attr('href');
$(sliderHref).fadeIn();
if(sliderHref == '#slider-1'){
anim1.start();
anim3.pause();
}else if(sliderHref == '#slider-2'){
anim2.start();
anim3.pause();
}else if(sliderHref == '#slider-3'){
anim3.reset();
anim3.start();
anim3.pause();
}
});
As you can see, I even run a anim3.pause(); at once, after I start it - just to check, if it will stop immediately - but even one chart-bar didn't stop..
So now, can somebody tell my please, how can I stop (and reset) these animated elements? I just need to get one working example and rest I can do by my own.
I will be grateful for any help
Cheers!
Ok, I found a solution.
1st of I modify a bars() function (add if statement)
function bars() {
var barHeight = 0;
var loop = true;
$('.chart-bar').each(function () {
barHeight = Math.floor(Math.random() * 100);
$(this).delay(1000).animate({
'height': barHeight + '%',
'min-height': '20px'},
700, function(){
if (loop) {
bars();
}
});
});
}
And then all I need was those two line of code added into my pause method:
pause: function() {
var $this = this;
$('#animation-3').find('*').stop(true, false);
$this.loop = false;
}
Thanks everyone for your time :)

How to call the drag events on the cloned element synchronously?

I've to drag the cloned element, but i don't understand how to call the trigger events synchronously
my example: http://jsfiddle.net/CfSMG/4/
correct example: http://jqueryui.com/demos/droppable/#photo-manager
Up:
Thx to all i've resolved the problem allready
My solution:
$('#move').mousedown(function(event) {
var offset = $(this).offset(),
map = {
position: 'absolute',
top : offset.top + 'px',
left : offset.left + 'px',
zIndex : 100
};
if($('.foo')[0]) return this;
$(this).clone().bind('mousedown mousemove', function(event) {
var _this = $(this),
offset = _this.position(),
_event = event;
$(document).bind({
mousemove : function(event) {
var axis = function(i) {
var page = {
top : 'pageY',
left : 'pageX'
}[i];
return event[page] - (_event[page] - offset[i]) + 'px';
};
_this.css({
left : axis('left'),
top : axis('top')
}).unbind('mousemove');
},
mouseup : function() {
_this.animate(map, function() {
$(this).remove();
});
$(this).unbind('mousemove');
}
});
}).addClass('foo').css(map).appendTo('body');
event.preventDefault();
event.stopPropagation();
});
Live demo: jsFiddle

Categories

Resources