Jquery calc math not working properly in small device - javascript

I'm making a header with a responsive img in the middle. I want to calculate 2 divs.
1 on top of img;
1 at bottom of img;
The calc is ok, except in small devices.
On the first load of the page, this is how it is: http://i.imgur.com/hdJnIId.png
If i reload the page, this is what happens: http://i.imgur.com/pY6GkpN.png
It's happening only in screen smaller than 440px
This is the Jquery i'm using:
$(document).ready(function() {
$(window).resize(function() {
getWidthAndHeight();
});
$(window).load(function() {
getWidthAndHeight();
});
});
function getWidthAndHeight (){
var full = $('.header-main').outerHeight (),
hImg = $('.hd-m-m').height (),
x = hImg,
y = full - x,
c1 = y * 0.3,
c2 = (y * 0.7) + 5,
ct = c1 + c2 + x; //used only to confirm the result - console.log
$('.hd-m-t').css({'height': c1});
$('.hd-m-b').css({'height': c2});
}
Ps.: I have the ' +5 ' because i'm using a margin-top: -5px to cover a small blank area after the img.
And this is my HTML
<header id="home" class="full"><!-- home -->
<div class="header-bg"></div><!-- background images -->
<div class="header-main">
<div class="hd-s"></div> <!-- div on left side -->
<div class="hd-m">
<div class="hd-m-t"></div> <!-- top div - needs calc -->
<div class="hd-m-m"> <!-- middle div -->
<img src="img/home/home-logo.png" />
</div>
<div class="hd-m-b"> <!-- bottom div - needs calc -->
<h2>main text</h2>
<h2>sub text</h2>
</div>
</div>
<div class="hd-s"></div> <!-- div on right side -->
</div><!-- transparent logo -->
</header>
This is the final result i'm looking for: http://i.imgur.com/vnS3BGb.png
I want to this way, because the background img will have a parallax effect and i want it to appear only trought the logo transparency.
Can anyone help me?

Ok, so, after some time, i didn't found anything to solve this problem but this 'fix'.
I don't know if it's the best way or not, but here we go:
I changed the $(document).ready part, so now it execute the function after everything is loaded (including img's). This solved the extra margin at the bottom.
$(document).ready(function() {
$(window).load(function() {
getWidthAndHeight();
});
$(window).resize(function() {
getWidthAndHeight();
});
});
Since the missing background at the bottom only happens in screen smaller than 440px, i added a if condition to the function with an extra calc. The missin background was always the same height. But i also moved the function inside the $(document).ready this is the final code:
$(document).ready(function() {
$(window).load(function() {
getWidthAndHeight();
});
$(window).resize(function() {
getWidthAndHeight();
});
function getWidthAndHeight (){
var full = $('.header-main').outerHeight (),
hImg = $('.hd-m-m').height (),
x = hImg,
y = full - x,
c1 = y * 0.3,
c2 = (y * 0.7) + 5,
c3 = c2 + 17,
ct = c1 + c2 + x;
$('.hd-m-t').css({'height': c1});
if ($(window).width() < 440) {
$('.hd-m-b').css({'height': c3});
} else {
$('.hd-m-b').css({'height': c2});
};
}
});
If anyone knows a better answer, i'll appreciate that. =D
Thanks #SableFost you gave me some good tips (even to learn extra things).

Related

JQuery animation stops mid-div on double click

I created a sliding list of divs using the following code :
<div class="row">
<img class="back-arrow">
<div class="hide-extra">
<div class="tile-container">
<div class="tile"></div>
<!-- More Divs -->
</div>
</div>
<img class="next-arrow">
</div>
The overflow is supposed to stay hidden and the divs slide to show the next/ previous divs when the corresponding arrows are clicked. Here's a simplified version of my code to move forward a tile:
function nextTile() {
var tileWidth = /*Width of each div*/;
var position = parseInt($(".tile").css("right"));
position += tileWidth;
var rightPosition = position + "px";
$(".tile").animate({right:rightPosition}); //in my code each of the divs in the row move position
}
}
The code works fine except that if I press too rapidly on the arrows the divs will not slide the appropriate length. Instead they slide part way and leave me stuck with a div half visible.
I made the following addition to my code using Malk's comment and his attached link: jQuery animation detect if animating?
function nextTile() {
var tileWidth = /*Width of each div*/;
var position = parseInt($(".tile").css("right"));
position += tileWidth;
var rightPosition = position + "px";
var tileLock = $(".tile").is(':animated'); // new code
if (tileLock === false) // new code
$(".tile").animate({right:rightPosition});
}

How to stop position fixed before footer?

