How to make a tooltip for scrollbar? - javascript

I'm doing a webpage with listed items and those items are in Alphabetic order. Today i saw Tooltip in Google's contact web when scrolling my Mobile contact list from that web. Tooltip was fixed with scroll-bar and moves along with scroll-bar. I was wondering to implement that idea into my project because my list items are also in Alphabetic order. Can someone help out how to make a Tooltip like Google does?

This should get you started - clearly this wont work on mobile devices, but it may be a good jumping off point
var tooltip = document.createElement('div');
tooltip.style.cssText = 'position:fixed;right:18px;top:0;display:none;width:4em;height:1.2em;background:black;font-size:24px;font-weight:bold;color:white;text-align:center;padding-top:5px;';
document.body.appendChild(tooltip);
var mouseIsDown = false;
var displayed = false;
window.addEventListener('mousedown', function() {
mouseIsDown = true;
});
window.addEventListener('mouseup', function() {
mouseIsDown = false;
if (displayed) {
displayed = false;
tooltip.style.display = 'none';
}
});
window.addEventListener('mousemove', function(e) {
if (displayed) {
tooltip.style.top = e.clientY + 'px';
console.log(e);
}
});
window.addEventListener('scroll', function() {
if (mouseIsDown) {
var pos = parseInt(window.scrollY * 100.0 / window.scrollMaxY);
tooltip.textContent = pos + '%';
if (!displayed) {
tooltip.style.display = 'block';
displayed = true;
}
}
});

I was working on the same problem.. what about this (naive) solution?
$(window).scroll(function(){
$("#scrollerTooltip").css("top",(window.pageYOffset+window.pageYOffset*window.innerHeight)/document.body.scrollHeight)+'px');
});
Here's an example for this issue (working on chrome)

Related

On scroll up/down trigger a function once

I need to load 2 different animated graphic on window scroll up/down on a website by triggering some functions, it's working but its buggy as the functions are triggered too many times when scrolling:
$(window).scroll(function() {
var scroll = $(window).scrollTop(),
headerHeight = $('.navbar').outerHeight();
if(scroll > headerHeight) {
loadLogoAnimeDown();
}else{
loadLogoAnimeUp();
}
});
You need a way to check if the functions have been called (and logo has been loaded), so you can use a variable for that. After the logo has been loaded, you set the variable as false, which prevents them from loading more than once.
var downNotLoaded = true;
var upNotLoaded = true;
$(window).scroll(function() {
var scroll = $(window).scrollTop(),
headerHeight = $('.navbar').outerHeight();
if(scroll > headerHeight) {
if(downNotLoaded){
loadLogoAnimeDown();
downNotLoaded = false;
}
}else{
if(upNotLoaded){
loadLogoAnimeUp();
upNotLoaded = false;
}
}
});
I think you might find this is a very hacky way to do it, but this should work.
var animated;
$(window).scroll(function() {
var scroll = $(window).scrollTop(),
headerHeight = $('.navbar').outerHeight();
if(scroll > headerHeight) {
if (animated == true) {
loadLogoAnimeDown();
animated = false;
}
} else{
if (animated == false) {
loadLogoAnimeUp();
animated = true;
}
}
});

How to remove jank when setting an element to a fixed position using JavaScript

I have a webpage that when scrolled down, the text freezes when it reaches the last paragraph of text but the images keep on scrolling. I've got the implementation working but there is a lot of jank when scrolling with a mouse wheel, not so much if I click and drag the scroll bar.
Are there any optimizations I can make to this code to make work as intended or is there a different way to accomplish the same task?
window.addEventListener('scroll', function (e) {
window.requestAnimationFrame(keepTextStationary);
//keepTextStationary(); // Less janky, but still horrible
});
function keepTextStationary() {
var textRect = writtenContent.getBoundingClientRect();
var imageRec = images.getBoundingClientRect();
if (textRect.bottom < window.innerHeight && document.documentElement.scrollTop > 0) {
writtenContent.style.position = 'relative';
writtenContent.style.bottom = (225 - document.documentElement.scrollTop) + 'px';
if (imagesTop === undefined) {
imagesTop = imageRec.y;
}
} else {
writtenContent.style.bottom = (225 - document.documentElement.scrollTop) + 'px';
}
if (imageRec.y >= imagesTop) {
writtenContent.style.position = '';
}
}
Here is the site so you can see the problem.
https://bowerbankninow.azurewebsites.net/exhibitions/oscar-perry-the-pheasant
You are causing layout trashing every time you call getBoundingClientRect. Try debouncing your scroll events:
var lastScrollY = 0;
var ticking = false;
function keepTextStationary() {
var textRect = writtenContent.getBoundingClientRect();
var imageRec = images.getBoundingClientRect();
if (textRect.bottom < window.innerHeight && lastScrollY > 0) {
writtenContent.style.position = 'relative';
writtenContent.style.bottom = (225 - lastScrollY) + 'px';
if (imagesTop === undefined) {
imagesTop = imageRec.y;
}
} else {
writtenContent.style.bottom = (225 - lastScrollY) + 'px';
}
if (imageRec.y >= imagesTop) {
writtenContent.style.position = '';
}
ticking = false;
}
function onScroll() {
lastScrollY = document.documentElement.scrollTop;
requestTick();
}
function requestTick() {
if (!ticking) {
requestAnimationFrame(keepTextStationary);
ticking = true;
}
}
window.addEventListener('scroll', onScroll );
See this article for in-depth explanation: https://www.html5rocks.com/en/tutorials/speed/animations/
You dont.
Relocations / styling in javascript take place after the CSS has been loaded. Bad practise. What you can do, is make it animated to make it look less horrible.
Why is pure CSS not an option ?

