8

Possible Duplicate:
How to get css3 multi-column count in Javascript

I have a long dynamic text which is going to be split into columns by using CSS

div
{
    -moz-column-width: 500px;
    -moz-column-gap: 20px;
}

Is it possible to get how many columns are created? I'm using jQuery in the client side.

Community
  • 1
  • 1
Iswanto Arif
  • 959
  • 2
  • 8
  • 8
  • what do you require the count for? you can use column-count to specify how many columns you want to be (optimally) generated. – bubblez Apr 23 '12 at 07:31
  • I actually grab HTML files in the server by Ajax and put it inside Javascript generated iframe. Text inside body is going to be split with column-width 500px. I need the count so that I can determine the width of the iframe. Sorry for my English, not my native language. – Iswanto Arif Apr 23 '12 at 07:40
  • Can you give us an example with jsFiddle? – gdoron Apr 23 '12 at 11:59
  • Here's the example http://jsfiddle.net/c2hQx/1/ – Iswanto Arif Apr 23 '12 at 12:37

2 Answers2

8

Your questions and fiddle ignore vendor prefixes; larssin's answer is a good direction but isn't complete.

I created a small helper function for you, which goes over currently implemented prefixes for these values, fetches the actual values with .css() and returns the correct number. Works cross-browser, including non-supporting browsers which always return 1.

I chose to ignore the iframe case, which just makes things more complicated but as I understand isn't related directly to your question.

Update: Now accounts for border and padding.

Code on jsFiddle and here:

function getColumnsNumber(el){
    var $el = $(el),
        width = $el.innerWidth(),
        paddingLeft, paddingRight, columnWidth, columnGap, columnsNumber;

    paddingLeft = parseInt( $el.css('padding-left'), 10 );
    paddingRight = parseInt( $el.css('padding-right'), 10 );

    $.each(['-webkit-','-moz-',''], function(i, prefix){
        var _width = parseInt( $el.css(prefix+'column-width'), 10 );
        var _gap =   parseInt( $el.css(prefix+'column-gap'), 10 );
        if (!isNaN(_width)) columnWidth = _width;
        if (!isNaN(_gap))   columnGap = _gap;
    });

    columnsNumber = Math.floor( (width - paddingLeft - paddingRight) / (columnWidth + columnGap) );
    if (isNaN(columnsNumber) || columnsNumber < 1) columnsNumber = 1;
    return columnsNumber;
}
Ronny
  • 4,295
  • 2
  • 24
  • 30
  • Using this function for the iframe scenario is fairly simple - Here's larssin's example, with some bugs fixed and my snippet in use (minified this time): http://jsfiddle.net/Ronny/c2hQx/3/ – Ronny Apr 24 '12 at 19:09
  • Thanks Ronny! Another problem was I didn't know how to get the width of the div inside the iframe if the div is wider than the iframe but then I stumbled upon scrollWidth and it's solved. Thanks for the solution, works perfectly! – Iswanto Arif Apr 25 '12 at 06:18
  • If the element ("el") is narrower than the "column-width" CSS rule, this function will return "0" in supporting browsers. May I suggest changing the second-to-last line to "if (isNaN(columnsNumber) || columnsNumber < 1) columnsNumber = 1;" This assumes we always have at least one column. – David Lantner Jul 31 '12 at 15:16
  • Actually, I should have just said "If the element is very narrow…" because it seemed at a glance to be narrower than the "column-width" rule. – David Lantner Jul 31 '12 at 15:48
  • Thanks @DavidLantner, I updated the code and made it a community wiki to allow further changes by anyone. – Ronny Aug 03 '12 at 11:39
  • On a side note, there's no need to work with prefixes if you are using jQuery. – Vilmos Ioo May 19 '14 at 11:16
  • Since jQuery 1.8 it needs no prefixes – Robert Feb 16 '15 at 15:02
0

If the columns are in different elements you can get the number of children with $(selector).length (http://api.jquery.com/length/). Not sure if I understand your problem correctly, but hope it will help.

An example:

<div id="myText">
    <div class="column">some text...</div>
    <div class="column">some text...</div>
    <div class="column">some text...</div>
</div>

var columns = $('#myText').length;
    /* or */
var columns = $('.column').length;

Update:

Ok, I had a look at your jsfiddle example and thought that you can get the resulting width of the iframe with $('#test').width() and then calculate the number of columns:

var width = $('#test').width();
var columns = width/(columnWidth+columnsGap);
larssin
  • 372
  • 4
  • 5
  • The columns are actually in the same element, thanks anyway... – Iswanto Arif Apr 23 '12 at 12:09
  • Ok. In javascript Strings can be treated as arrays and if you know how many characters can be in one column you can maybe calculate how many columns you can anticipate. I.e. if you have: var aText = "This is a test."; var length= aText.length; However this can couse problems in different browser, because the font sizes are treated a bit differently. – larssin Apr 23 '12 at 12:18
  • But I guess not every line has the same number of characters. Here's a jsfiddle example http://jsfiddle.net/c2hQx/1/ in that example string is split into 3 columns. I'd like to know how to get that number with Javascript. – Iswanto Arif Apr 23 '12 at 13:25
  • 1
    Thanks larssin, was actually thought of this but I realize that the div was inside an iframe, it's a lot wider than the iframe itself and I didn't know how to get the div width. So now I figured out document.body.scrollWidth is used to get the whole width of the div... +1 for helping :) – Iswanto Arif Apr 25 '12 at 05:56