Get real width of elements with jQuery

前端 未结 6 1981
Happy的楠姐
Happy的楠姐 2021-02-12 16:48

I am writing a validator for \"visual correctness\" of html files. The goal is to detect too wide elements.

Here is a demo of my problem.

The do

相关标签:
6条回答
  • 2021-02-12 17:18

    This effect is called "shrinkwrapping", and there's a couple of ways to determine the "real" width of the element.

    Float

    One of the ways that you can use is to float your <p> element which will force it as small as possible, but you'll need to use a clearfix if anything inside your div is floating:

    #two { float: left; }
    

    Inline-block element

    Inserting an inline element should work.

    <p>content</p>
    

    would become

    <p><span>content</span></p>
    

    Absolutely positioned element

    Changing the element position to be absolute should also work:

    #two { position: absolute; }
    

    If you can't statically change the markup or the style, you can always change them dynamically through JavaScript.

    (absolutely positioned element)

    var realWidth = $("#two").css("position", "absolute").width();
    

    (float)

    var realWidth = $("#two").css("float", "left").width();
    

    (inline-block element)

    var t = $("#two").html();
    var realWidth = $("#two")
        .empty()
        .append($("<span>").html(t))
        .width();
    
    0 讨论(0)
  • 2021-02-12 17:18

    As others have pointed out, changing the position of the element to absolute also works. Doing this will result in an inline-style which can mess with your css afterwards if you don't watch out. Here is a solution to get rid of the inline style again.

    //Change position to absolute
    $('#two').css("position", "absolute");
    var textWidth = $('#two').width();
    
    //Get rid of the inline style again
    $('#two').removeStyle("position");
    
    
    
    //Plugin format
    (function ($) {
        $.fn.removeStyle = function (style) {
            var search = new RegExp(style + '[^;]+;?', 'g');
    
            return this.each(function () {
                $(this).attr('style', function (i, style) {
                    return style.replace(search, '');
                });
            });
        };
    }(jQuery));
    
    0 讨论(0)
  • 2021-02-12 17:22

    Apply word-wrap: break-word; to it.. so the word will break and there won't be any text going out of the container... btw you can't check the width of the text which is going out of the container.

    Example

    Update: You can check if the width of text in it is bigger than the width of the container like this

    0 讨论(0)
  • 2021-02-12 17:27

    As others have said, temporarily wrap the text node in an inline element.

    var two = document.getElementById('two'),
        text = two.firstChild,
        wrapper = document.createElement('span');
    
    // wrap it up
    wrapper.appendChild(text);
    two.appendChild(wrapper);
    
    // better than bad, it's good.
    console.log(wrapper.offsetWidth);
    
    // put it back the way it was.
    two.removeChild(wrapper);
    two.appendChild(text);
    

    http://jsfiddle.net/vv68y/12/

    Here is a getInnerWidth function that should be useful to you. Pass it an element and it will handle the wrapping and unwrapping.

    function getInnerWidth(element) {
    
        var wrapper = document.createElement('span'),
            result;
    
        while (element.firstChild) {
            wrapper.appendChild(element.firstChild);
        }
    
        element.appendChild(wrapper);
    
        result = wrapper.offsetWidth;
    
        element.removeChild(wrapper);
    
        while (wrapper.firstChild) {
            element.appendChild(wrapper.firstChild);
        }
    
        return result;
    
    }
    

    http://jsfiddle.net/vv68y/13/

    0 讨论(0)
  • 2021-02-12 17:33

    scrollWidth will do it:

    $("#two").get()[0].scrollWidth or getElementById("two").scrollWidth

    this outputs 212px, the real width you are looking for.

    0 讨论(0)
  • 2021-02-12 17:33

    The element itself is constrained to 200px, but the text inside spills out. If you insert a span (or any other inline element) inside the P tag it works fine.

    http://jsfiddle.net/will/vv68y/5/

    Hope that helps :)

    0 讨论(0)
提交回复
热议问题