adjusting for browser font width variations in jquery - javascript

I am writing a script that takes the items in the navigation bar, and stretches each row except the last to the width of the menu's container. The process is basically:
-Find the menu container width
-Iterate through each item, adding the .outerWidth(true) to a variable containing the current row width
-When the current row width becomes greater than or equal to the container width run a few tests
--subtract .outerWidth(true) from current row width and add .innerWidth().
--if row width is still greater than container width, move to the next row array, and add the current item as the first item in the row,
--if the row width is equal to or less than the container width, add the item as the last item of the current row, and move to the next row array.
Once the rows have been created, calculated the necessary padding to add to each element by finding the difference between the container width and the row width and following the following formula:
this.addedPadding = Math.floor( this.difference / ( this.items.length * 2) );
then calculate the leftover space by:
this.leftovers = this.difference - (this.addedPadding * 2 * this.items.length);
Then proceed to iterate through all items, adding the added padding. Then take leftovers, iterate it downwards by 2's, adding 1px of padding to each side of the first element, then second, third, and so on until leftovers is equal to 1 or 0. If it equals one, add one px of padding to the padding-right of the last item in the row.
Iterate through each row, and repeat the process.
Now, the problem is, different browsers render font slightly differently, so the numbers don't always add up perfectly. My current solution is to change the container width by the necessary adjustment by the browser so that the rows render correctly. This doesn't even have consistent results. For instance, on the site I'm working on, in Chrome, the homepage renders incorrectly at first, but (at least on my computer) if you refresh, it renders correctly.
What would be the correct way to address this without having to change the containerWidth based on browser and content? Is there a way?
For an example of the issue, visit http://development.rjhallsted.com/login_system/browsing/projects/insidemt/

Related

Get total width of individual child elements (then half it)

I have a div which contains multiple children. I'm planning on using a horizontal layout so I need to set a width on the parent div for the layout to run from left to right. Rather than all the items in a single row I want 2 rows, so once I have the total width I'll need to divide it by 2 so the items wrap onto another line.
The number of children will change, so a CSS value isn't appropriate in this situation.
The mark-up will look a bit like this:
<div id="container">
<figure>1</figure>
<figure>2</figure>
<figure>4</figure>
<figure>5</figure>
<figure>6</figure>
</div>
Really appreciate it if someone can help me with this. I've managed to get the dimensions of a single element before but I can't see to do it for a group.
Thanks in advance,
Steve
Please refer to this fiddle: https://jsfiddle.net/m6k1jamd/
What has to be done to acheive this is:
- On page load get a predefined width for the figure (set in css)
- Get the number of girues within the container
- Work out how many figures to show per row (you want 2 rows).
- Force 2 rows by using Math.ceil()
- Determine how wide each row is by calculating the number of figures per row * figure width.
- Set the containers width to the calculated row width.
Javascript from above logic
$(document).ready(function(){
//Get the figures width
var figure_width = $("#container figure").css("width").replace("px", "");
//Get num figures
var num_figures = $("#container figure").length;
//Work out how manay figures per row
var num_row_figures = Math.ceil(num_figures / 2);
//Get the total width
var row_width = figure_width * num_row_figures;
//Set container width to half the total
$("#container").width(row_width);
});
Hope this helps!
Josh

How to deal with sub-pixel jQuery.width() results

I have a ul that is set to display inline-block and list elements that are set to display inline block.
The ul is set to have a width of auto so it shrinks if the container does (responsive).
The list items are set to be auto width of their content which is set to whitespace nowrap and so if they dont all fit in a line they drop down to the next line.
I am trying to detect with jQuery if this is happening. So I am getting the inner width (using width()) of the ul and the calculating the total width of each li by getting each outerWidth() and adding them together. Then I check if the total li width is greater than the inner width of the ul.
But heres the problem, jQuery is returning a value of 933.6800003051758 for the nav's inner width and a value of 934 for the list items. So you'd think that the list items would be breaking onto a second line- but they aren't! So I suppose that the browser is rounding up the nav's innerwidth to be 934.
What I'd like to know is, if I round up the nav's inner width before I compare the value to the total list items width will that be reliable or will my function sometimes think the list items are not breaking on to a second line when in fact they are?

Telerik RadGrid scrollbar is offsetting the columns

I have a page with anywhere between 1 and 6 dynamically built iframes containing RadGrids in two columns on the page. I've managed to get a column by the name Document Number to line up in all of them, however if one of them contains more data then the space allowed it will scroll. This is expected and correct.
My issue is when the scrollbar does show it pushes all my columns left just a smidge in that grid, and now it's out of sync with the other grids. I've added a small column which I can dynamically display to push the other grids' columns to match, I just need to be able to detect/determine if a scroll bar is actually being displayed.
I found an old telerik post that suggests I use the scroll height vs the overflow height and if scroll height is larger then we know there's a scroll bar being displayed. My attempts to use the supplied javascript have shown me that the post is outdated and that GridDataDiv no longer exists.
Is there a new/updated way to detect the presence of a scrollbar? Alternatively, is there a better way to have my document number columns even regardless of scrollbar?
Compare the grid's client width and the scroll area width of the grid data:
var grid = document.getElementById("RadGrid1"),
scrollArea = document.getElementById("RadGrid1_GridData");
// ex. 171 (note no units included)
alert("grid.clientHeight: " + grid.clientHeight);
// ex. 300px (note the "px" units are included)
alert("scrollArea.style.height: " + scrollArea.style.height);
// Is the verticle scroll bar visible?
var vertIsVis = scrollArea.style.height.replace("px", "") > grid.clientHeight;