I have a floating box and I'd like to know how I can stop it from overlapping the footer div by stopping it on the main div where it is only allowed to go.
window.onload = function ()
{
var scrolledElement = document.getElementById('scrolling_box');
var top = scrolledElement.offsetTop;
var listener = function ()
{
var y = scrolledElement.scrollTop || scrolledElement.scrollTop || window.pageYOffset;
if (y >= top-25)
{
scrolledElement.classList.add('fixed');
} else {
scrolledElement.classList.remove('fixed');
}
};
window.addEventListener('scroll', listener, false);
}
I'd like for it to stop at the main div, that is as followed:
<div class="outer">
<div class="main">
<div class="left">
</div>
<div class="right">
<div class="scrolling_box">
the box that is scrolled goes right here
</div>
</div>
</div>
<div id="footer">
Footer goes here
</div>
</div>
I'd like it to be stopped at the main class, I have looked a lot of other tutorials and none that I could port it to plain javascript. I tried including the .stop() but it wound up being only for jQuery sadly. I could not replicated the issue in jsfiddle, sadly.
I tried using float:both, left and right but neither seemed to have worked at all.
Almost Solved Check for Demo
$(window).scroll(function(){
var pos = $('#footer').offset();
var top = pos.top;
var pos1 = $('#scrolling_boxI').offset();
var top1 = pos1.top
//alert(top);
if( $(window).scrollTop()<top-150-top1)
{
$("#scrolling_boxI").stop().animate({"marginTop": ($(window).scrollTop()) + "px", "marginLeft":($(window).scrollLeft()) + "px"}, "slow" );
}
});

Responsive Javascript Image Slider, managing state change

