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:
- Call
extractCSS
with the element you want to extract - Generate your pdf using
res.stylesheet
- Call
swapBackIds
withres.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
Html:Draw Table Using Innerhtml
How to Retain the Scroll Position of a Scrollable Area When Pressing Back Button
Using CSS Modules How to Define More Than One Style Name
Ckeditor: Class or Id for Editor Body
How to Increase the Font Size Based on the Window Width
Mime Type Error with Express.Static and CSS Files
Escaping </Script> Tag Inside JavaScript
Es6 Map and Set Complexity, V8 Implementation
Cross-Browser Method to Determine Vertical Scroll Percentage in JavaScript
How to Reach the Element Itself Inside Jquery's 'Val'
Any Event Triggered on Autocomplete
Add CSS Styled Marker to Google Maps
Tool for Checking Unused CSS Selectors
How to Use CSSstylesheet.Insertrule() Properly