I am using hammer.js to make a basic touch friendly mobile site. I have hidden the top menu with a negative top position and it will appear using css3 transitions upon a double tap. However I want it to then hide again upon a second double tap.
I have tried using if/else to call the top position then re-set it accordingly but I cant get it to work, anyone know where I am going wrong?
var t = $("#topbar");
var position = t.position();
$sw.on('doubletap', function(event) {
event.preventDefault();
if (position.top == '-55px') {
$('#topbar').css("top", "0");
}
else {
$('#topbar').css("top", "-55px")
}
});
The site address is http://www.bettondesignwork.co.uk/tim/mobile
Thanks
You can try this:
var t = $("#topbar");
var position = t.offset();
$sw.on('doubletap', function(event) {
event.preventDefault();
if (position.top == '-55px') {
$("#topbar").offset({ top: "0"});
}
else {
$('#topbar').offset({ top: "-55px"});
}
}
The problem could be this line
if (position.top == '-55px')
If i'm not mistaken, the .top property is numeric, so u could change the code to
if (position.top == -55)
Or become more defensive
if (position.top < 0)
Gets top position of one HTMLElement
function getHTMLElementTop(thisNode, Top)
{
if (Top == undefined)
{
var Top = 0;
}
if (thisNode.nodeType == 1)
{
Top += thisNode.offsetTop;
//if (thisNode.parentNode)
if (thisNode.offsetParent)
{
Top = getHTMLElementTop(thisNode.offsetParent, Top);
}
}
return Top;
}
May be it helps
Related
I'm looking for ideas to hide a div when it reaches another div and show it again when it passes the same div. There can also be multiple divs to pass. Something like:
var bottom = $('.out-of-grid-images')
$(window).scroll(function(){
if ($(this).scrollTop() > bottom){
$('.share-icons').fadeOut(200); // hide share icons when reached and overlaps
}
else if ($(this).scrollTop() < bottom){ {
$('.share-icons').fadeIn(200); // show icons when passed element
}
});
I can not produce a jsFiddle because I haven't found anything similar to work with. Any ideas?
EDIT:
The share icons are a fixed position element. The elements reached are dynamic and not fixed from top of the page (they are post content images out of the grid)
EDIT: here's an image to illustrate the matter
What you'll want to do is have an Array of divs that you want to trigger the hiding effect, then calculate their bounding rectangle, and then perform collision detection on them.
Here is a very rough example - you'll have to fix the showing and hiding, as this will cause a fadeIn/fadeOut on each scroll event.
const shareIcons = $('.share-icons');
const divs = $('.trigger-div');
const rects = [];
divs.each(function () {
rects.push(this.getBoundingClientRect());
});
$(window).scroll(function () {
let interectsAny = false;
rects.forEach(function (rect) {
if (intersectRect(rect, shareIcons[0].getBoundingClientRect())) {
interectsAny = true;
}
});
if (interectsAny) {
shareIcons.fadeOut(200);
} else {
shareIcons.fadeIn(200);
}
});
// https://stackoverflow.com/questions/2752349/fast-rectangle-to-rectangle-intersection
function intersectRect(r1, r2) {
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
I am working on a bootstrap based website and I have the following case :
A main container and a floating left navigation menu.
The floating left navigation menu, is set to position fixed, because it is following the user scroll.
What I would like is when the end user resize the window, and when the main content meets the left menu (overlap), the left menu becomes hidden, and when there is enough space the left menu comes back.
Actually, it is not really working, it is blinking. I have written a little bit of jquery binded to the resize function.
Here is the jsfiddle :
https://jsfiddle.net/cuw46rsv/5/
function getDiffLeftMenu(div1, div2) {
var value = ($(div1).offset().left - $(div2).offset().left);
console.log(value - $(div2).width());
if(value - $(div2).width() < 0){
return true;
}
}
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
$('#sectionsMenu').hide();
}
else {
$('#sectionsMenu').show();
}
}).resize();
Is this possible to not have this blinking effet ?
Thanks a lot for any help.
Regards.
Here's the solution with your logic, .hide() method causes it to have offset 0 and that's why it's blinking (it can get stuck as hidden all the time).
https://jsfiddle.net/cuw46rsv/7/
function getDiffLeftMenu(div1, div2) {
var value = ($(div1).offset().left - $(div2).offset().left);
console.log(value - $(div2).width());
if(value - $(div2).width() < 0){
return true;
}
}
By using opacity offset will stay there.
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
$('#sectionsMenu').css('opacity', 0);
}
else {
$('#sectionsMenu').css('opacity', 1);
}
}).resize();
well you are doing it wrong, but you can solve it like this (as a workaround):
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
setTimeout(function(){$('#sectionsMenu').hide();},20);
}
else {
$('#sectionsMenu').show();
}
}).resize();
https://jsfiddle.net/cuw46rsv/6/
I have a div called #menu which I want to display when I scroll past the element #section3, if I scroll up past that element again, I want #menu to disappear
How would I code this?
Maybe something like this?
scrolled = "no"
$(window).scroll(function(){
scr = $("body").scrollTop();
if (scr > 100 && scrolled == "no"){
$("#menu").css({"display:block"})
displayed = "yes"
}
if (displayed == "yes" && scrolled = "yes"){
$("#menu").css({"display:none"})
}
});
The above assumes that #section3 is 100 pixels down the page. If you do not know where its going to be on the page then you could use the method outlined here:
Trigger event when user scroll to specific element - with jQuery
With jQuery you can get the scroll position with $("body").scrollTop();.
Expanding on what #Ned Hulton said, I recommend comparing the scroll position to the top of a "container element" (or 'row') in your page like this:
if ($('body').scrollTop() > $('#someRow').offset().top){
//do something
}
That way you can account for your container appearing at a variable distance down the page (which will come in handy for mobile browsing or cases where your text wraps to additional lines)
I just whipped this up in jsfiddle
https://jsfiddle.net/rb56j0yu/
it uses jQuery, and checks the scroll position against the target div. Css sets the menu as position: fixed, and defaults to hidden.
$(window).scroll(function(){
var yPos = $("body").scrollTop();
var yCheck = $("#c3").position().top;
if (yPos > yCheck && !$("#menu").is(":visible"))
{
$("#menu").show();
}
if (yPos <= yCheck && $("#menu").is(":visible"))
{
$("#menu").hide();
}
});
First, get your #section3 top offset and height. Which will be used as the threshold whether #section3 is actually on the window screen.
var top = $('#section3').offset().top;
var bot = topOffset + $('#section3').height();
Then, detect it on your scroll event.
$(window).on('scroll', function () {
var scrollTop = $(window).scrollTop();
if (scrollTop >= top && scrollTop <= bot) {
// #section3 is within the screen.
$('#menu').show();
}
else {
// #section3 is out of screen.
$('#menu').hide();
}
});
This is a common use case, I wrote following code:
// what does "Auto Header" mean, goto https://www.yahoo.com/
// scroll down and you will see the purple part auto fixed to top,
// while when scroll up, it restores and does not be fixed.
// 1. multiple auto header elements handled
// 2. dynamically create/remove elements issue handled
// 3. no unnecessary dom operation, high performance
// usage: just add 'class="auto-header"' to any element you want to auto header
// suggest set each auto-header element specific width and height
// do not guarantee it works when resize or scroll left/right
$(document).ready(function() {
var rawTops = [],
rawLefts = [],
rawStyles = [],
$locations = [], // record next sibling so that element easily find where to restore
fixed = []; // mark whether this element is fixed
$(".auto-header").each(function() {
var $this = $(this),
offset = $this.offset();
rawTops.push(offset.top);
rawLefts.push(offset.left);
rawStyles.push($this.attr("style"));
$locations.push($this.siblings().eq($this.index()));
fixed.push(false);
});
$(window).on("scroll", function() {
$(".auto-header").each(function(i, e) {
if(!fixed[i] && $(window).scrollTop() > rawTops[i]) {
var $te = $(this).clone(true);
$(this).remove();
$locations[i].before($te);
$te.css({
"position": "fixed",
"top": 0,
"left": rawLefts[i],
"z-index": 100
});
fixed[i] = true;
} else if(fixed[i] && $(window).scrollTop() < rawTops[i]) {
$(this).removeAttr("style").attr("style", rawStyles[i]);
fixed[i] = false;
}
});
});
});
I need to compare the scroll position with and element position (relative to window top) and when both have the same value, do something (this case console.log("we are the same")).
I've tried the following code, but it's not working. I added an image to explain better.
if ($('.contenedorbusiness figure').length) {
$(document).scroll(function(event) {
var alto_total = $(this).scrollTop();
var loader_business = $('.loader_business').offset().top;
if (alto_total == loader_business.top) {
console.log(alto_total + " == " + parseInt(loader_business));
}
});
}
What I want is:
Change this: alto_total == loader_business.top to this: alto_total == loader_business
.top is what's stored in the variable, so there's no need to do it in the comparison.
DEMO
I took out your initial if statement, so make sure the code inside is running. You will also notice you can't scroll fast. If you scroll past it without pausing, the alert won't trigger.
The following is safer. The == can miss the mark.
$(document).on("scroll", function (event) {
var alto_total = $(this).scrollTop();
var loader_business = $('div').offset();
console.log(alto_total + " == " + loader_business.top);
if (alto_total >= loader_business.top) {
alert('tomalo');
$(document).off("scroll");
}
});
Fiddle
I have a function that gets called when a user scrolls to check for scrollTop() and after a certain scroll happens it changes the menu's z-index from -1 to 1. However this only occurs on a scroll so if the user refreshes the site the menu is virtually unusable until the next scroll occurs.
Is there a way for me to call this and check if the amount of screen scrolled (after the refresh not a user scroll) meets the criteria change the z-index?
My JS:
function getPosition(){
var y = $(window).scrollTop();
var status = (y > 880) ? true : false;
//console.log(status);
if(status)
$('#actual-menu').css('z-index', 1);
else
$('#actual-menu').css('z-index', -1);
}
z-index property has no effect on non-positioned elements, the element must be either relatively positioned ,absolutely positioned, or fixed.Replace your line with this:
Try adding this first ,
$("#actual-menu").css('position', 'relative');
$('#actual-menu').css('z-index', 1);
Just run getPosition inside of your ready event.
Functioning Example
var limit = 50;
$(function () {
function getPosition() {
var y = $(window).scrollTop();
var status = (y > limit) ? true : false;
if (status) {
$('#actual-menu').css('zIndex', 1);
} else {
$('#actual-menu').css('zIndex', -1);
}
}
$(document).on('scroll', getPosition);
getPosition();
});