Home > Enterprise >  How do I change the height of dynamically created elements using JavaScript?
How do I change the height of dynamically created elements using JavaScript?

Time:06-08

I've dynamically created a fretboard with 6 strings. Each are given a height of 8px using the class of .string:before. How do I give each string a height value taken from the stringGauge array so that as they are created, the strings increase in thickness(height)?

The height needed to be assigned using a pseudo class so I am unable to solve this through the use of inline styling as far as I know.

    const root = document.documentElement;
    const fretboard = document.querySelector(".fretboard");

    // The stringGauge array below contains the values I want to assign to each new string
    const stringGauge = [1, 2, 3, 6, 7, 8];

    const instrumentTuningPresets = {
      Guitar: [4, 11, 7, 2, 9, 4],
    };
    
    let selectedInstrument = "Guitar";
    let numberOfStrings = instrumentTuningPresets[selectedInstrument].length;
    
    const app = {
      init() {
        this.setupFretboard();
      },
      setupFretboard() {
        fretboard.innerHTML = "";
    
        // This creates the strings for the fretboard
        for (let i = 0; i < numberOfStrings; i  ) {
          let string = tools.createElement("div");
          string.classList.add("string");
          fretboard.appendChild(string);

          // This loops throught the stringGauge array but only manages to assign the
          //last value in the array which is 8. Subtracting 1-5 from i (e.g. stringGauge[i-3])
          // does change the height but for all of them.
          root.style.setProperty("--string-height", stringGauge[i]);
        }
      },
    };
    
    const tools = {
      createElement(el, content) {
        el = document.createElement(el);
        if (arguments.length > 1) {
          el.innerHTML = content;
        }
        return el;
      },
    };
    
    app.init();
:root {
  --fretboard-height: 300;
  --string-height: 8;
}

.fretboard {
  display: flex;
  flex-direction: column;
  background-image: url(../assets/images/maple.jpg);
  width: 100%;
  min-width: 1500px;
  height: calc(var(--fretboard-height) * 1px);
  margin-top: 50px;
}

.string {
  display: flex;
  position: relative;
  width: 100%;
  height: 100%;
}

.string:before {
  content: "";
  width: 100%;
  height: calc(var(--string-height) * 1px);
  background: linear-gradient(#eee, #999);
  box-shadow: 76px 3px 10px #806233;
  z-index: 1;
  position: absolute;
  top: calc(var(--string-top-position) * 1px);
}
<div ></div>

CodePudding user response:

The most rudimentary way, without changing much of your existing code, would just be to give the css variables you create a name based off the i index, and then use the nth-child selector to target each string. I'm doing i 1 for easier reading because nth-child starts at 1, not 0.

root.style.setProperty(`--string-height-${i 1}`, stringGauge[i]);
.string:nth-child(1):before {
    height: calc(var(--string-height-1) * 1px);
}

You could make the nth-child logic a bit terser by using a Sass loop.

Here's a snippet showing the simple way to get you started.

const root = document.documentElement;
    const fretboard = document.querySelector(".fretboard");

    // The stringGauge array below contains the values I want to assign to each new string
    const stringGauge = [1, 2, 3, 6, 7, 8];

    const instrumentTuningPresets = {
      Guitar: [4, 11, 7, 2, 9, 4],
    };
    
    let selectedInstrument = "Guitar";
    let numberOfStrings = instrumentTuningPresets[selectedInstrument].length;
    
    const app = {
      init() {
        this.setupFretboard();
      },
      setupFretboard() {
        fretboard.innerHTML = "";
    
        // This creates the strings for the fretboard
        for (let i = 0; i < numberOfStrings; i  ) {
          let string = tools.createElement("div");
          string.classList.add("string");
          fretboard.appendChild(string);

          // This loops throught the stringGauge array but only manages to assign the
          //last value in the array which is 8. Subtracting 1-5 from i (e.g. stringGauge[i-3])
          // does change the height but for all of them.
          root.style.setProperty(`--string-height-${i 1}`, stringGauge[i]);
        }
      },
    };
    
    const tools = {
      createElement(el, content) {
        el = document.createElement(el);
        if (arguments.length > 1) {
          el.innerHTML = content;
        }
        return el;
      },
    };
    
    app.init();
:root {
  --fretboard-height: 300;
}

.fretboard {
  display: flex;
  flex-direction: column;
  background-image: url(../assets/images/maple.jpg);
  width: 100%;
  min-width: 1500px;
  height: calc(var(--fretboard-height) * 1px);
  margin-top: 50px;
}

.string {
  display: flex;
  position: relative;
  width: 100%;
  height: 100%;
}

.string:before {
  content: "";
  width: 100%;
  background: linear-gradient(#eee, #999);
  box-shadow: 76px 3px 10px #806233;
  z-index: 1;
  position: absolute;
  top: calc(var(--string-top-position) * 1px);
}

.string:nth-child(1):before {
    height: calc(var(--string-height-1) * 1px);
}
.string:nth-child(2):before {
    height: calc(var(--string-height-2) * 1px);
}
.string:nth-child(3):before {
    height: calc(var(--string-height-3) * 1px);
}
.string:nth-child(4):before {
    height: calc(var(--string-height-4) * 1px);
}
.string:nth-child(5):before {
    height: calc(var(--string-height-5) * 1px);
}
.string:nth-child(6):before {
    height: calc(var(--string-height-6) * 1px);
}
<div ></div>

  • Related