34

CSS:

 .blue
    {
     width:200px;
     height:200px;
     background-color:blue;
     color:#000000;
     overflow:auto;
    }

JavaScript:

function addChar() {
    $('.blue').append('some text  ');
}

HTML:

<div id='blue1' class="blue"></div><br />
<a href='javascript:void(0)' onclick='addChar()'>Add</a>

div id='blue1' has overflow property set to auto. I want to detect overflow when it happens.

Jan Hančič
  • 53,269
  • 16
  • 95
  • 99
Praveen Prasad
  • 31,561
  • 18
  • 73
  • 106

10 Answers10

42
$.fn.HasScrollBar = function() {
    //note: clientHeight= height of holder
    //scrollHeight= we have content till this height
    var _elm = $(this)[0];
    var _hasScrollBar = false; 
    if ((_elm.clientHeight < _elm.scrollHeight) || (_elm.clientWidth < _elm.scrollWidth)) {
        _hasScrollBar = true;
    }
    return _hasScrollBar;
}

/// this is my solution

Praveen Prasad
  • 31,561
  • 18
  • 73
  • 106
20
$.fn.hasOverflow = function() {
    var $this = $(this);
    var $children = $this.find('*');
    var len = $children.length;

    if (len) {
        var maxWidth = 0;
        var maxHeight = 0
        $children.map(function(){
            maxWidth = Math.max(maxWidth, $(this).outerWidth(true));
            maxHeight = Math.max(maxHeight, $(this).outerHeight(true));
        });

        return maxWidth > $this.width() || maxHeight > $this.height();
    }

    return false;
};

Example:

var $content = $('#content').children().wrapAll('<div>');
while($content.hasOverflow()){
    var size = parseFloat($content.css('font-size'), 10);
    size -= 1;
    $content.css('font-size', size + 'px');
}
Luka Zakrajšek
  • 1,079
  • 12
  • 12
17

One-liner solution to the specific question:

var elt, hasOverflow = (elt = $('#blue1')).innerWidth() > elt[0].scrollWidth;

Just wanted to golf a bit. :]

(Note: This is only for horizontal overflow detection; it's trivial to add vertical overflow detection as well.)

Noyo
  • 4,874
  • 4
  • 39
  • 41
4

As far as I know you will have to compare the width/clientWidth and height/clientHeight in your addChar() function. When that changes you've got scrollbars (unless you moddify the dimensions somewhere else ...)

Something like this:

function addChar () {
    var blueEl = $( '.blue' );
    blueEl.append ( 'some text  ' );

    if ( blueEl.width () !== blueEl[0].clientWidth || blueEl.height () !== blueEl[0].clientHeight ) {
        // element just got scrollbars
    }
}
Jan Hančič
  • 53,269
  • 16
  • 95
  • 99
  • This will work. You can also check .scrollWidth and .scrollHeight against the original height() and width() to achieve the same thing. I'm not sure which is more x-browser compatible. – Lance McNearney Jan 13 '10 at 20:28
  • @jan there is a mistake in ur code do like below blueEl.width () !== blueEl[0].scrollWidth || blueEl.height () !== blueEl[0].scrollHeight ==compare scrollHeight/scrollWidth not client width/height – Praveen Prasad Jan 13 '10 at 20:30
  • 1
    This in plugin format: `$.fn.overflows = function() { return ($(this).width() !== this.clientWidth || $(this).height() !== this.clientHeight); };` – Mathias Bynens Jan 23 '10 at 16:31
2
jQuery.fn.preventOverflow = function(){
    return this.each(function(){
        var defaultDisplay = $(this).css('display');
        var defaultHeight = $(this).height();

        $(this).css('display', 'table');
        var newHeight = $(this).height();
        $(this).css('display', defaultDisplay);
        if(newHeight > defaultHeight){
            $(this).height(newHeight);
        }
    });
};

$('.query').preventOverflow();

here i'm just preventing the height, but i think this method can be used to width too.

2

The only way I can think of is to create a nested DIV and compare the outer div height with the inner div. If you don't want to modify existing markup you can append it using jQuery like this:

var outer = $('.blue'),
    inner = $('<div>').appendTo(outer);

function addChar() {
    inner.append('some text ');
    if (inner.height() > outer.height()) {
        console.log('overflowed');
    }
}
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
1

You can check the element's scrollWidth and/or scrollHeight properties against its clientWidth and/or clientHeight.

Note that this doesn't actually require jQuery.

  • 2
    You should know that `clientWidth` [doesn't always act in a standard, cross-browser way](http://www.howtocreate.co.uk/tutorials/javascript/browserwindow) and [isn't part of the W3C standard](http://www.w3schools.com/jsref/dom_obj_all.asp), although it seems to have a lot of support. – RustyTheBoyRobot Jun 28 '12 at 22:39
1

I used Luka's answer until I realised it was comparing each child individually. It didn't work since it doesn't calculate the dimensions of the content of a DOM node, just each child individually. I used the scrollHeight property of DOM nodes instead:

(function($) {
  $.fn.hasOverflow = function() {
    var $this = $(this);
    return $this[0].scrollHeight > $this.outerHeight() ||
        $this[0].scrollWidth > $this.outerWidth();
  };
})(jQuery);

EDIT: Fixed a bug caused by using .height() which doesn't take padding into account.

Aram Kocharyan
  • 20,165
  • 11
  • 81
  • 96
1

Here's a plugin i wrote, which might come in handy if you want to find out if an element is overflown or not: https://github.com/ZetaSoftware/jquery-overflown-plugin.

With this plugin, in the original example, you could just do: $("#blue1").overflown() to find out of children of #blue1 are overflowing.

zıəs uɐɟəʇs
  • 1,728
  • 3
  • 14
  • 27
-1

Thought I should add an improved solution based on Praveen's answer. This improvement allows to check for width, height or both. Hence the name $.hasOverflow so thanks Luka as well. The ternary operator makes it a little more expressive and clear.

/**
 * @param {Boolean} x overflow-x
 * @param {Boolean} y overflow-y
 */
$.fn.hasOverflow = function (x, y) {
    var el = $(this).get(0),
        width = el.clientWidth < el.scrollWidth,
        height = el.clientHeight < el.scrollHeight;

    return !x
        ? !y
        ? width || height
        : height
        : width;
}
Tim Vermaelen
  • 6,869
  • 1
  • 25
  • 39