11

I want to know if there is any way you can call and use what the overflow:hidden has well hidden.

To clarify what I mean, in this example I would like to know that "This is hidden" is the hidden part of the div.

Is this even possible? How would you approach it?

I've tagged the question jQuery but of course whatever gets the job done is great, pure CSS or Javascript will do just fine.

Thanks in advance!

Trufa
  • 39,971
  • 43
  • 126
  • 190
  • @gms8994 sorry for that typo! thanks for the edit!! – Trufa Feb 08 '11 at 15:17
  • Is it always just easy, unstyled text? Will the element with `overflow: hidden` **always** have a `width` and `height`? In other words, how contrived is your example? – thirtydot Feb 08 '11 at 15:29
  • @thirtydot Well thats actually a good question! I'm not sure how to answer, since I would need it right now for un-styled text with fixed height and width, but would find it very interesting an answer that also covers other situations, without making the question so open that it is not possible to answer. Did I explain myself? – Trufa Feb 08 '11 at 15:33
  • @Trufa: What I'm thinking is using JS to: enclose each word with a `` tag. You can read the width/height of the container. You can iterate over each span, looking at the width/height, adding them up as you go. When the added width and/or height exceeds that of the container, you know that all the subsequent span tags are hidden. – thirtydot Feb 08 '11 at 15:37
  • @thirtydot ok, I think if that works would be a good hack, but that would make the code (quite) horrible wouldn't it? But again this apparently a very particular situation, so can't complain if it gets a little bit ugly... – Trufa Feb 08 '11 at 15:46
  • @Trufa: I imagine it could be done in less than 30 lines of slick jQuery. It'd take a while for me to write it, I'll have a stab at it later when I have more time if it's not answered acceptably by then. – thirtydot Feb 08 '11 at 15:50
  • @thirtydot thank you very much! no hurries! – Trufa Feb 08 '11 at 15:53
  • @thirtydot have a look at [this question](http://stackoverflow.com/questions/2456442/how-can-i-highlight-the-line-of-text-that-is-closest-to-the-mouse) for some solutions to a similar problem that could quickly be adapted (the accepted answer probably won't work though, because [getClientRects()](https://developer.mozilla.org/en/DOM/element.getClientRects) doesn't return rectangles for elements that overflow). – robertc Feb 08 '11 at 16:03
  • @Trufa: This looks close enough to solved, so I'm going to leave it alone. – thirtydot Feb 08 '11 at 22:58
  • @thirtydot thank you for the courtesy, the only reason I haven't accepted an answer yet is because I haven't have time to implement it in the "real" scenario, I think the answers are excellent already, of course feel free to chop in whenever you feel like it! And thanks anyway! – Trufa Feb 08 '11 at 23:01

4 Answers4

5

Try this:

CSS:

.text{


    outline:1px solid orange;

    width:100px;
    height:20px;
    overflow:hidden;

}

HTML:

<div class="text">This is shown. This is hidden</div>

<div id="result"></div>

<div id="container" style="visibility:hidden;"></div>

JS:

$("<span />").text($(".text").text()).appendTo("#container"); 

$("#result").append("<span>"+$(".text").width()+"</span><br />");
$("#result").append("<span>"+$("#container span").width()+"</span><br />");

$("#result").append("<span>Overflow: "+ (($("#container span").width() > $(".text").width()) ? "yes" : "no")+"</span><br />");

Example

EDIT

Try this:

based on this plugin

New Example

CSS:

.text{
    outline:1px solid orange;
    width:100px;
    height:20px;
    overflow:hidden;
}

HTML:

<br/>
<br/>
<div class="text" id="test1">This is shown. This is hidden</div>
<div class="text" id="test2">No hidden</div>
<br/>
<br/>
<div id="result"></div>

JS:

(function($) {

    $.fn.noOverflow = function(){

        return this.each(function() {

            var el = $(this);

            var originalText = el.text();
            var w = el.width();

            var t = $(this.cloneNode(true)).hide().css({
                'position': 'absolute',
                'width': 'auto',
                'overflow': 'visible',
                'max-width': 'inherit'
            });
            el.after(t);

            var text = originalText;
            while(text.length > 0 && t.width() > el.width()){
                text = text.substr(0, text.length - 1);
                t.text(text + "");
            }
            el.text(t.text());

            /*
            var oldW = el.width();
            setInterval(function(){
                if(el.width() != oldW){
                    oldW = el.width();
                    el.html(originalText);
                    el.ellipsis();
                }
            }, 200);
            */

            this["overflow_text"] = {
                hasOverflow: originalText != el.text() ? true : false,
                texOverflow: originalText.substr(el.text().length)
            };

            t.remove();

        });

    };

})(jQuery);

$("#test1").noOverflow();

$("#result").append("<span>Test 1</span><br />");

$("#result").append("<span>Has Overflow: "+ (($("#test1")[0].overflow_text.hasOverflow) ? "yes" : "no")+"</span><br />");

$("#result").append("<span>Text Overflow: "+ $("#test1")[0].overflow_text.texOverflow+"</span><br />");

$("#test2").noOverflow();

$("#result").append("<br /><span>Test 2</span><br />");
$("#result").append("<span>Has Overflow: "+ (($("#test2")[0].overflow_text.hasOverflow) ? "yes" : "no")+"</span><br />");
$("#result").append("<span>Text Overflow: "+ $("#test2")[0].overflow_text.texOverflow+"</span><br />");
andres descalzo
  • 14,887
  • 13
  • 64
  • 115
  • @andres descalzo, neighbor, I'm not really getting though how can I use this to echo what is hidden... – Trufa Feb 08 '11 at 16:13
  • I'm testing with this plugin. When I have finished what you step. I will also be useful to me. http://dl.dropbox.com/u/534786/index.html – andres descalzo Feb 08 '11 at 17:57
  • I hope you find it useful, Greetings.¡¡I just tried it in Chrome, not tested for compatibility with other browsers!! – andres descalzo Feb 08 '11 at 18:59
  • @andres Gracais!! Sorry for the delay in accpeting!! completly forgot.. excelent answer, came in very helpful!! – Trufa Feb 15 '11 at 15:55
3

Here's my solution (using jQuery).

Markup:

<div class="text">This is shown. This is hidden</div>

CSS:

.text{


    outline:1px solid orange;

    width:200px;
    height:20px;
    overflow:hidden;

}

(Only the overflow: hidden actually matters, the code will still work with different values for height and width.)

JS:

$('.text').wrapInner('<div/>');
var originaltext = $('.text div').text();

var t = $('.text div').text();

while(true)
{
    if ($('.text div').height() <= $('.text').height()) { break; }

    $('.text div').text(t.substring(0, t.lastIndexOf(" ")));
    t = $('.text div').text();
}

$('.text div').text(originaltext);

alert("shown: " + originaltext.substring(0, t.length));
alert("hidden: " + originaltext.substring(t.length));

Here's what it's doing:

We save the original text into a variable so we can restore it later.

We then remove one word at a time, until the inner div has decreased to the same height as the container (with overflow hidden). Everything still in the div was visible and everything that we had to remove was hidden.

Limitations

My solution assumes the div contains text only. It will mostly work with inline elements like spans, but currently strips them out during the process. It could easily be fixed to preserve spans, but coping with images or other complications like positioned elements is a lot more involved.

Seb Pollard
  • 366
  • 1
  • 3
2

This can give an estimate of the hidden text in the particular case in which the text in the div can wrap.

 <div class="text"><div id="inner">This is shown. This is hidden</div></div>

add to the .text css class:

 line-height: 20px;

At runtime, you can use the .height() jquery function to get the computed height of the inner div. Dividing it by the line-height, you can get the number of lines to which the text has been wrapped, with only the first being shown. Then you can guess the last word being shown/not shown and substring your text there.

var text = $("#inner").html();
var height = $("#inner").height();
var lineheight = $("div.text").height();
var rows = Math.round(height / lineheight);
alert("computed inner height: "
    + $("#inner").height()
    + " | rows: " + rows);
alert("Hidden text: "
    + text.substring(
        text.indexOf(" ",Math.round(text.length / rows))));
guido
  • 18,864
  • 6
  • 70
  • 95
  • @Trufa thanks; to have better results, one quirk would have to collapse white space (as the browsers do), you can do that easily with a regex replace. If your inner text contains html, remember to do the computations on text with tags stripped away, and if the content contains an image, remember the height() function returns the actual image height after the image has finished downloading – guido Feb 08 '11 at 16:24
  • @guido thanks for reminding me to strip the tags, I would have forgot that for sure! I didn't understand the clarification about the images though... – Trufa Feb 08 '11 at 16:31
  • @Trufa i mean that if you place your snippet in document.ready(), the image height returned will probably be 0 (because the image is still loading). You should bind your code to the some handler bound to load() – guido Feb 08 '11 at 16:45
0

Try this solution using jQuery

JQuery

$t = $('#text');

var shown, all, hiddenWidth;

// we start with the shown width set (via css) at 100px
shown = $t.width();

// we change the css to overflow:visible, float:left, and width:auto
$t.css({'overflow': 'visible', 'float': 'left', 'width': 'auto'});

// and get the total width of the text
all = $t.width();

// then we set the css back to the way it was
$t.css({'overflow': 'hidden', 'float': '', 'width': '100px'});

// and retrieve the hiddenWidth
hiddenWidth = all - shown;

HTML

<div id="text">This is shown. This is hidden</div>   

CSS

#text{
    outline:1px solid orange;
    width:100px;
    height:20px;
    overflow:hidden;
}
MikeM
  • 27,227
  • 4
  • 64
  • 80
  • That is nice, very well commented BTW! but I don't get how you would actually use "This is hidden" – Trufa Feb 08 '11 at 17:33
  • The hiddenWidth tells you whether or not there is a hidden portion. I guess the question now is do you want to show that hidden portion to the user or do you want to programmatically determine what content is not shown for other purposes. I guess it depends on what you're looking to get out of determing if there is a hidden portion of the div – MikeM Feb 08 '11 at 19:31