I get a really interesting glitch in both Safari and Firefox with the following JSFiddle:
http://jsfiddle.net/68gcy2gp/
You have to click on the red box to toggle the blue overlay.
I have two left floated relative positioned li elements with a width of 32% plus 1% right margin. I then put a div element positioned absolute with top/left 0 over the li element. The width of this div will be set to the same width the 32% li has (via jQuery).
On certain screen widths I get then a 1px glitch (too long or too short). Like this screenshot shows it:
How can I prevent this glitch?
Okay, as an official answer:
jQuery .width() or .innerWidth() is rounding the width of subpixel to the next integer value either with floor or ceil, depending on the value. To avoid that you can use some raw javascript:
$('.person').each(function() {
var front = $(this).find('.front');
var back = $(this).find('.back');
var link = $('');
link.on('click', function() {
var width = $(front)[0].getBoundingClientRect().width;
back.innerWidth(width);
back.toggle();
});
$(this).wrap(link);
back.hide();
});
The following function is for checking pixel errors by resizing the window with active overlay:
$(window).resize(function() {
$('li').each(function() {
var back = $(this).find('.back');
var width = $(this)[0].getBoundingClientRect().width;
back.width(width);
});
});
If you use .innerWidth() instead of getBoundingClientRect() you will see the error you have stated.
Related
I have a fixed header div with a 200px height. On scroll, the height is reduced until it reaches a certain height (40px). This gives the effect of the header turning into a fixed header once user reaches the content container.
This works smooth in Firefox and Chrome, however, Safari is glitchy. Particularly, when user scrolls back up and the header increases in height. See JS Fiddle here.
$(window).scroll(function () {
var $scrollTop = $(window).scrollTop(),
$element = $('.content-container').offset().top,
$distance = ($element - $scrollTop);
if ($scrollTop < $element - $newHeight) {
header.height($distance);
}
});
What is causing safari to glitch so much on the height increase? What can I do to smooth this out?
The way to smoothen out this effect in Safari is to change the approach all together. Instead of changing the height of the header on scroll, make the content container position:relative; and set a higher z-index. Then when scroll reaches the bottom of your header (or wherever point you'd like to make the header sticky), change the z-index of the header to be higher than the content container and set it's height to your desired size.
Here is the JS. Please see this JS Fiddle for demo and the rest of code (css, html).
$(window).scroll(function () {
if ($scrollTop > $element - $newHeight) {
header.height($newHeight).css("z-index", 1000);
}
else {
header.css("z-index", 100).height($oldHeight);
}
});
Also, consider using requestAnimationFrame instead of onScroll. It''ll be lighter weight.
I am creating a site in which there are a number of fixed background images that you scroll past. Associated with each fixed background is an image slider (or text) that is hidden until the title is clicked on. These items are all fixed positioned.
I was able to make this work by using z-index to place items in order top to bottom/first to last and then have each disappear in turn using:
$(document).scroll(function() {
$('#porttitle').toggle($(this).scrollTop() < 225);
});
However, I am unable to use this because the length pixel distance down on the page changes based on the screen size. I am pretty new to Jquery but wanted to try to use .offset .top to have the item disappear not based on the pixel length to the top of the page but instead when an element appears on the screen. This is what I have so far but it isn't seeming to work.
$(document).scroll(function() {
$('#porttitle').toggle($(this).scrollTop() < $(‘article.post-100’).offset().top);
});
Here is the link to the site: http://s416809079.onlinehome.us (not final location - just developing)
Any thoughts?
Thanks!
I think this may work for you, read the comments on the code for a line by line explanation.
Working Example
$(window).scroll(function () { // When the user scrolls
$('div').each(function () { // check each div
if ($(window).scrollTop() < $(this).offset().top) { // if the window has been scrolled beyond the top of the div
$(this).css('opacity', '1'); //change the opacity to 1
} else { // if not
$(this).css('opacity', '0'); // change the opacity to 0
}
});
});
I'm conditionally changing the opacity rather than using toggle because:
...jQuery does not support getting the offset coordinates of hidden
elements or accounting for borders, margins, or padding set on the
body element.
While it is possible to get the coordinates of elements with
visibility:hidden set, display:none is excluded from the rendering
tree and thus has a position that is undefined.
Related documentation:
.offset()
.each()
.scroll()
.scrollTop()
There are some elements that have class='snap'
I want to find these elements in the body. Then snap and resize elements to fit grids by Jquery.
When?
The document is ready.
The window is resized.
Note:
Size of grid cells are 10px
Contents of elements can be different.
Element can move down maximum in 1 cell size. (Up is not allowed).
Because of responsive elements, It's not true to snap the element by specifying width and height.
See on JsFiddle
Any ideas or help would be greatly appreciated.
JsFiddle updated: Removed width of .content in CSS, It can be not specified.
What you could do, and this is just an idea that is perfectible, is getting the offset of the .snap div and remove all margins. Then you snap to the next (right and bellow) lines :
var Content = {
snapElement: function(element){
offset = element.offset();
element.css('left', (Math.ceil(offset.left/10)*10)+'px');
element.css('top', (Math.ceil(offset.top/10)*10)+'px');
element.css('margin', '0');
},
snapElements: function(){
var elements = $("body").find(".snap");
elements.each(function(){
Content.snapElement($(this));
});
}
}
You will also have to make your .snap divs relative :
.snap {position:relative;}
The demo
You can also keep the margins but you will have to subtract them to the left and top.
Edit : A more sophisticated demo that handle width
I'm positioning my elements using JavaScript. In order to do it perfectly I have to get the amount of horizontal space available. Badly, $(window).width() does not take in account the scrollbar width. The result is this:
bad http://dl.dropbox.com/u/62862049/Screenshots/fb.png
Here, "Pagina 1" is contained in a small div that was supposed to align with the right border of the window. Well, it does - literally - ignoring the scrollbar, which covers part of the div, throwing the "1" of "Página 1" to the next line.
use this function
function scrollbar_width() {
var calculation_content = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
jQuery('body').append(calculation_content);
var width_one = jQuery('div', calculation_content).innerWidth();
calculation_content.css('overflow-y', 'scroll');
var width_two = jQuery('div', calculation_content).innerWidth();
jQuery(calculation_content).remove();
return (width_one - width_two);
}
now calculate available with
var availableWidth = $(window).width() - scrollbar_width();
This is similar to two previous questions:
how to get innerWidth of an element in jquery WITHOUT scrollbar
and
How to get screen width without (minus) scrollbar?
I'm writing a simple tooltip that can hold HTML tags. Please check http://jsfiddle.net/Qkwm8/ for the demo.
I want the tooltip box to show properly regardless of the position of element, in this case <a>, that shows tooltips on mouseover event.
The tooltips are shown fine except when <a> floats right (or is at the end of the line) or at the bottom of the screen where it doesn't show properly, it appears off the screen
If the <a> floats right, or at the end of the line, or is at the bottom of the screen, I want the tooltip to change position so it remains visible
Thank you.
Update demo link
here's the complete result: http://jsfiddle.net/Qkwm8/3/
You can use the document width to check how wide the html document is and adjust the left position accordingly. Say:
//set the left position
var left = $(this).offset().left + 10;
if(left + 200 > $(document).width()){
left = $(document).width() - 200;
}
I used 200 here because you are setting your tooltip to 200px wide. Something similar can be done with height.
There is also a window width but I always get confused about the difference so you should check which one gives you better results.
An example of the bottom of the page is:
//set the height, top position
var height = $(this).height();
var top = $(this).offset().top;
if(top + 200 > $(window).height()){
top = $(window).height() - 200 - height;
}
Again, using 200 since you are setting your tooltip to 200px height.
$('a.show-tooltips').mouseover(function() {
if(($(this).parent()).css('float')) =="right") add the proper class to left
else -> the proper class the right
....
}