Can't set exact div width as other div, script - javascript

I have responsive navigation menu and item blocks. Item blocks automatically adjusts their width as screen resolution changes(this is great). But navigation menu is in different section of page markup and don't receive the same width values as item blocks.
My goal: When resolution changes - script checks width of item block and then changes width of navigation menu to the same value.
So far I have:
$(document).ready(function(){
$( window ).resize(function() {
Resized();
});
});
function Resized()
{
var block_width= $(".block_item").width();
var width_to_set = parseInt(block_width);
$(".header-navi-inner").css({
'width': (width_to_set + 'px')
});
};
When I resize I can see that script executes and navigation menu changes width, but the width is not exactly the same as item block has. It is very close but it is wider for about 1px-5px based on what resolution is set.
For example:
When I looked in to CSS of these elements I found that item block has such styling:
float: left;
border-radius: 2px;
margin: 2px .25%;
position: relative;
width: 49.5%;
line-height: 0.8;
I believe margin .25% is causing issues because margin percentage value is calculated based on parent node. So when resolution changes parent node changes its size and also margin. That is why 1-5px difference occurs to my script?!
Is it true? How can I get exact width of element without any other added pixels?
What I have also tried:
$(".item").innerWidth();
$(".item").outerWidth(true);
But results were the same.
What I have also tried 2 (UPDATE):
I also tried to calculate margin value and then subtract it from width_to_set value:
var parent_node = $(".twelve").width();
var margin= (main_slaider * 0.0025);
var width_to_set = parseInt(column_width) - margin;
But still navigation menu was wider than item blocks for 1-3px
Thanks in advance for any help.

Related

Prevent browser viewport from sticking to bottom when page height increases in runtime?

