Get All Computed Style of an Element

Get all computed style of an element

Try using this function (updated your jsFiddle);

function getComputedStyle(elm, style) {
var computedStyle;
if (typeof elm.currentStyle != "undefined") {
computedStyle = elm.currentStyle;
}
else {
computedStyle = document.defaultView.getComputedStyle(elm, null);
}
return computedStyle[style];
}

getComputedStyle() function is from I does Javascript!

How get all computed css properties of element and its children in Javascript

Here is something I came up with, basically pass the element you want to extract the styles of and ones of its children, and it will return you the stylesheet as a string. Open your console before running the snippet and you will see the output from the console.log.

Because I wanted to support the extraction of every element even those without a selector, I had to replace each element id by a unique uuid specifically generated for them in order to facilitate the styling of your output. The problem with this approach is in case you are using ids for styling or for user interaction, you are going to loose such functionality on concerned elements after calling extractCSS.

However, it is pretty trivial to use the oldId I'm passing to change back once your pdfKit process finished the generation. Simply call swapBackIds passing the elements returned by the function. You can see the difference of behavior if you uncomment the call in my snippet: the #root pink background would disappear because the styling targets an element id.

All in all, you need to:

  1. Call extractCSS with the element you want to extract
  2. Generate your pdf using res.stylesheet
  3. Call swapBackIds with res.elements

// Generate an unique id for your element
// From https://stackoverflow.com/a/2117523/2054072
function uuidv4 () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

// Flatten an array
// https://stackoverflow.com/a/15030117/2054072
function flatten(arr) {
return arr.reduce(function (flat, toFlatten) {
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
}, []);
}

function recursiveExtract (element) {
var id = uuidv4()
var oldId = element.id

var computed = window.getComputedStyle(element)
var style = computed.cssText

// Now that we get the style, we can swap the id
element.setAttribute('id', id)

// The children are not a real array but a NodeList, we need to convert them
// so we can map over them easily
var children = Array.prototype.slice.call(element.children)
return [{ id: id, style: style, oldId: oldId }].concat(children.map(recursiveExtract))
}

function extractCSS (element) {
if (!element) { return { elements: [], stylesheet: '' } }

var raw = recursiveExtract(element)
var flat = flatten(raw)

return {
elements: flat,
stylesheet: flat.reduce(function (acc, cur) {
var style = '#' + cur.id + ' {\n' + cur.style + '\n}\n\n'
return acc + style
}, '')
}
}

var pdfElement = document.querySelector('#root')
var res = extractCSS(pdfElement)

console.log(res.stylesheet)

function swapBackIds (elements) {
elements.forEach(function (e) {
var element = document.getElementById(e.id)
element.setAttribute('id', e.oldId)
})
}

swapBackIds(res.elements)
#root {
background-color: pink;
}

.style-from-class {
background-color: red;
width: 200px;
height: 200px;
}

.style-from-id {
background-color: green;
width: 100px;
height: 100px;
}
<div id="root">
<span>normal</span>
<span style="background: blue">inline</span>
<div class="style-from-class">
style-class
</div>
<div class="style-from-id">
style-id
<div style="font-size: 10px">a very nested</div>
<div style="font-size: 12px; color: white">and another</div>
</div>
</div>

<div id="ignored-sibling">
</div>

how to get all the calculated styles of an element with jQuery?

after further research using Majid's answer, I found out that Jquery's ".css" method return computed style as well, and is better because it accounts for browser difference
http://api.jquery.com/css/

How to set all computed styles as literal styles on an element?

Well, the following snippet does what you want, though I don't think it's what you needed. MS Word is NOT a browser, I'm not sure if it supports all the styles or if jQuery works there...

var $this = $('b');var styles = window.getComputedStyle($this[0]);
$this.css( Object.values(styles).reduce( (a, e) => 0*(a[e] = styles[e]) || a, {} ))
console.log(`style="${$this.attr('style')}"`)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<b>I have styles</b>


Related Topics



Leave a reply



Submit