I have a responsive site that has an image slider that the user can look through.
Here is the link to that slider:
http://firehousecoffeeco.com
I was able to get the slideshow to return to the first slide when they click the "right" button on the last slide, without the right edge of the last slide ever coming too far into the window. This is done by checking the viewport width against the container div's width (see the left button's click handler below).
My question is: How do I make it so that the same thing that is happening with the last slide happens with the first slide. (no matter what, I never want the container's left edge to go above 0px). I tried to do the same with the first slide as with the last, but it didnt' work, please see below:
Here is the markup of the slider:
<section id="photoGallery">
<div id="slides">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
<!--left and right buttons-->
<div id="left" data-dir="left"></div>
<div id="right" data-dir="right"></div>
</section>
The container div is "slides" and it is what is being moved.
Here is my script's click handlers and transition function:
//click handlers
leftButton.on('click', function(){
var viewport = $(window).width();
var slidesContainerLeftEdge = $('#slides').get(0).getBoundingClientRect().left;
var slidesContainer = $('#slides').width();
if (slidesContainerLeftEdge == 0) { //if on first image (this is not working, help!)
slides.animate({marginLeft: ""+-(slideShowLimiter * 320)+"px"}, 200);
console.log("working");
} else {
transition("+=");
}
});
rightButton.on('click', function(){
var viewport = $(window).width();
var slidesContainerEdge = $('#slides').get(0).getBoundingClientRect().right;
var slidesContainer = $('#slides').width();
if (slidesContainerEdge < viewport + 320) { //if last slide
slides.animate({marginLeft:"0px"}, 200);
} else {
transition("-=");
}
});
function transition(direction) {
slides.animate({marginLeft: ""+direction+""+movement+"px"}, 200);
}
Hopefully you guys can help me out of a jam. Thanks in advance!
if(0 >=slidesContainerLeftEdge > -320){ // if first slide
slides.animate({marginLeft: ($(window).width()-$('#slides').width())+"px"}, 200);
}else{
//...
}
Just to follow the logic here you used for the rightClick, so when it's the first slide on the left, you'll move the slides to the left (by setting the margin-left) so its right matches the right of the window.
See Full Code:
leftButton.on('click', function(){
var viewport = $(window).width();
var slidesContainerLeftEdge = $('#slides').get(0).getBoundingClientRect().left;
var slidesContainer = $('#slides').width();
if (0 >=slidesContainerLeftEdge > -320) {
slides.animate({marginLeft: (viewport-slidesContainer)+"px"}, 200);
} else {
transition("+=");
}
});

CSS/JS Dynamic Width & Font Size

I have a client site with a navigation feature that has been very tightly designed (and not by me):
It consists of an unordered list, with three DIVs in each list item:
<ul id="application-tabs">
<li>
<div class="cv-home-applications-slideshow-tab-first"></div>
<div class="cv-home-applications-slideshow-tab"><h4>Coffee</h4></div>
<div class="cv-home-applications-slideshow-tab-right"></div>
</li>
<li>
<div class="cv-home-applications-slideshow-tab-left"></div>
<div class="cv-home-applications-slideshow-tab"><h4>Pet Food</h4></div>
<div class="cv-home-applications-slideshow-tab-right"></div>
</li>
</ul>
The content is in the center DIV, while the first/left and right DIVs create the angled tab buttons.
This client has also requested a Google Translate utility up at the top of the page.
My problem is that I need the navigation element to always fill that space from end to end. If the translation produces a shorter word – such as "Cafe" instead of "Coffee" – I need it to expand accordingly.
Likewise, if it results in a longer word, like "Cerveza," I'll need the font size to reduce.
I'm sure I'll need to employ some javascript, in combination with the CSS, but I'm not entirely sure where to start. Any assistance would be appreciated.
Thanks,
ty
here is a fiddle of a solution, it automatically spaces the menu to fit http://jsfiddle.net/nFRjc/
var $j = jQuery.noConflict();
$j(document).ready(function () {
var containerWidth = $j('#application-tabs').width();
var linksWidth = 0;
$j('#application-tabs li div + div').children().each(function () {
linksWidth += $j(this).width();
});
var linkSpacing = Math.floor((containerWidth - linksWidth) / ($j('#application-tabs').children('li').length));
$j('#application-tabs').children().not(':last-child').css('margin-right', linkSpacing + "px");
});​
Ok simple solution to make the font reduce in size if it's too large. See this fiddle, the links font size are 100px, but the script reduces them until they fit. http://jsfiddle.net/nFRjc/2/ I just added a loop that checks whether or not the total width of the individual links is greater than the container width, and reduces the font size by 1 if true.
var $j = jQuery.noConflict();
$j(document).ready(function () {
var containerWidth = $j('#application-tabs').width();
var linksWidth = 0;
$j('#application-tabs li div + div').children().each(function () {
linksWidth += $j(this).width();
});
while (linksWidth >= (containerWidth - 100)) {
$j('#application-tabs li div + div h4').css({'font-size': '-=1'});
var linksWidth = 0;
$j('#application-tabs li div + div').children().each(function () {
linksWidth += $j(this).width();
});
}
var linkSpacing = Math.floor((containerWidth - linksWidth) / ($j('#application-tabs').children('li').length));
$j('#application-tabs').children().not(':last-child').css('margin-right', linkSpacing + "px");
});​

Smoother fixed float

I have created a spirit level for my new site.
I used the fixed float idea but tried to limit it to the realm of the tube. It's not perfect but it's aided by the shortness of the page.
How could I make it smoother (particularly when scrolling slowly)?
Also, when I scroll with my iPhone, it works but only after I finish scrolling and not as I'm scrolling. Is this just a limitation of the iPhone's scrolling mechanism or is there a way around that?
The HTML:
<div id="spirit_level">
<div id="shimmery"></div> <!-- just for y gradient -->
<div id="shimmerx"></div> <!-- just for x gradient -->
<div id="bumps"></div> <!-- just for another overlay -->
<div id="tube">
<div id="bubble"></div>
<div id="overside"></div> <!-- glass + line markings -->
</div>
</div>
<div id="spirit_shadow"></div>
The CSS:
The spirit level is placed using fixed positioning, and everything inside is positioned absolutely (relative to the spirit level).
The Javascript:
/* START: init spirit_level/bubble */
var bubble_h = 53, tube_h = 242,
doc_h = parseInt($(document).height()),
viewport_h = parseInt($(window).height()),
scrollDepth = $(document).scrollTop(),
orig_scrollDepth = scrollDepth,
tube_top = viewport_h/2 - tube_h/2,
center = 0;
/*center the tube and bubble:
$('#tube').css('top', tube_top+'px')
.addClass('bubble_prep');
placeBubble(1);
/* END: init spirit_level/bubble */
$(window).unbind("scroll").scroll(function () {
placeBubble(0);
})
The placeBubble() function:
function placeBubble(first_time)
{
scrollDepth = $(document).scrollTop();
if(first_time)
{
$('#bubble').css('top', center + 'px');
}
temp = ((center - (scrollDepth - orig_scrollDepth))/viewport_h)*100;
$('#bubble').css('top', (temp<-50?-50:(temp>50?50:temp)) +'%')
.animate(
{top: (center/viewport_h)*100+'%'},
{duration:800,queue:false},
{
step: function(now, fx) {
//this is never called, don't know why
alert(now);
}
}, function(){
/*
Should I do the following?
orig_scrollDepth = $(document).scrollTop();*/
});
/*Without the next line, the bubble slides down from the top of the
tube on any length scroll in any direction*/
orig_scrollDepth = $(document).scrollTop();
}
}
Edit:
Wow, I just checked with a Samsung Galaxy S1 (standard web browser). The z-indexing and absolute positioning of the measuring tape are disastrously failing. Why is this?
Maybe your use of .css is making it jumpy? .animate could be a suitable replacement, with a very fast setting so that it smoothly glides to the temporary starting position, then slowly glides back to the center afterward.
$('#bubble').animate({'top': (temp<-50?-50:(temp>50?50:temp)) +'%'},{duration:200})
.animate( [...]

Categories

Resources