I would like to create a "smooth" scroll animation that slides down from one element to the next. I do not want to use Jquery or any libraries, just javascript and HTML. I have tried:
element.scrollIntoView();
This causes scrolling, but not a smooth animation. I have already looked at some other smooth-scrolling techniques, but they use Jquery. I would also like to add that the scrolling should be from ELEMENT on a page to another ELEMENT on the page. Scroll down only. Also only javascript function like function scrollFromHere(from, to).
I know this is an old answer, but for anyone looking for a solution in "modern times", scrollIntoView supports the behavior parameter:
element.scrollIntoView({
behavior: 'smooth'
});
Support for behavior: "smooth" is Chrome 61, Edge 79, Firefox 36, Safari 15.4.
So Safari is the only real issue for support, assuming you want to support more than just the latest major of Safari (as of 2022).
Never mind, I think I found an answer to my question. It took lots of searching, but here it is:
<div id="elem1"><button onclick="scrollToward('elem2', 'elem1');">Scroll Down</button></div>
<div id="elem2"></div>
<script>
//Here is my script:
function animate(elem,style,unit,from,to,time,prop) {
if( !elem) return;
var start = new Date().getTime(),
timer = setInterval(function() {
var step = Math.min(1,(new Date().getTime()-start)/time);
if (prop) {
elem[style] = (from+step*(to-from))+unit;
} else {
elem.style[style] = (from+step*(to-from))+unit;
}
if( step == 1) clearInterval(timer);
},25);
elem.style[style] = from+unit;
}
function scrollToward(ele, from) {
var target = document.getElementById(ele);
from = document.getElementById(from).offsetTop;
animate(document.body, "scrollTop", "", from, target.offsetTop, 1500, true);
}
</script>
Tested and works when you style the divs in a way that creates a scrollbar. Found the answer here.
!doctype html>
<head>
<style>
/* Prevents slides from flashing */
#slides {
display:none;
}
</style>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="jquery.slides.min.js"></script>
<script>
$(function(){
$("#slides").slidesjs({
width: 940,
height: 528
});
});
</script>
</head>
<body>
<div id="slides">
<img src="">
</div>
</body>
Related
I'm building multi layered parallax effect on my site (html, css, js). Everything works quite well, but I've noticed that my parallax effect works really bad on Firefox, window.onscroll seems to be laggy, refresh rate so to speak is very low.
Here's my JS implementation:
document.addEventListener('DOMContentLoaded', function() {
const layers = document.querySelectorAll("[data-type='parallax']");
window.addEventListener('scroll', event => {
const topDistance = window.pageYOffset;
window.requestAnimationFrame(function() {
for (let i = 0; i < layers.length; ++i) {
const depth = layers[i].getAttribute('data-depth');
const movement = topDistance * depth;
const translate3d = 'translate3d(0, ' + movement + 'px, 0)';
layers[i].style.transform = translate3d;
}
})
});
});
My html code:
<div class="parallax-banner">
<div class="parallax-layer layer-1" data-type="parallax" data-depth="0.05"></div>
<div class="parallax-layer layer-2" data-type="parallax" data-depth="0.2"></div>
<div class="parallax-layer layer-3" data-type="parallax" data-depth="0.4"></div>
<div class="parallax-layer layer-4" data-type="parallax" data-depth="0.6"></div>
<div class="parallax-layer layer-5" data-type="parallax" data-depth="0.7"></div>
<div class="parallax-layer layer-6" data-type="parallax" data-depth="0"></div>
</div>
Have you encountered it? Is it typical issue? How can I fix that?
I have the following very simple JS-implementation with two layers in the back, which was unusable with Firefox due to jittering and laggy behaviour:
$(function() {
$(window).on('scroll', function() {
$('#background').css('background-position-y', $(window).scrollTop() * -.15);
});
});
$(function() {
$(window).on('scroll', function() {
$('#background2').css('background-position-y', $(window).scrollTop() * -.09);
});
});
CSS-only alternatives didnt work for me as it caused the background layers to visibly overflow after my contents end.
Finally I found a way to improve the performance desktop Firefox (not on mobile yet). I added
position: fixed;
background-attachment: fixed;
background-position: top;
to all my background layers.
Still no improvement in iOS Safari and mobile Firefox.
There are several bug reports for Firefox since version 16.
On my long way searching the internet for solutions i also found and added a script by keithclark but I'm not sure if this makes any difference at all, the script is from 2011:
/*
Firefox super responsive scroll (c) Keith Clark - MIT Licensed
*/
(function(doc) {
console.log("Document executed")
var root = doc.documentElement,
scrollbarWidth, scrollEvent;
// Not ideal, but better than UA sniffing.
if ("MozAppearance" in root.style) {
// determine the vertical scrollbar width
scrollbarWidth = root.clientWidth;
root.style.overflow = "scroll";
scrollbarWidth -= root.clientWidth;
root.style.overflow = "";
// create a synthetic scroll event
scrollEvent = doc.createEvent("UIEvent")
scrollEvent.initEvent("scroll", true, true);
// event dispatcher
function scrollHandler() {
doc.dispatchEvent(scrollEvent)
}
// detect mouse events in the document scrollbar track
doc.addEventListener("mousedown", function(e) {
if (e.clientX > root.clientWidth - scrollbarWidth) {
doc.addEventListener("mousemove", scrollHandler, false);
doc.addEventListener("mouseup", function() {
doc.removeEventListener("mouseup", arguments.callee, false);
doc.removeEventListener("mousemove", scrollHandler, false);
}, false)
}
}, false)
// override mouse wheel behaviour.
doc.addEventListener("DOMMouseScroll", function(e) {
// Don't disable hot key behaviours
if (!e.ctrlKey && !e.shiftKey) {
root.scrollTop += e.detail * 16;
scrollHandler.call(this, e);
e.preventDefault()
}
}, false)
}
})(document);
You can test it by pasting it to the console.
I hope I could at least help a little bit.
In IOS8 Safari there is a new bug with position fixed.
If you focus a textarea that is in a fixed panel, safari will scroll you to the bottom of the page.
This makes all sorts of UIs impossible to work with, since you have no way of entering text into textareas without scrolling your page all the way down and losing your place.
Is there any way to workaround this bug cleanly?
#a {
height: 10000px;
background: linear-gradient(red, blue);
}
#b {
position: fixed;
bottom: 20px;
left: 10%;
width: 100%;
height: 300px;
}
textarea {
width: 80%;
height: 300px;
}
<html>
<body>
<div id="a"></div>
<div id="b"><textarea></textarea></div>
</body>
</html>
Based on this good analysis of this issue, I've used this in html and body elements in css:
html,body{
-webkit-overflow-scrolling : touch !important;
overflow: auto !important;
height: 100% !important;
}
I think it's working great for me.
The best solution I could come up with is to switch to using position: absolute; on focus and calculating the position it was at when it was using position: fixed;. The trick is that the focus event fires too late, so touchstart must be used.
The solution in this answer mimics the correct behavior we had in iOS 7 very closely.
Requirements:
The body element must have positioning in order to ensure proper positioning when the element switches to absolute positioning.
body {
position: relative;
}
The Code (Live Example):
The following code is a basic example for the provided test-case, and can be adapted for your specific use-case.
//Get the fixed element, and the input element it contains.
var fixed_el = document.getElementById('b');
var input_el = document.querySelector('textarea');
//Listen for touchstart, focus will fire too late.
input_el.addEventListener('touchstart', function() {
//If using a non-px value, you will have to get clever, or just use 0 and live with the temporary jump.
var bottom = parseFloat(window.getComputedStyle(fixed_el).bottom);
//Switch to position absolute.
fixed_el.style.position = 'absolute';
fixed_el.style.bottom = (document.height - (window.scrollY + window.innerHeight) + bottom) + 'px';
//Switch back when focus is lost.
function blured() {
fixed_el.style.position = '';
fixed_el.style.bottom = '';
input_el.removeEventListener('blur', blured);
}
input_el.addEventListener('blur', blured);
});
Here is the same code without the hack for comparison.
Caveat:
If the position: fixed; element has any other parent elements with positioning besides body, switching to position: absolute; may have unexpected behavior. Due to the nature of position: fixed; this is probably not a major issue, since nesting such elements is not common.
Recommendations:
While the use of the touchstart event will filter out most desktop environments, you will probably want to use user-agent sniffing so that this code will only run for the broken iOS 8, and not other devices such as Android and older iOS versions. Unfortunately, we don't yet know when Apple will fix this issue in iOS, but I would be surprised if it is not fixed in the next major version.
I found a method that works without the need to change to position absolute!
Full uncommented code
var scrollPos = $(document).scrollTop();
$(window).scroll(function(){
scrollPos = $(document).scrollTop();
});
var savedScrollPos = scrollPos;
function is_iOS() {
var iDevices = [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod'
];
while (iDevices.length) {
if (navigator.platform === iDevices.pop()){ return true; }
}
return false;
}
$('input[type=text]').on('touchstart', function(){
if (is_iOS()){
savedScrollPos = scrollPos;
$('body').css({
position: 'relative',
top: -scrollPos
});
$('html').css('overflow','hidden');
}
})
.blur(function(){
if (is_iOS()){
$('body, html').removeAttr('style');
$(document).scrollTop(savedScrollPos);
}
});
Breaking it down
First you need to have the fixed input field toward the top of the page in the HTML (it's a fixed element so it should semantically make sense to have it near the top anyway):
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
</head>
<body>
<form class="fixed-element">
<input class="thing-causing-the-issue" type="text" />
</form>
<div class="everything-else">(content)</div>
</body>
</html>
Then you need to save the current scroll position into global variables:
//Always know the current scroll position
var scrollPos = $(document).scrollTop();
$(window).scroll(function(){
scrollPos = $(document).scrollTop();
});
//need to be able to save current scroll pos while keeping actual scroll pos up to date
var savedScrollPos = scrollPos;
Then you need a way to detect iOS devices so it doesn't affect things that don't need the fix (function taken from https://stackoverflow.com/a/9039885/1611058)
//function for testing if it is an iOS device
function is_iOS() {
var iDevices = [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod'
];
while (iDevices.length) {
if (navigator.platform === iDevices.pop()){ return true; }
}
return false;
}
Now that we have everything we need, here is the fix :)
//when user touches the input
$('input[type=text]').on('touchstart', function(){
//only fire code if it's an iOS device
if (is_iOS()){
//set savedScrollPos to the current scroll position
savedScrollPos = scrollPos;
//shift the body up a number of pixels equal to the current scroll position
$('body').css({
position: 'relative',
top: -scrollPos
});
//Hide all content outside of the top of the visible area
//this essentially chops off the body at the position you are scrolled to so the browser can't scroll up any higher
$('html').css('overflow','hidden');
}
})
//when the user is done and removes focus from the input field
.blur(function(){
//checks if it is an iOS device
if (is_iOS()){
//Removes the custom styling from the body and html attribute
$('body, html').removeAttr('style');
//instantly scrolls the page back down to where you were when you clicked on input field
$(document).scrollTop(savedScrollPos);
}
});
I was able to fix this for select inputs by adding an event listener to the necessary select elements, then scrolling by an offset of one pixel when the select in question gains focus.
This isn't necessarily a good solution, but it's much simpler and more reliable than the other answers I've seen here. The browser seems to re-render/re-calculate the position: fixed; attribute based on the offset supplied in the window.scrollBy() function.
document.querySelector(".someSelect select").on("focus", function() {window.scrollBy(0, 1)});
Much like Mark Ryan Sallee suggested, I found that dynamically changing the height and overflow of my background element is the key - this gives Safari nothing to scroll to.
So after the modal's opening animation finishes, change the background's styling:
$('body > #your-background-element').css({
'overflow': 'hidden',
'height': 0
});
When you close the modal change it back:
$('body > #your-background-element').css({
'overflow': 'auto',
'height': 'auto'
});
While other answers are useful in simpler contexts, my DOM was too complicated (thanks SharePoint) to use the absolute/fixed position swap.
Cleanly? no.
I recently had this problem myself with a fixed search field in a sticky header, the best you can do at the moment is keep the scroll position in a variable at all times and upon selection make the fixed element's position absolute instead of fixed with a top position based on the document's scroll position.
This is however very ugly and still results in some strange back and forth scrolling before landing on the right place, but it is the closest I could get.
Any other solution would involve overriding the default scroll mechanics of the browser.
Haven't dealt with this particular bug, but maybe put an overflow: hidden; on the body when the text area is visible (or just active, depending on your design). This may have the effect of not giving the browser anywhere "down" to scroll to.
A possible solution would be to replace the input field.
Monitor click events on a div
focus a hidden input field to render the keyboard
replicate the content of the hidden input field into the fake input field
function focus() {
$('#hiddeninput').focus();
}
$(document.body).load(focus);
$('.fakeinput').bind("click",function() {
focus();
});
$("#hiddeninput").bind("keyup blur", function (){
$('.fakeinput .placeholder').html(this.value);
});
#hiddeninput {
position:fixed;
top:0;left:-100vw;
opacity:0;
height:0px;
width:0;
}
#hiddeninput:focus{
outline:none;
}
.fakeinput {
width:80vw;
margin:15px auto;
height:38px;
border:1px solid #000;
color:#000;
font-size:18px;
padding:12px 15px 10px;
display:block;
overflow:hidden;
}
.placeholder {
opacity:0.6;
vertical-align:middle;
}
<input type="text" id="hiddeninput"></input>
<div class="fakeinput">
<span class="placeholder">First Name</span>
</div>
codepen
None of these solutions worked for me because my DOM is complicated and I have dynamic infinite scroll pages, so I had to create my own.
Background: I am using a fixed header and an element further down that sticks below it once the user scrolls that far down. This element has a search input field. In addition, I have dynamic pages added during forward and backwards scroll.
Problem: In iOS, anytime the user clicked on the input in the fixed element, the browser would scroll all the way to the top of the page. This not only caused undesired behavior, it also triggered my dynamic page add at the top of the page.
Expected Solution: No scroll in iOS (none at all) when the user clicks on the input in the sticky element.
Solution:
/*Returns a function, that, as long as it continues to be invoked, will not
be triggered. The function will be called after it stops being called for
N milliseconds. If `immediate` is passed, trigger the function on the
leading edge, instead of the trailing.*/
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function is_iOS() {
var iDevices = [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod'
];
while (iDevices.length) {
if (navigator.platform === iDevices.pop()) { return true; }
}
return false;
}
$(document).on("scrollstop", debounce(function () {
//console.log("Stopped scrolling!");
if (is_iOS()) {
var yScrollPos = $(document).scrollTop();
if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
$('#searchBarDiv').css('position', 'absolute');
$('#searchBarDiv').css('top', yScrollPos + 50 + 'px'); //50 for fixed header
}
else {
$('#searchBarDiv').css('position', 'inherit');
}
}
},250,true));
$(document).on("scrollstart", debounce(function () {
//console.log("Started scrolling!");
if (is_iOS()) {
var yScrollPos = $(document).scrollTop();
if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
$('#searchBarDiv').css('position', 'fixed');
$('#searchBarDiv').css('width', '100%');
$('#searchBarDiv').css('top', '50px'); //50 for fixed header
}
}
},250,true));
Requirements: JQuery mobile is required for the startsroll and stopscroll functions to work.
Debounce is included to smooth out any lag created by the sticky element.
Tested in iOS10.
I just jumped over something like this yesterday by setting height of #a to max visible height (body height was in my case) when #b is visible
ex:
<script>
document.querySelector('#b').addEventListener('focus', function () {
document.querySelector('#a').style.height = document.body.clientHeight;
})
</script>
ps: sorry for late example, just noticed it was needed.
This is now fixed in iOS 10.3!
Hacks should no longer be needed.
I had the issue, below lines of code resolved it for me -
html{
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
I have elements moving downwards which can be paused and resumed by pressing the P key. I tried every jQuery pause plugin out there, however once I pause the animation it won't resume. What am I doing wrong?
Spawning code:
$(document.createElement('img')).attr('src', source).
attr('class', 'snowflake').
css('left', x + 'px').
prependTo('body').animate({ bottom: '0' }, 5000, 'linear');
Pause function (called when the P key is pressed):
Snow.togglePause = function (label) {
'use strict';
if (Snow.paused) {
$('.snowflake').fadeIn(250);
$('.snowflake').each(function() {
$(this).resume();
});
Snow.paused = false;
} else {
$('.snowflake').fadeOut(250);
$('.snowflake').each(function() {
$(this).pause();
});
Snow.paused = true;
}
};
I also tried replacing the each function with just $('.snowflake').resume(); and it didn't work.
Edit: The solution was simple. I solved it in a couple of minutes when I sat down and did the math after Matthew pointed me to the right way. Here's the final formula.
http://i.stack.imgur.com/gs8mj.png
In my case the duration after resuming is DOCUMENT_HEIGHT * 5000 / ELEMENT.css('bottom'); Document height is the distance covered if not paused as the element will move from the top to the bottom. 5000 is the speed I chose at the start and the bottom property of the element is the distance the element will cover when resumed. This makes the speed constant and solves the problem. Thank you all for your help.
If you're a user trying to get the equation yourself, simply equate the speed at the start with the speed at the end and use v = d / t to get the formula.
It looks like to achieve this you will need to use queue and dequeue (and clearQueue):
There is some information on it here with a nice little demo:
http://api.jquery.com/clearQueue/
Essentially you are creating a queue for your animation and then dequeuing it when someone hits the pause button and queuing it up again when they hit resume.
If you using jQuery 1.8 and above, you can use progress function callback in animate method.
Link to animate documentation : http://api.jquery.com/animate/
You can save the state of the current animation in the element and restore it later.
Example (it's a draft, feel free to upgrade):
Link to the example : http://jsbin.com/egemaTA/2/edit
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var $mydiv = $('div').animate({ bottom: '0' }, {
duration : 5000,
easing : 'linear',
progress : function(animation, progress, remainingMs){
$(this).data('stay', remainingMs);
}
});
$('#stop').click(function(ev){
$mydiv.stop();
});
$('#go').click(function(ev){
$mydiv.animate({ bottom: '0' }, {
duration : $mydiv.data('stay'),
easing : 'linear',
progress : function(animation, progress, remainingMs){
$(this).data('stay', remainingMs);
}
});
});
});
</script>
<style>
html, body{
height : 100%;
}
div{
position : absolute;
bottom : 100%;
width : 50px;
height : 50px;
background-color : lightblue;
}
</style>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div></div>
<button id="stop">Stop !</button>
<button id="go">Go</button>
</body>
</html>
I want to create an animation to scroll the page smoothly when clicking on anchor links, just like jQuery.ScrollTo plugin (http://demos.flesler.com/jquery/scrollTo/) does it.
I tried making it using YUI 2.x Animation utility, by animating the value of the property document.activeElement.scrollTop. It works on webkit only :'( - on the other browser, nothing happens - not even an error is raised.
goToAnchor = function(e, id) {
var targetToGo = Dom.get(id),
scrollToTarget = new Animation(document.activeElement,
{
scrollTop:
{
from: document.activeElement.scrollTop,
to: targetToGo.offsetTop
}
}, 1, Easing.easeOut
)
Event.preventDefault(e);
scrollToTarget.animate();
}
What I'd like to know is if there's a plugin that does this for YUI 2.x or how to do a cross browser compatible code to do so.
Thanks!
You need to keep in mind that depending on browser you might need to scroll the html or the body element.
(practially, you need to scroll both to be sure)
Also at http://developer.yahoo.com/yui/animation/#scroll i see
var element = document.getElementById('test');
var myAnim = new YAHOO.util.Scroll(element, {
scroll: {
to: [ 500, test.scrollTop ]
}
});
myAnim.animate();
Maybe that is what you are looking for (still you will have to animate both html and body)
<script>
(function() {
var scrollingBody = document.body;
if (YAHOO.env.ua.gecko){
scrollingBody = document.documentElement;
}
(new YAHOO.util.Scroll(
scrollingBody,
{
scroll:
{
to: [0, 50]
}
},
0.7,
YAHOO.util.Easing.easeOut
)).animate();
})();
</script>
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I'm trying to make a "bubble" that can popup when the onmouseover event is fired and will stay open as long as the mouse is over the item that threw the onmouseover event OR if the mouse is moved into the bubble. My bubble will need to have all manners of HTML and styling including hyperlinks, images, etc.
I've basically accomplished this by writing about 200 lines of ugly JavaScript but I would really like to find a jQuery plugin or some other way to clean this up a bit.
Qtip is the best one I've seen. It's MIT licensed, beautiful, has all the configuration you need.
My favorite lightweight option is tipsy. Also MIT licensed. It inspired Bootstrap's tooltip plugin.
This can be done easily with the mouseover event as well. I've done it and it doesn't take 200 lines at all. Start with triggering the event, then use a function that will create the tooltip.
$('span.clickme').mouseover(function(event) {
createTooltip(event);
}).mouseout(function(){
// create a hidefunction on the callback if you want
//hideTooltip();
});
function createTooltip(event){
$('<div class="tooltip">test</div>').appendTo('body');
positionTooltip(event);
};
Then you create a function that position the tooltip with the offset position of the DOM-element that triggered the mouseover event, this is doable with css.
function positionTooltip(event){
var tPosX = event.pageX - 10;
var tPosY = event.pageY - 100;
$('div.tooltip').css({'position': 'absolute', 'top': tPosY, 'left': tPosX});
};
Although qTip (the accepted answer) is good, I started using it, and it lacked some features I needed.
I then stumbled upon PoshyTip - it is very flexible, and really easy to use. (And I could do what I needed)
Ok, after some work I'm able to get a "bubble" to pop up and go away at all the right times. There is a LOT of styling that needs to happen still but this is basically the code i used.
<script type="text/javascript">
//--indicates the mouse is currently over a div
var onDiv = false;
//--indicates the mouse is currently over a link
var onLink = false;
//--indicates that the bubble currently exists
var bubbleExists = false;
//--this is the ID of the timeout that will close the window if the user mouseouts the link
var timeoutID;
function addBubbleMouseovers(mouseoverClass) {
$("."+mouseoverClass).mouseover(function(event) {
if (onDiv || onLink) {
return false;
}
onLink = true;
showBubble.call(this, event);
});
$("." + mouseoverClass).mouseout(function() {
onLink = false;
timeoutID = setTimeout(hideBubble, 150);
});
}
function hideBubble() {
clearTimeout(timeoutID);
//--if the mouse isn't on the div then hide the bubble
if (bubbleExists && !onDiv) {
$("#bubbleID").remove();
bubbleExists = false;
}
}
function showBubble(event) {
if (bubbleExists) {
hideBubble();
}
var tPosX = event.pageX + 15;
var tPosY = event.pageY - 60;
$('<div ID="bubbleID" style="top:' + tPosY + '; left:' + tPosX + '; position: absolute; display: inline; border: 2px; width: 200px; height: 150px; background-color: Red;">TESTING!!!!!!!!!!!!</div>').mouseover(keepBubbleOpen).mouseout(letBubbleClose).appendTo('body');
bubbleExists = true;
}
function keepBubbleOpen() {
onDiv = true;
}
function letBubbleClose() {
onDiv = false;
hideBubble();
}
//--TESTING!!!!!
$("document").ready(function() {
addBubbleMouseovers("temp1");
});
</script>
Here is a snippet of the html that goes with it:
Mouseover this for a terribly ugly red bubble!
I have programmed an useful jQuery Plugin to create easily smart bubble popups with only a line of code in jQuery!
What You can do:
- attach popups to any DOM element!
- mouseover/mouseout events automatically managed!
- set custom popups events!
- create smart shadowed popups! (in IE too!)
- choose popup’s style templates at runtime!
- insert HTML messages inside popups!
- set many options as: distances, velocity, delays, colors…
Popup’s shadows and colorized templates are fully supported by
Internet Explorer 6+, Firefox, Opera 9+, Safari
You can download sources from
http://plugins.jquery.com/project/jqBubblePopup
QTip has bug with jQuery 1.4.2. I had to switch to jQuery Bubble Pop up http://www.vegabit.com/jquery_bubble_popup_v2/#examples and it works great!
Sounds to me you dn't want the mouse over events: you want the jQuery hover() event.
And what you seem to want is a "rich" tooltip, in which case I suggest jQuery tooltip. With the bodyHandler option you can put arbitrary HTML in.
I'm trying to make a "bubble" that can
popup when the onmouseover event is
fired and will stay open as long as
the mouse is over the item that threw
the onmouseover event OR if the mouse
is moved into the bubble. My bubble
will need to have all manners of html
and styling including hyperlinks,
images, etc.
All those events fully managed by this plugin...
http://plugins.jquery.com/project/jqBubblePopup
ColorTip is the most beautiful i've ever seen
The new version 3.0 of the jQuery Bubble Popup plugin supports jQuery v.1.7.2, currently the latest and stable version of the most famous javascript library.
The most interesting feature of the 3.0 version is that You can use together jQuery & Bubble Popup plugin with any other libraries and javascript frameworks like Script.aculo.us, Mootols or Prototype because the plugin is completely encapsulated to prevent incompatibility problems;
jQuery Bubble Popup was tested and supports a lot of known and “unknown” browsers; see the documentation for the complete list.
Like previous versions, jQuery Bubble Popup plugin continues to be released under the MIT license; You are free to use jQuery Bubble Popup in commercial or personal projects as long as the copyright header is left intact.
download the latest version or visit live demos and tutorials at
http://www.maxvergelli.com/jquery-bubble-popup/
Autoresize simple Popup Bubble
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="bubble.css" type="text/css" rel="stylesheet" />
<script language="javascript" type="text/javascript" src="jquery.js"></script>
<script language="javascript" type="text/javascript" src="bubble.js"></script>
</head>
<body>
<br/><br/>
<div class="bubbleInfo">
<div class="bubble" title="Text 1">Set cursor</div>
</div>
<br/><br/><br/><br/>
<div class="bubbleInfo">
<div class="bubble" title="Text 2">Set cursor</div>
</div>
</body>
</html>
bubble.js
$(function () {
var i = 0;
var z=1;
do{
title = $('.bubble:eq('+i+')').attr('title');
if(!title){
z=0;
} else {
$('.bubble:eq('+i+')').after('<table style="opacity: 0; top: -50px; left: -33px; display: none;" id="dpop" class="popup"><tbody><tr><td id="topleft" class="corner"></td><td class="top"></td><td id="topright" class="corner"></td></tr><tr><td class="left"></td><td>'+title+'</td><td class="right"></td></tr><tr><td class="corner" id="bottomleft"></td><td class="bottom"><img src="bubble/bubble-tail.png" height="25px" width="30px" /></td><td id="bottomright" class="corner"></td></tr></tbody></table>');
$('.bubble:eq('+i+')').removeAttr('title');
}
i++;
}while(z>0)
$('.bubbleInfo').each(function () {
var distance = 10;
var time = 250;
var hideDelay = 500;
var hideDelayTimer = null;
var beingShown = false;
var shown = false;
var trigger = $('.bubble', this);
var info = $('.popup', this).css('opacity', 0);
$([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: -40,
left: 10,
display: 'block'
}).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;
});
});
});
bubble.css
/* Booble */
.bubbleInfo {
position: relative;
width: 500px;
}
.bubble {
}
.popup {
position: absolute;
display: none;
z-index: 50;
border-collapse: collapse;
font-size: .8em;
}
.popup td.corner {
height: 13px;
width: 15px;
}
.popup td#topleft {
background-image: url(bubble/bubble-1.png);
}
.popup td.top {
background-image: url(bubble/bubble-2.png);
}
.popup td#topright {
background-image: url(bubble/bubble-3.png);
}
.popup td.left {
background-image: url(bubble/bubble-4.png);
}
.popup td.right {
background-image: url(bubble/bubble-5.png);
}
.popup td#bottomleft {
background-image: url(bubble/bubble-6.png);
}
.popup td.bottom {
background-image: url(bubble/bubble-7.png);
text-align: center;
}
.popup td.bottom img {
display: block;
margin: 0 auto;
}
.popup td#bottomright {
background-image: url(bubble/bubble-8.png);
}
Tiptip is also a nice library.
You can use qTip for this; However you'd have to code a little for launching it on mouseover event; And in case you want a default watermark on your text fields, you'd have to use the watermark plugin...
I realized that this leads to lot of repetitive code; So I wrote a plugin on top of qTip that makes it really easy to attach informational popup to form fields. You can check it out here: https://bitbucket.org/gautamtandon/jquery.attachinfo
Hope this helps.