Modern browsers seem to have a feature where the viewport sticks to bottom when page height increases. What actually happens is that browser scrolls the viewport at the same rate as height being increased when initial position is at (or very close to) the bottom of the page. This results in appearance as if page is expanding upwards instead of downwards.
How can this feature be disabled for a certain page using CSS or JS, so that the page would always visually expand downwards?
This of course, also happens when added element's height is expanded animated. For this reason, if possible, I would want to avoid resetting scroll position afterwards to prevent visible jump. The demo of this "feature" (that seems to happen only within rare conditions) interacting with the viewport and drop animation can be observed in the gif below.
I know there must be a way, otherwise every site with infinite scroll would suffer from an infinite loop. Counter argument: Chrome appears not to do this for containers that surpass certain height limit. So maybe infinite-scroll sites don't even bother addressing this in their sites.
Check this fiddle. You can observe that in Chrome, the first container snaps to the bottom, while the other divs has a scroll relative to the top. In Firefox or IE 11, you cannot observe this behavior.
This happens when the top bound of the last element on a scroll container is above the top bound of the container. The browser decides that the last element is what the user is interested in and decides to stay in that position.
The last div doesn't snap to the bottom because the scroll happens relative to the top bound of the last element and the last element is growing.
If you want a different behavior, I would not suggest handling it with Javascript, but I would suggest changing your layout considering these rules. For example the last div should be the growing one, instead of the previous siblings of it.
Obligatory code:
var div = document.querySelectorAll('.growing');
var height = 500;
setInterval(function(){
height += 100;
div[0].style.height = height + 'px';
div[1].style.height = height + 'px';
div[2].style.height = height + 'px';
},1000);
.start, .end{
height: 110px;
}
.start{
background: red;
}
.end{
background: green;
}
.growing{
background: yellow;
}
.cnt1,.cnt2,.cnt3{
overflow: auto;
border: 5px solid black;
margin: 5px 0;
scroll-snap-type: mandatory;
}
.cnt1{
height: 100px;
}
.cnt2{
height: 120px;
}
.cnt3{
height: 100px;
}
<div class="cnt1">
<div class="start"></div>
<div class="growing"></div>
<div class="end"></div>
</div>
<div class="cnt2">
<div class="start"></div>
<div class="growing"></div>
<div class="end"></div>
</div>
<div class="cnt3">
<div class="start"></div>
<div class="end"></div>
<div class="growing">
Content
</div>
</div>
Edit:
If the bounds of the growing div is in the visible area, the scroll is relative to the top of the growing div. So you can hack CSS to show the growing div, but actually not show it.
In this fiddle I have used two different CSS hacks. First one is adding a negative margin bottom and a positive padding bottom at same amount. The second hack is adding an :after element to the growing div but hide its visibility.
for click events, use blur, avoid scrollTo
It seems like this issue is focus-related. I came across a similar bug and when the element that triggered a height change was switched to an unfocusable element, like a div, the screen jumping disappeared. This clearly isn't a great solution because we should be able to use buttons! It also implicates focus in this strange behavior. Further experimentation led to blurring the trigger element before the height change, which solves the problem without moving the viewport. I've only tried this with click events so I'm not sure if it works for drag n drop.
codepen that showcases viewport jumping with accordions and a blur fix
function handleClick(e) {
e.currentTarget.blur();
// code to change height
}
Do you mean that when you scroll to the bottom, and a piece of content gets added, you stay at the bottom? Because the solution for that is real simple:
Option 1
Store the current scrolloffset to the top (eg how many px you've scrolled down)
Add new content
Set scrolloffset to the top to the stored value
Those last two steps can be done so fast that the user wont notice.
Option 2
Not 100% sure this works, but i'm guessing it does:
When the visitor scroll to the bottom, always scroll them back 3px. This way, they're not at the bottom at the point where new content gets added, so the browser stays where it is.
As per my understanding regarding your requirement, I have given a working jsfiddle sample.
Hope it would help to you.
If you expect something more, feel free to add comment.
Cool!
$(function(){
var height = 200;
var pos = 0;
setInterval(function(){
if($(document).height() >= $(window).height()){
var height = $('.container1').height();
$('.container1').height(height + 20);
pos = pos + 20;
$(window).scrollTop(pos);
}
}, 1000);
});
.container1 {
border: 1px solid #ccc;
min-height: 200px;
background: #ccc;
height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container1">
<p>11</p>
<p>12</p>
<p>13</p>
</div>
All of your draggable elements are in a container with no auto overflow, when you drag and drop your elements the whole page scrolls due to dragging.
Instead of that do as:
<div class="container">
<!-- Place all your draggable elements here -->
</div>
set a max-height and overflow of the container class as:
.container {
max-height: 400px;
overflow: auto;
}
Now when you drag and drop your elements, instead of the whole page, the only container will scroll.
After implementing this solution, it will look like this.
Before dragging.
While dragging.
Hope this helps you.

Zurb Foundation 6 reveal modal adds vertical spacing on mobile devices

I am using Zurb Foundation 6.3.0 and have come across the following issue. The reveal modal receives the following inline styles when opened both in chrome both in desktop and in responsive mode.
element.style {
display: block;
top: 0px;
left: 0px;
margin: 0px;
}
However if I open the website using remote debugging for my android device the inline styles are set as the following.
element.style {
display: block;
top: 60px;
left: 0px;
margin: 0px;
}
This causes the modal to move 60px further down than it should and display the content behind the modal. What would be causing the inline styles to be set differently on android device?
This is a result of the calculation done by foundation.reveal.js:
var height = this.$element.outerHeight();
var outerHeight = $(window).height();
if (this.options.vOffset === 'auto') {
if (height > outerHeight) {
top = parseInt(Math.min(100, outerHeight / 10), 10);
} else {
top = parseInt((outerHeight - height) / 4, 10);
}
}
If the element height is greater than the window height, it sets the top property for the element to be 1/10th of the window height. If the element height is not greater than the element height then the top value is set to 1/4th of the difference between the window height and the element height.
In this case the height of the element is calculated as being greater than the window height (even though it should be set as 100vh). Therefore the position of the element is being set as ~ 1/10th of the window height.
This issue is also address in this answer: CSS3 100vh not constant in mobile browser.
In order to prevent the modal element to have a top value of greater than 0 is to add the attribute `data-v-offset="0"' to the element like this:
<div class="full reveal" data-reveal data-v-offset="0">
<!-- content -->
</div>
This forces the value of the top property to be 0 as the calculations done in the foundation.reveal.js _updatePosition function are not made if the data-v-offset is set to 0.
This and other plugin options are covered further in the Zurb Foundation docs.

Setting margin-left and width of an element to match margin and size of another element

I would like to make a menu effect such as on the example below, where HR tag is used to create sliding line effect under menu items.
But in the example under the link the "moving" hr is positioned using static settings (see the link for actual example):
http://codepen.io/rm/pen/ldhon
.two:hover ~ hr {
margin-left: 25%;
}
I have a set of images that constitute my website menu, but these are positioned in floating way and I do not know their position at design time. I need therefore to modify code above in such a way that at least margin-left matches the position of the element (image) that has class two (the one that gets hovered) and, if possible, also match its width to the width of the element with class two. How I could possibly achieve that, do I manage with css or have to have a jQuery code?
If you set the hr's position to absolute, you can set its left offset and width with jQuery:
$('.container a').mouseover(function() {
$('.container hr').css({
left: $(this).offset().left,
width: $(this).width()
});
});
I don't think you can do so in CSS alone without hard-coding the widths.
CodePen

Auto re-size container if inner elements too small

I have container, which is re-sizable and contains inner elements <div>, which can be placed in any order and I can add them to container any amount when amount of them rising, the become smaller. My goal is when inner divs height or width, becomes smaller than 100px then automatically re-size container.
There can be more than one element smaller than 100px. When container re-sizes, all elements become bigger depending of percents of their width.
Problem: when there is more than one small element, they send many events to container, I want to send one request to container to re-size if there is possibility that it is enough to make all element enough size.
I tried to watch width, but it sends to many requests.
scope.$watch(function () {
return element.width();
}, function (oldval, newval) {
clearTimeout(containerCtrl.resizedFinished);
containerCtrl.resizedFinished = setTimeout(function () {
console.log("New Value=" + newval);
if (newval < 100)
scope.resizeContainer(element.width());
}, 100);
});
Maybe someone can give me any suggestions?
I use Angular, jquery base module, js.
I think you try to achieve:
draggable components should be minimum of 100px wide
when you drag/drop component into container, all components should shrink, so that they fit inside container
when components cannot get any smaller, container should grow (with 100px for each added component)
Sounds like you could get the styling done with flexbox in css:
.container {
display: inline-flex;
flex-direction: row;
padding: 2px;
min-width: 500px;
height: 120px;
background-color: yellow;
}
.component {
background-color: grey;
flex: 0 1 200px;
min-width: 100px;
height: 50px;
margin: 2px;
}
That way you do not have to do any watching of components through jQuery.
If the components also should have variable height, and container can have multiple rows, things become trickier. Then you need to be more specific about constraints.
EDIT:
If you cannot use flexbox for IE9, then try:
add event listener to component being dropped inside container (not on resize of individual components)
check (read from DOM) how many components are in container
if (container width - (component width * old number of components)) < 100
then shrinking is not allowed, so expand container
else
loop over each component to shrink them

Using scrollTop inside of a fixed element with overflow-y:scroll

I can't seem to get scrolltop to work when my content is inside of a fixed position container that has overflow-y: scroll specified.
Here is my relevant code:
/* some container with many large content blocks inside */
#container {
position: fixed;
width: 300px;
height: 300px;
overflow-y: scroll;
}
/* button that has a data-path attribute that specifies where the container should scroll to*/
$(".button").on("click", function(){
var path = $(this).attr("data-path");
var anchor = $("#" + path);
var position = anchor.position().top;
$("#container").animate({scrollTop: position});
});
I believe this fiddle illustrates my dilemma quite well: http://jsfiddle.net/Qndu5/
If you scroll from the top down to an element, it works great. After that, all bets are off. It is completely incapable of scrolling from any position other than the top. It either horribly misses the mark, or scrolls all the way back to the top, even though the position values being fed to it are seemingly correct.
Surely I'm missing something here, but I'm not sure what I am not understanding. Thanks for any help provided!
What you are missing is the scrollTop when calculating the position, so if the view is already scrolled, that need to be added to the calculation var position = anchor.position().top + $("#container").scrollTop();
http://jsfiddle.net/x36Rm/

Categories

Resources