I want to repurpose this code from a video guide on website headers that hides when you scroll down and shows when you scroll up
<script>
"use strict";
OB_ready(OB_doWhenReady);
function OB_doWhenReady() {
// localize everything
var ooohBoi = window.ooohBoi || {};
// local scope variables
ooohBoi.prev_scroll_pos = window.scrollY || document.body.scrollTop;
ooohBoi.cur_scroll_pos;
ooohBoi.scroll_direction = 'init';
ooohBoi.prev_scroll_direction = 0;
ooohBoi.header = document.querySelector('#show-hide-header'); // header ID
ooohBoi.header_pos = {
top: ooohBoi.header.offsetTop,
left: ooohBoi.header.offsetLeft,
};
ooohBoi.header_height = OB_outerHeight(ooohBoi.header);
// show-hide header with ease/transition
ooohBoi.header.style.transition = 'all 0.3s ease';
// update header height on window resize
ooohBoi.updateHeaderHeight = function() {
ooohBoi.header_height = OB_outerHeight(ooohBoi.header);
}
// listen "scroll" event and decide what to do
ooohBoi.checkScroll = function() {
ooohBoi.cur_scroll_pos = window.scrollY || document.body.scrollTop;
if (ooohBoi.cur_scroll_pos > ooohBoi.prev_scroll_pos) ooohBoi.scroll_direction = 'down';
else if (ooohBoi.cur_scroll_pos < ooohBoi.prev_scroll_pos) ooohBoi.scroll_direction = 'up';
if (ooohBoi.scroll_direction !== ooohBoi.prev_scroll_direction) ooohBoi.toggleHeader(ooohBoi.scroll_direction, ooohBoi.cur_scroll_pos);
ooohBoi.prev_scroll_pos = ooohBoi.cur_scroll_pos;
}
// add or remove class based on the scrolling direction
ooohBoi.toggleHeader = function(scroll_direction, scroll_current) {
if (scroll_direction === 'down' && scroll_current > ooohBoi.header_height) {
OB_addClass(ooohBoi.header, 'im-hidden'); // for styling
ooohBoi.header.style.top = -1 * ooohBoi.header_height + "px";
ooohBoi.prev_scroll_direction = scroll_direction;
} else if (scroll_direction === 'up') {
OB_removeClass(ooohBoi.header, 'im-hidden');
ooohBoi.header.style.top = ooohBoi.header_pos.top + "px";
ooohBoi.prev_scroll_direction = scroll_direction;
}
}
// listen "scroll" and "resize" window events
window.addEventListener('scroll', ooohBoi.checkScroll);
window.addEventListener('resize', ooohBoi.updateHeaderHeight);
}
function OB_outerHeight(el) {
var height = el.offsetHeight;
var style = getComputedStyle(el);
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
return height;
}
function OB_addClass(el, className) {
if (el.classList) el.classList.add(className);
else {
var current = el.className,
found = false;
var all = current.split(' ');
for (var i = 0; i < all.length, !found; i++) found = all[i] === className;
if (!found) {
if (current === '') el.className = className;
else el.className += ' ' + className;
}
}
}
function OB_removeClass(el, className) {
if (el.classList) el.classList.remove(className);
else el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
function OB_ready(fn) {
if (document.readyState != 'loading') fn();
else if (document.addEventListener) document.addEventListener('DOMContentLoaded', fn);
else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState != 'loading') fn();
});
}
}
</script>
What I want to do is to repurpose this code for a sticky button at the bottom of screen (image)
How do I edit the code so that:
Instead of showing on scroll up and hiding on scroll down -> It shows on scroll down and hides on scroll up
Instead of sliding in and out from the top of the screen -> The button slides in and out from the bottom of the screen.
Thank you!
Related
I integrated dragula in my project, and I need the tiles to have a grid look, so I changed line #441 (dropTarget.insertBefore(item, reference);) to:
var immediateSibling = immediate.nextSibling;
parent.insertBefore(immediate, item);
parent.insertBefore(item, immediateSibling);
See issue #391 for more info on that.
Anyway, I want to add animation when you drag the tiles. So I modifyed line #441 to this:
var immediateSibling = immediate.nextSibling,
itemRect = item.getBoundingClientRect(),
immediateRect = immediate.getBoundingClientRect();
parent.insertBefore(immediate, item);
parent.insertBefore(item, immediateSibling);
animate(immediate, immediateRect, itemRect);
animate(item, itemRect, immediateRect);
function animate(target, currentRect, prevRect) {
var ms = 5000;
target.style.transition = 'none';
target.style.transform = 'translate3d(' + (currentRect.left - prevRect.left) + 'px,' +
(currentRect.top - prevRect.top) + 'px, 0)';
target.offsetWidth; // repaint
target.style.transition = 'transform ' + ms + 'ms';
target.style.transform = 'translate3d(0, 0, 0)';
}
When I add the animation, then drag vertically, I get errors with a weird animation. Here's a gif explaining:
How can I make sure there isn't multiple logs of DOM is Changing for every change of the DOM?
JSFiddle
Here's the relevant code starting from line #392:
function drag(e) {
if (!_mirror) {
return;
}
e.preventDefault();
var clientX = getCoord('clientX', e);
var clientY = getCoord('clientY', e);
var x = clientX - _offsetX;
var y = clientY - _offsetY;
_mirror.style.transform = 'translate3d(' + x + 'px,' + (y - (_mirror.offsetHeight * 2)) + 'px, 0)';
var item = _copy || _item;
var elementBehindCursor = getElementBehindPoint(_mirror, clientX, clientY);
var dropTarget = findDropTarget(elementBehindCursor, clientX, clientY);
var changed = dropTarget !== null && dropTarget !== _lastDropTarget;
//if (item.style.transition === 'transform 5000ms') return;
if (changed || dropTarget === null) {
out();
_lastDropTarget = dropTarget;
over();
}
var parent = getParent(item);
if (dropTarget === _source && _copy && !o.copySortSource) {
if (parent) {
parent.removeChild(item);
}
return;
}
var reference;
var immediate = getImmediateChild(dropTarget, elementBehindCursor);
if (o.revertOnSpillParent === true && immediate === parent) {
immediate = null;
}
if (immediate !== null) {
reference = getReference(dropTarget, immediate, clientX, clientY);
}
else if (o.revertOnSpill === true && !_copy) {
reference = _initialSibling;
dropTarget = _source;
}
else {
if (_copy && parent) {
parent.removeChild(item);
}
return;
}
if (
(reference === null && changed) ||
reference !== item &&
reference !== nextEl(item)
) {
console.log('hello');
_currentSibling = reference;
// save the location of next sibling of immediate
var immediateSibling = immediate.nextSibling,
// Save location of swapped elements
itemRect = item.getBoundingClientRect(),
immediateRect = immediate.getBoundingClientRect();
parent.insertBefore(immediate, item);
parent.insertBefore(item, immediateSibling);
animate(immediate, immediateRect, itemRect);
animate(item, itemRect, immediateRect);
drake.emit('shadow', item, dropTarget, _source);
}
function moved(type) {
drake.emit(type, item, _lastDropTarget, _source);
}
function over() {
if (changed) {
moved('over');
}
}
function out() {
if (_lastDropTarget) {
moved('out');
}
}
function animate(target, currentRect, prevRect) {
var ms = 5000;
target.style.transition = 'none';
target.style.transform = 'translate3d(' + (currentRect.left - prevRect.left) + 'px,' +
(currentRect.top - prevRect.top) + 'px, 0)';
target.offsetWidth; // repaint
target.style.transition = 'transform ' + ms + 'ms';
target.style.transform = 'translate3d(0, 0, 0)';
}
}
I'm making an alcohol simulator, so when I press a button, you see an alcohol bottle being drained, but at the same time I should see the stomach filling. I have a code already for 'drinking', but I want to fix that if the water of the bottle moves 2 steps, that the water of the stomach only moves one step. I'll put just the js here, if you want the html as well, let me know.
var top_max = 475,
top_min = 400,
left_max = 200;
function move_img(str) {
var step = 1; // change this to different step value
var el = document.getElementById('i1');
var el2 = document.getElementById('i2');
if (str == 'up' || str == 'down') {
var top = el.offsetTop;
var height = el.offsetHeight;
console.log(height);
if (str == 'up') {
top -= step;
height += step;
} else {
top += step;
height -=step;
}
if (top_max >= top && top >= 110) {
document.getElementById('i1').style.top = top + "px";
document.getElementById('i1').style.height = height;
} else {
clearInterval(myVar)
}
} else if (str == 'left' || str == 'right') {
var left = el.offsetLeft;
if (str == 'left') {
left += step;
} else {
left -= step;
}
if (top_left < left && left >= 0) {
document.getElementById('i1').style.left = top + "px";
} else {
clearInterval(myVar)
}
}
}
function auto(str) {
myVar = setInterval(function () {
move_img(str);
}, 90);
}
function nana() {}
var myVar;
function handler() {
clearInterval(myVar);
auto(this.id);
}
function auto(str) {
myVar = setInterval(function(){ move_img(str); }, 2) ;
}
function stop(){
setTimeout(function( ) { clearInterval( myVar ); }, 1);
}
if(e.target.id == "cited"){
alert(e.target.innerHTML);
if (document.getElementById(e.target.id).innerHTML == "[1]") {
display = "sometext1";
}
else if (document.getElementById(e.target.id).innerHTML == "[2]") {
display = "sometext2";
}
else if (document.getElementById(e.target.id).innerHTML == "[3]") {
display = "sometext3";
}
Alright, well when I hover over my [3] it displays "sometext2" when it should be displaying "sometext3". [2] and [3] is on the same page.
I did add a quick debug in to see if it picking up the wrong innerHTML by doing:
alert(e.target.innerHTML);
it displays the right one when I hover over in the alert message, but I don't know why it is displaying the wrong toolTip. Any help here?
document.onmousemove = function(e)
{
// e.target, e.srcElement and e.toElement contains the element clicked.
var x = e.pageX;
var y = e.pageY;
var display;
if(e.target.id == "cited"){
// alert(e.target.innerHTML);
if (document.getElementById(e.target.id).innerHTML == "[1]") {
display = "sometext1";
}
else if (document.getElementById(e.target.id).innerHTML == "[2]") {
display = "sometext2";
}
else if (document.getElementById(e.target.id).innerHTML == "[3]") {
display = "sometext3";
}
document.getElementById("toolTip").style.top = y-50+"px";
document.getElementById("toolTip").style.left = x+"px";
document.getElementById("toolTip").style.visibility = "visible";
document.getElementById("toolTip").innerHTML = "<p>"+display+"</p>";
}
else {
document.getElementById("toolTip").style.visibility = "hidden";
}
One problem seems to be that you have multiple elements on the same page with the same id. From your code, it seems that you have at least three elements with id cited.
If you want to refer to more than one element, you should use classes.
Bad way of fixing it:
document.onmousemove = function (e) {
var x = e.pageX;
var y = e.pageY;
var display;
if (e.target.id == "cited") {
if (e.target.innerHTML == "[1]") {
display = "sometext1";
} else if (e.target.innerHTML == "[2]") {
display = "sometext2";
} else if (e.target.innerHTML == "[3]") {
display = "sometext3";
}
document.getElementById("toolTip").style.top = y - 50 + "px";
document.getElementById("toolTip").style.left = x + "px";
document.getElementById("toolTip").style.visibility = "visible";
document.getElementById("toolTip").innerHTML = "<p>" + display + "</p>";
} else {
document.getElementById("toolTip").style.visibility = "hidden";
}
}
A better way would be to add event listeners to all of the elements and change their ids to classes, but that gets clumsy, so here's a jQuery solution:
$('.cited').mousemove(function(e) {
$('#tooltip').css({
top: e.pageY - 50 + 'px',
left: e.pageX + 'px',
text: $(this).data('tooltip')
});
}).mouseleave(function() {
$('#tooltip').hide();
}).mouseenter(function() {
$('#tooltip').show();
});
You'd change the HTML to this:
<span class="cited" data-tooltip="This is the tooltip text">Foo</span>
<span class="cited" data-tooltip="This is the tooltip text">Bar</span>
I have the following script and am trying to add mouse enter and leave events on a slideshow such that when the mouse is over the image it won't switch to the next one, and once removed it continues.
I can get the slide to stop when the mouse is over but once the mouse is out the slideshow won't proceed.
I am unsure if these 2 lines are in the right place:
---> jQuery('#slider-holder').mouseenter(function(){MOUSE_IN = true;});
---> jQuery('#slider-holder').mouseleave(function(){MOUSE_IN = false;});
jQuery(function () {
jQuery('a').focus(function () {
this.blur();
});
SI.Files.stylizeAll();
slider.init();
});
---> var MOUSE_IN = false;
var slider = {
num: -1,
cur: 0,
cr: [],
al: null,
at: 10 * 1000, /* change 1000 to control speed*/
ar: true,
anim:'slide',
fade_speed:600,
init: function () {
if (!slider.data || !slider.data.length) return false;
var d = slider.data;
slider.num = d.length;
var pos = Math.floor(Math.random() * 1);
for (var i = 0; i < slider.num; i++) {
if(slider.anim == 'fade')
{
jQuery('#' + d[i].id).hide();
}
else{
jQuery('#' + d[i].id).css({
left: ((i - pos) * 1000)
});
}
jQuery('#slide-nav').append('<a id="slide-link-' + i + '" href="#" onclick="slider.slide(' + i + ');return false;" onfocus="this.blur();">' + (i + 1) + '</a>');
}
jQuery('img,div#slide-controls', jQuery('div#slide-holder')).fadeIn();
---> jQuery('#slider-holder').mouseenter(function(){MOUSE_IN = true;});
---> jQuery('#slider-holder').mouseleave(function(){MOUSE_IN = false;});
slider.text(d[pos]);
slider.on(pos);
if(slider.anim == 'fade')
{
slider.cur = -1;
slider.slide(0);
}
else{
slider.cur = pos;
window.setTimeout('slider.auto();', slider.at);
}
},
auto: function () {
if (!slider.ar) return false;
if(MOUSE_IN) return false;
var next = slider.cur + 1;
if (next >= slider.num) next = 0;
slider.slide(next);
},
slide: function (pos) {
if (pos < 0 || pos >= slider.num || pos == slider.cur) return;
window.clearTimeout(slider.al);
slider.al = window.setTimeout('slider.auto();', slider.at);
var d = slider.data;
if(slider.anim == 'fade')
{
for (var i = 0; i < slider.num; i++) {
if(i == slider.cur || i == pos) continue;
jQuery('#' + d[i].id).hide();
}
if(slider.cur != -1){
jQuery('#' + d[slider.cur].id).stop(false,true);
jQuery('#' + d[slider.cur].id).fadeOut(slider.fade_speed);
jQuery('#' + d[pos].id).fadeIn(slider.fade_speed);
}
else
{
jQuery('#' + d[pos].id).fadeIn(slider.fade_speed);
}
}
else
{
for (var i = 0; i < slider.num; i++)
jQuery('#' + d[i].id).stop().animate({
left: ((i - pos) * 1000)
},
1000, 'swing');
}
slider.on(pos);
slider.text(d[pos]);
slider.cur = pos;
},
on: function (pos) {
jQuery('#slide-nav a').removeClass('on');
jQuery('#slide-nav a#slide-link-' + pos).addClass('on');
},
text: function (di) {
slider.cr['a'] = di.client;
slider.cr['b'] = di.desc;
slider.ticker('#slide-client span', di.client, 0, 'a');
slider.ticker('#slide-desc', di.desc, 0, 'b');
},
ticker: function (el, text, pos, unique) {
if (slider.cr[unique] != text) return false;
ctext = text.substring(0, pos) + (pos % 2 ? '-' : '_');
jQuery(el).html(ctext);
if (pos == text.length) jQuery(el).html(text);
else window.setTimeout('slider.ticker("' + el + '","' + text + '",' + (pos + 1) + ',"' + unique + '");', 30);
}
};
if (!window.SI) {
var SI = {};
};
SI.Files = {
htmlClass: 'SI-FILES-STYLIZED',
fileClass: 'file',
wrapClass: 'cabinet',
fini: false,
able: false,
init: function () {
this.fini = true;
var ie = 0
if (window.opera || (ie && ie < 5.5) || !document.getElementsByTagName) {
return;
}
this.able = true;
var html = document.getElementsByTagName('html')[0];
html.className += (html.className != '' ? ' ' : '') + this.htmlClass;
},
stylize: function (elem) {
if (!this.fini) {
this.init();
};
if (!this.able) {
return;
};
elem.parentNode.file = elem;
elem.parentNode.onmousemove = function (e) {
if (typeof e == 'undefined') e = window.event;
if (typeof e.pageY == 'undefined' && typeof e.clientX == 'number' && document.documentElement) {
e.pageX = e.clientX + document.documentElement.scrollLeft;
e.pageY = e.clientY + document.documentElement.scrollTop;
};
var ox = oy = 0;
var elem = this;
if (elem.offsetParent) {
ox = elem.offsetLeft;
oy = elem.offsetTop;
while (elem = elem.offsetParent) {
ox += elem.offsetLeft;
oy += elem.offsetTop;
};
};
var x = e.pageX - ox;
var y = e.pageY - oy;
var w = this.file.offsetWidth;
var h = this.file.offsetHeight;
this.file.style.top = y - (h / 2) + 'px';
this.file.style.left = x - (w - 30) + 'px';
};
},
stylizeById: function (id) {
this.stylize(document.getElementById(id));
},
stylizeAll: function () {
if (!this.fini) {
this.init();
};
if (!this.able) {
return;
};
var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if (input.type == 'file' && input.className.indexOf(this.fileClass) != -1 && input.parentNode.className.indexOf(this.wrapClass) != -1) this.stylize(input);
};
}
};
(function (jQuery) {
jQuery.fn.pngFix = function (settings) {
settings = jQuery.extend({
blankgif: 'blank.gif'
},
settings);
var ie55 = (navigator.appName == 'Microsoft Internet Explorer' && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf('MSIE 5.5') != -1);
var ie6 = (navigator.appName == 'Microsoft Internet Explorer' && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf('MSIE 6.0') != -1);
if (jQuery.browser.msie && (ie55 || ie6)) {
jQuery(this).each(function () {
var bgIMG = jQuery(this).css('background-image');
if (bgIMG.indexOf(".png") != -1) {
var iebg = bgIMG.split('url("')[1].split('")')[0];
jQuery(this).css('background-image', 'none');
jQuery(this).get(0).runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + iebg + "',sizingMethod='" + settings.sizingMethod + "')";
}
});
}
return jQuery;
};
})(jQuery);
jQuery(function () {
if (jQuery.browser.msie && jQuery.browser.version < 7) {
}
});
The position of both lines is fine, they just add an event handler to the mouse in/out event. The problem you experience is actually in tha auto function, if you note, at the end of the init function you have:
window.setTimeout('slider.auto();', slider.at)
This line makes a call to the auto function after a slider.at time (which is 10 seconds in your example), the auto function checks if MOUSE_IN is set to true, if it's not, then calls the slide function, then in the slide function you have another call to the auto function:
slider.al = window.setTimeout('slider.auto();', slider.at);
But once you set the MOUSE_IN variable to true the auto function simply returns and it stop the execution of further slide functions, to solve this, you may want to either handle the MOUSE_IN logic in the slide function, or before returning false in the auto function, call with a time out the auto function again.
Thought this would work but it doesnt, the mouseleave eventdoesnt seem to fire.
jQuery('#slider-holder').mouseenter(function(){MOUSE_IN = true;});
jQuery('#slider-holder').mouseleave(function(){MOUSE_IN = false;});
while(MOUSE_IN==true)
{
jQuery('#slider-holder').mouseenter(function(){MOUSE_IN = true;});
jQuery('#slider-holder').mouseleave(function(){MOUSE_IN = false;});
}
So using a script for 360 image rotation, i've set up a tags to act as hot spots and lead to different pages within a jquery mobile document. Everything works a desktop, but when i test the page on an ipad, none of the links do anywhere. Heres the script for the rotation.
<script>
jQuery(document).ready(function ($) {
var $product = $('#product'),
$imgs = $product.find(".child"),
imageTotal = $imgs.length - 1,
clicked = false,
widthStep = 4,
currPos,
currImg = 0,
lastImg = 0;
$imgs.bind('mousedown', function (e) {
e.preventDefault(); // prevent dragging images
})
.filter(':gt(0)').addClass('notseen');
$product.bind('mousedown touchstart', function (e) {
if (e.type == "touchstart") {
currPos = window.event.touches[0].pageX;
} else {
currPos = e.pageX;
}
clicked = true;
return false;
});
$(document)
.bind('mouseup touchend', function () {
clicked = false;
})
.bind('mousemove touchmove', function (e) {
if (clicked) {
var pageX;
if (e.type == "touchmove") {
pageX = window.event.targetTouches[0].pageX;
} else {
pageX = e.pageX;
}
widthStep = 4;
if (Math.abs(currPos - pageX) >= widthStep) {
if (currPos - pageX >= widthStep) {
currImg++;
if (currImg > imageTotal) {
currImg = 0;
}
} else {
currImg--;
if (currImg < 1) {
currImg = imageTotal;
}
}
currPos = pageX;
$imgs.eq(lastImg).addClass('notseen');
$imgs.eq(currImg).removeClass('notseen');
lastImg = currImg;
// $obj.html('<img src="' + aImages[options.currImg] + '" />');
}
}
});
});
</script>
I'm know its the script because when i remove it, the links work. Any ideas?
jQuery(document).ready() is not supported in jQM.
http://view.jquerymobile.com/1.3.0/docs/faq/dom-ready-not-working.php