Scroll a div when hovering over a clipped item

This is a tricky problem to describe...I have a fixed height <div> on my page with a bunch of content items inside. Each item is a square <div>, floated left, so they fill in the area left to right and top to bottom. If there are too many items to fit in the view, then the content area will scroll (overflow-y: auto).
Forgive the ASCII art:
---------------------
| [ 1 ] [ 2 ] [ 3 ] |
| [ 4 ] [ 5 ] [ 6 ] |
| [ 7 ] [ 8 ] [ 9 ] |
---------------------
The thing is, the items inside don't fit perfectly in the area without the bottom row getting clipped. So what I want to do is somehow automatically scroll the view down when the user hovers over an item that's clipped off the bottom of the content area.
I can't figure out how I would go about determining whether a particular item is clipped or not.
Is this totally wacky? Or is there a logical method for doing this?
This is a very basic example.
http://jsfiddle.net/8Kb7N/
Essentially, each of your square divs would have an associate anchor inside with a unique name.
You want to set a hover event for each item that sets the window.location to the name of its anchor. This should let it navigate inside the area.
After first experimenting with #Geuis' method, I realized I was solving the wrong problem, because the last row of items isn't necessarily the same row that's getting clipped.
For example, say I have 12 items in a 3x4 grid: 3 items per row, 4 rows in total. Then say my container is only tall enough to show the first two rows and the top half of the third row. The last row is the fourth row, but the row that's getting clipped is the third row, assuming I'm scrolled to the top. Or, what if I scroll to the bottom of the container? Now the second row is getting clipped, and off the top rather than the bottom.
So I realized that rather than looking at the rows, I need to look at the particular item that's being hovered over and determine if that single item is being shown in full or not. If it is, do nothing; if it's not, scroll up or down depending on which end of the item is clipped.
Here's what I came up with. On hover:
var containerHeight = $container.height(),
itemHeight = $(this).height(),
itemOffset = Math.floor($(this).position().top),
itemVisible = containerHeight - itemOffset,
itemClip = itemHeight - itemVisible;
if (itemClip > 0){
$container.scrollTo('+=' + itemClip, 600);
} else if (itemOffset < 0){
$container.scrollTo('-=' + Math.abs(itemOffset), 600);
}
($container is defined elsewhere in my script as the containing div)
Line by line:
Get the height of the container that holds all the items
Get the height of the item being hovered
Get the distance from the top of the container to the top of the hovered item
Subtract the distance (line 3) from the height of the container (line 1)
Take the difference from line 4 and subtract it from the height of the item being hovered (line 2)
Now, this tells you two things:
If the result of line 3 is negative, the item is being clipped by that many pixels past the top of the container
If the result of line 5 is positive, the item is being clipped by that many pixels past the bottom of the container
Knowing this, you can then scroll the container in the correct direction and by the correct distance to reveal the whole item.
The actual scrolling itself requires the jQuery ScrollTo plugin in order to scroll up or down x number of pixels from the current scroll position (not from the top of the container, which is what jQuery's built-in .scrollTop() function does).
(ScrollTo does not take a negative number as a value, so in order to scroll up, you need to get the absolute value of itemOffset - hence Math.abs(itemOffset)).

How to get css3 multi-column count in Javascript

We're using the new css3 multi-column layout properties to get our text into newspaper columns. Each column gets a fixed width, and the column-count defaults to "auto", which means that the browser decides how many columns there are.
How do we get the actual number of columns as an integer in Javascript?
If we query the css "column-count" (or -moz-column-count) we get either "auto" or a blank as a result.
The secret is to put a small marker at the end of the content. You can programmatically add an empty span:
<span id="mymarker"></span>
then grab the span using a jquery $("#mymarker") and get the "left" property. Divide that number by the width of the columns (adjusted for column-gap), and that will tell you what column this last element is in. Math.ceil() on the value and you have the column count.
Divide the column container's scrollable width by visible width:
container.scrollWidth / container.offsetWidth
Try this:
$.fn.howMuchCols = function(){
return Math.round($(this).find(' :last').position().left - $(this).position().left / $(this).outerWidth()) +1;
};
$('.my-stuff-with-columns').howMuchCols();
Code explanation:
This code will create a function 'howMuchCols ' to each jQuery element.
You can't get the width of a element with columns using the conventional way, because his width is used to define each inner column size. To know how many columns the element have inside, you need to get his real width and divide by the columns size, then you will have the column amount.
The way to get the real width is to sum the X offset of the last child element of the columns container with it width, then, subtract it with the sum of the column container X offset.
In the code, I have added the size of one column after make the subtraction and division rather than use the pixel unit before the division (it does not make difference).
The Math.round must be there because not always the container size will be exactly divisible by his inner columns width.
could you set a class to each column such as class="another-column" and then use Jquery to select the classes and iterate them.
var count = 0;
$('.another-column').each(function(){
count++;
});
Warning, this is untested. If you could supply with some html/css3 code I could test it on jsfiddle

Categories

Resources