Forum How do I...?

JavaScript TypeError: getting and setting element width

jamieappleseed
Hi,

I'm including jQuery 1.8.3 in my document and iterate over some img elements. However, when I call $(this).width(), Prince gives me an error: error: TypeError: value is not an object. If I call .offsetWidth directly on an element (without using jQuery), I get "undefined".

Is getting (and setting) width not supported by Prince yet?
mikeday
Right, at the moment Prince runs JavaScript before typesetting, not after, so element positions and sizes are not available. We hope to fix this in the future for browser compatibility, but it will be a big change.
Hi,

There is any other way to calculate the offset width using JS when we converting in pdf?
mikeday
The only way is to use the multi-pass process, which allows you to typeset the document and then measure box positions after typesetting in order to modify the style and typeset again. However the API for doing this is different to the browser DOM properties.
mattr
Hi, coincidentally I was looking to use clientWidth property 1 day later than the last comment here, (to get the width of a variable element, so to dynamically set matching width for another decorative element). I assume my answer would be the same as above?
And what would be the multipass api equivalent of clientWidth?
luizrocha
Hi, mattr. This is the code I've used to change clientWidth (browser and Prince). Hope it helps:
HTML:
<div data-section-style='11' ><img src='https://global.discourse-cdn.com/sitepoint/original/3X/7/7/77d4eb062e9fb08f5b79dbf2422cf76edabb29d8.png'  alt=''/><figcaption>Passando dificuldade</figcaption>
</div>


Javascript:
<script type="text/javascript">
function adjustFigcaptionWidthBrowser() {
  console.log("### adjustFigcaptionWidth Browser ###")
  var figcaptions = document.querySelectorAll('figcaption');
  for (var i = 0; i < figcaptions.length; i++) {
    var figcaption = figcaptions[i];
    var parent = figcaption.parentNode;
    var prevSibling = figcaption.previousElementSibling;
    if (prevSibling.tagName === 'IMG') {
      var newWidth = prevSibling.clientWidth + 'px';
      parent.style.width = newWidth;
      figcaption.style.width = newWidth;
    }
  }
}

function adjustFigcaptionWidthPrince() {
  Prince.trackBoxes = true;
  Log.info("### adjustFigcaptionWidth Prince ###")
  var figcaptions = document.querySelectorAll('figcaption');
  for (var i = 0; i < figcaptions.length; i++) {
    var figcaption = figcaptions[i];
    var parent = figcaption.parentNode;
    var prevSibling = figcaption.previousElementSibling;
    if (prevSibling.tagName === 'IMG') {
      var boxes = prevSibling.getPrinceBoxes();
      var newWidth = boxes[0].w + 'px';
      parent.style.width = newWidth;
      figcaption.style.width = newWidth;
    }
  }
}

try {
  Prince.trackBoxes = true;
  Prince.registerPostLayoutFunc(adjustFigcaptionWidthPrince);
} catch (error) {
  try {
    Log.debug(error)
  } catch (e) {
    console.log(e);
  }
}
// this code only runs on the browser
if (navigator.userAgent !== 'Prince/15.1 (www.princexml.com)') {
  window.onload = function() {
    adjustFigcaptionWidthBrowser();
  };
}

</script>

Edited by luizrocha