Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Word Wrap detection in JavaScript

I am trying to work out a way to detect wordwrap in a specific span tag inside a banner. If it wraps to 2 lines then increase the overall height of the container by 56px. There is also a sub headline (headline2) which also needs to increase (or decrease) the height by 40px.

I have written some basic JS code here which checks the div height of the span but its not great & also will only work for 3 lines.

   // Variable banner heights
    var hl11sub = 368;
    var hl21sub = 448;
    var hl31sub = 548;

    var hl12sub = 416;
    var hl22sub = 496;
    var hl32sub = 576;

    var hLFontSizeCSS = window.getComputedStyle(headlineText, null).getPropertyValue("font-size");
    var hL2FontSizeCSS = window.getComputedStyle(headline2text, null).getPropertyValue("font-size");
    var bannerHeightCSS = window.getComputedStyle(banner, null).getPropertyValue("height");
    var headlineHeight = headlineText.offsetHeight;
    var hL2HeadHeight = headline2text.offsetHeight;

    var headHeight = headlineText.style.lineHeight = parseInt(hLFontSizeCSS) + 10 + "px";
    var hL2Height = headline2text.style.lineHeight = parseInt(hL2FontSizeCSS) + 10 + "px";

    // Text Height values
    var hL1LineHeight = parseInt(headHeight); // 8 is line height & padding
    var hL2LinesHeight = 140;
    var hL3LinesHeight = 195;

    // HL2 height values
    var hL2TextOver1LineHeight = parseInt(hL2Height); // 8 is line height & padding
    var hL2TextOver2LineHeight = 84;

    if(hL2HeadHeight == hL2TextOver1LineHeight && headlineHeight == hL1LineHeight){
      banner.style.height = hl11sub + "px";
    }
    else if(hL2HeadHeight == hL2TextOver1LineHeight && headlineHeight == hL2LinesHeight){
      banner.style.height = hl21sub + "px";
    }
    else if(hL2HeadHeight == hL2TextOver1LineHeight && headlineHeight >= hL3LinesHeight){
      banner.style.height = hl31sub + "px";
    }
    else if(hL2HeadHeight == hL2TextOver2LineHeight && headlineHeight == hL1LineHeight){
      // Single headline with 2 lines sub
      banner.style.height = hl12sub + "px";
    }
    else if(hL2HeadHeight == hL2TextOver2LineHeight && headlineHeight == hL2LinesHeight){
      // 2 headlines with 2 lines sub
      banner.style.height = hl22sub + "px";
    }
    else {
      banner.style.height = hl32sub + "px";
      // 3 headlines with 2 lines sub

It needs to only change the height of the banner depending on if the span words wrap once, twice, three times etc.

Any suggestions or help with this would be greatly appreciated.

like image 425
ste Avatar asked Mar 05 '23 02:03

ste


1 Answers

Here is a very basic implementation on how to detect when a line is wrapped hopefully this gives you a good idea where to start and integrate it into your app.

Heres the docs for stuff used

https://developer.mozilla.org/en/docs/Web/API/EventTarget/addEventListener https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

You mentioned the height changing and you needing to know when its wrapped you can use a mutation observer to check when the style has changed then check if its wrapped.

Resize the demo window to see results

any questions i'll try get to them asap if i've misunderstood i'll happily change :)

const h1 = document.querySelector('h1');
const banner = document.querySelector('.banner');


//handles style changes on banner to check wrapping
const observer = new MutationObserver(mutations =>
  mutations.forEach(mutationRecord => onLineWrapDoSomething())
);
observer.observe(banner, { attributes : true, attributeFilter : ['style'] });


// handles window resize events
window.addEventListener('resize', onLineWrapDoSomething)

function onLineWrapDoSomething() {
  const { lineHeight } = getComputedStyle(h1);
  const lineHeightParsed = parseInt(lineHeight.split('px')[0]);
  const amountOfLinesTilAdjust = 2;

  if (h1.offsetHeight >= (lineHeightParsed * amountOfLinesTilAdjust)) {
    console.log('your h1 now wrapped')
  } else {
    console.log('your h1 on one line')
  }
}

// shows it logs when style changes and it wraps, ignore the disgusting code below
setTimeout(() => {
  banner.style.width = '50%'
  setTimeout(() => {
    banner.style.width = '100%'
  }, 1500)
}, 1500)
.banner {
  width: 100%;
}
h1 {
  line-height: 1.5
}
<div class="banner">
  <h1>This is some text that will eventually wrap</h1>
</div>
like image 155
Joe Warner Avatar answered Mar 12 '23 18:03

Joe Warner