Home > Net >  Is there a cleaner way to append a span to H3 when creating elements? Feel like I overdid the code o
Is there a cleaner way to append a span to H3 when creating elements? Feel like I overdid the code o

Time:09-02

I have the following code:

const calendarHeading = (month, year) =>{
    let monthH3 = document.createElement('h3')
    monthH3.classList.add('calendar__heading-month')
    monthH3.innerHTML = monthObjects[month].month

    let yearSpan = document.createElement('span')
    yearSpan.classList.add('calendar__heading-year')
    yearSpan.innerHTML = year


    let targetDiv = document.querySelector('.calendar__heading')

    targetDiv.appendChild(monthH3)
    document.querySelector('.calendar__heading-month').appendChild(yearSpan)

};

Pretty much I am creating an H3 element and a Span element.

I then attach the h3 element to the already created div in the html.

I then attach the span to the newly created h3 node.

My question is, is there a way to do this in one line? Or am I overthinking things, I am noob i am sorry :(

CodePudding user response:

You're appending two separate elements to two other separate elements, so there need to be (or should be) at least two separate statements. This could be done pretty concisely by just writing out the HTML markup instead of constructing elements with .createElement.

const calendarHeading = (month, year) =>{
    document.querySelector('.calendar__heading').insertAdjacentHTML(
        'beforeend',
        `<h3 >${monthObjects[month].month}</h3>`
    );
    document.querySelector('.calendar__heading-month').insertAdjacentHTML(
        'beforeend',
        `<span >${year}</span>`
    );
};

That said, both this code (and your original code) has a potential vulnurability - if the year argument or the monthObjects object is untrustworthy (such as from an external API), inserting HTML can result in arbitrary code execution, which would be a problem in some circumstances. If that's something you might be concerned about, things will have to become more verbose (such as with your original code plus use of .textContent instead of .innerHTML).

CodePudding user response:

that should be enough...

const calendarHeading = (month, year) =>
  {
  let targetDiv = document.querySelector('.calendar__heading')
    , monthH3   = document.createElement('h3')

  monthH3.className = 'calendar__heading-month'
  monthH3.innerHTML = `${monthObjects[month].month}<span >${year}</span>`

  targetDiv.appendChild(monthH3)
  }

CodePudding user response:

This would be one way to do it, it isn't exactly less lines per se, but it feels less convoluted to me. Added some comments in the code that I hope you find helpful.

I am by no means an expert, just trying to provide a different perspective.

This solution makes use of template literals and the DOMParser object to achieve what I believe you are asking.

Happy coding!

const calendarHeading = (month, year) => {
  //Not sure what your month object looks like, but adjust as needed
  const monthObject = {
    Jan: "I am Jan",
    Feb: "I am Feb",
    Mar: "I am Mar",
  }

  //Write up your HTML as you desire using template literals
  let htmlString = `<h3 >${monthObject[month]} <span >${year}</span></h3>`;

  //Create a DOMParser object, parse your HTML string
  const parser = new DOMParser();
  const newNode = parser.parseFromString(htmlString, "text/xml");

  //Select target element and append using the new node
  let targetDiv = document.querySelector('.calendar__heading')
  targetDiv.appendChild(newNode.documentElement);
};

//Log to console
calendarHeading("Jan", 1991)
body {
  background: transparent;
  /* Make it white if you need */
  color: #000;
  padding: 0 24px;
  margin: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="src/style.css">
</head>

<body>
  <div ></div>
  <script src="src/script.js"></script>
</body>

</html>

  • Related