Thullyo Castilho
Thullyo Castilho

Reputation: 63

How to reproduce the `.width()` jQuery behavior in pure JavaScript, without another library/framework

I know the method .width() from jQuery returns the element's width without padding, border and margin.

In the accepted answer Table with vertical scroll, in which I can't comment, such method is used to get the width of the td elements of the first row of the table.

One of the jsFiddle in the answer there can be used to see the values returned by the method.

I tried to reproduce the behavior with this piece of code:

    let colunas = document.querySelector('.scroll tbody tr:first-child').children;
    let colunasWidth = [];
    for (let i = 0, length = colunas.length; i < length; i++) {
        colunasWidth.push(colunas[i].offsetWidth);//Width/clientWidth
    }

I tried the various widths (offsetWidth, width, clientWidth), none gave the same result as jQuery and then I tried to get the border and padding width to subtract from such various widths, but I can't think of a way to get the math or right properties right.

Is there a simple and straightfoward way to do it?

Upvotes: 2

Views: 703

Answers (2)

colxi
colxi

Reputation: 8660

You can use element.clientWidth and getComputedStyle together, to obtain teh value you are looking for...

element.clientWidth

The Element.clientWidth property is zero for elements with no CSS or inline layout boxes, otherwise it's the inner width of an element in pixels. It includes padding but not the vertical scrollbar (if present, if rendered), border or margin.

window.getComputedStyle

The window.getComputedStyle() method returns an object that reports the values of all CSS properties of an element after applying active stylesheets and resolving any basic computation those values may contain.

function width(el){
  // get element computed styles
  let styles=getComputedStyle(el);
  // remove the 'px' from the returned values
  let paddingLeft = styles['padding-left'].slice(0,-2);
  let paddingRight= styles['padding-right'].slice(0,-2);
  // substract paddings from value returned by clientWidth, and return value
  return el.clientWidth - paddingLeft - paddingRight;
}

// test
let w = width(document.getElementById('test'))

console.log( 'VanillaJS:' , w )
console.log( 'JQuery : ', $('#test').width())
#test{
  border:10px solid red;
  width:200px;
  margin:10px;
  padding:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test">
  I'm 200px + <br>
  10px padding + <br>
  10px border +<br>
  10px margin
</div>

Upvotes: 2

Sneakybastardd
Sneakybastardd

Reputation: 288

You want window.getComputedStyle and .getPropertyValue What it does is, it gets the styles used and then gets the actual width value of the element.

Here's a jsfiddle to show you: http://jsfiddle.net/u9d27wno/1/

var jquerywidth = $("#container").width();
var jqueryishwidth = window.getComputedStyle(document.getElementById("container"));
var offsetWidth = document.getElementById('container').offsetWidth;
var clientWidth = document.getElementById('container').clientWidth;
var msg = "offsetWidth: " + offsetWidth + "<br>\n";
msg += "clientWidth: " + clientWidth + "<br>\n";
msg += "jQuery width: " + jquerywidth + "<br>\n";
msg += "jQueryish width: " + jqueryishwidth.getPropertyValue("width") + "<br>\n";
document.getElementById('msg').innerHTML = msg;
//alert(document.getElementById('msg').innerHTML);

Let me know if that's the solution you needed!

Upvotes: 2

Related Questions