Dragging full-width elements - possible?

I am building simple slider with dragging ability. For now, I use pageX to determine the position, like so:
var dragdir = 0,
drag = null;
$('article.small-section').on('mousedown', function(ev) {
drag = 1;
dragdir = ev.pageX;
if(drag) {
$(this).css('cursor','move');
}
}).on('mouseup', function(e){
drag = null
if(!drag) {
$(this).css('cursor','initial');
$(this).css('left','0')
}
});
$('article.small-section').on('mousemove', function(e) {
if(drag) {
if(dragdir > e.pageX) {
//console.log(dragdir+'|'+e.pageX)
if(dragdir > e.pageX+100) {
$(this).parent('section').cycle('prev');
}
$(this).css('right','');
$(this).css('left','-'+(parseInt(e.pageX/10))+'px');
} else {
if(dragdir < e.pageX-100) {
$(this).parent('section').cycle('next');
}
$(this).css('left','');
$(this).css('right','-'+(parseInt(e.pageX/10))+'px');
}
}
});
It works great dragging to the right. To the left - it does, then it backs (or doesn't go at all). I noticed that pageX is going down - that's the problem. How can I fix it?
Working fiddle: http://jsfiddle.net/2jEJH/1/

jQuery curtain scroller app

I'm trying to build a curtain slider - much like what is used on the Apple site - http://www.apple.com/30-years/
http://jsfiddle.net/NYEaX/405/
I've created the following code - I need to add listeners to detect the mouse hovering over the far left/far right sides of the page - and then invoke an exponential slide.
var curtainSlider = {
invoke: function(el){
var that = this;
var list = $(el + " ul").find("li");
this.initialListWidth = list.outerWidth(true);
list
.mouseover(function() {
console.log("over");
that.expand(this);
})
.mouseout(function() {
console.log("out");
that.contract(this);
});
},
expand: function(el){
var that = this;
$(el).stop().animate({
width: that.initialListWidth*2
},400, function() {
// Animation complete.
});
},
contract: function(el){
var that = this;
$(el).stop().animate({
width: that.initialListWidth
},400, function() {
// Animation complete.
});
}
}
$(document).ready(function() {
console.log( "ready!" );
curtainSlider.invoke("#curtain");
});
**LATEST CODE - complete integration - http://jsfiddle.net/NYEaX/538/ **
I have stabilized this version of the scroller. - This curtains the images and spectrum fades them on start up. It repositions the a elements so the image is more centrally aligned.
http://jsfiddle.net/NYEaX/432/
I've separated out the code responsible for moving the slider unit, with an acceleration/deceleration. Its this part of the application I wish to focus on now.
http://jsfiddle.net/NYEaX/434/
I've tried to push the pagex variable into the animation part to help manipulate the duration of the animation. How can this be stabilized/improved on. I am finding it hard to reverse engineer the apple 30 year slider.
var curtainSlider = {
bindEvents: function(){
var that = this;
$("body").on("mousemove",function(event) {
if (event.pageX < 50) {
// animate curtain left
console.log("curtain left");
that.scroll("l", event.pageX);
}
if (event.pageX > (window.width - 50)) {
// animate curtain right
console.log("curtain right");
that.scroll("r", window.width - event.pageX);
}
});
},
scroll: function(direction, leveler){
var charge = "-";
if(direction == "r"){
charge = "+";
}
$('#curtainholder #slider').animate({
left: charge+"="+leveler
},400, function() {
// Animation complete.
});
},
invoke: function(el){
var that = this;
this.bindEvents();
}
}
$(document).ready(function() {
curtainSlider.invoke("#curtain");
});

Javascript drag and drop code works on div but doesn't work on img

I'm fairly new to JavaScript, so any help would be awesome!
I created this small block of code that let's me grab a div and drag it around. I assign the "dragme" id to the div and all is fine and dandy. The problem is that if I replace that div from my html and put an img element instead (obviously assigning the "dragme" id to the img), things don't work as expected.
When I click to drag the img, it actually moves for about 3 or 4 pixels then it freezes until I lift the mouse button (mouseup).
Is there some property or characteristic that would prevent the img element from acting the same way as the div does?
var isClicked = false;
var startClientX = 0;
var startClientY = 0;
var startLeft = 0;
var startTop = 0;
window.addEventListener("load", addListeners, true);
function addListeners()
{
document.getElementById("dragme").addEventListener("mousedown", mouseIsDown, false);
document.getElementById("dragme").addEventListener("mouseup", mouseIsUp, false);
window.addEventListener("mousemove", moveImage, false);
function mouseIsDown(e)
{
if (isClicked == false)
{
isClicked = true;
startClientX = e.clientX;
startClientY = e.clientY;
startLeft = document.getElementById("dragme").offsetLeft;
startTop = document.getElementById("dragme").offsetTop;
}
}
function mouseIsUp()
{
if (isClicked == true)
{
isClicked = false;
}
}
function moveImage(e)
{
if (isClicked == true)
{
imageLeftDif = e.clientX - startClientX;
imageTopDif = e.clientY - startClientY;
var newLeftPos = (startLeft + imageLeftDif) + "px";
var newTopPos = (startTop + imageTopDif) + "px";
document.getElementById("dragme").style.left = newLeftPos;
document.getElementById("dragme").style.top = newTopPos;
}
}
}
This fixed the problem (answer provided as a comment by syazdani):
I'd venture to say that the built in browser drag and drop for images
is kicking in. Try e.preventDefault and return false in the mousedown
handler. – syazdani Dec 2 '12 at 17:26

Categories

Resources