1

I'm in no way a coder but I got an idea. I create websites with the tool webflow and when you set up a CMS collection with a rich-text-field the client can add headlines including h1, which I don't want them to. My idea is that with javascript replace every h1 with h2 within a class (so the page title doesn't get changed).

So far I manage to create this:

var e = document.getElementsByTagName('h1')[0];

var d = document.createElement('h2');
d.innerHTML = e.innerHTML;

e.parentNode.replaceChild(d, e);
<h1>Don't change this</h1>
<div class="the-class">
  <h1>Replace this with h2</h1>
</div>

7
  • Provide the HTML code please. Commented Apr 17, 2023 at 11:26
  • Do you need the HTML code? Here: <div class="the-class"><h1>Heading</h1><p>some content</p></div> Commented Apr 17, 2023 at 11:42
  • 3
    When we ask for the HTML (or CSS, JavaScript...), we're asking for it to be added to the question; code in comments isn't really readable, and those trying to help shouldn't have to read the comments (which are prone to deletion) to understand the question. On this occasion I've added the code for you, and converted it into a runnable snippet. Commented Apr 17, 2023 at 11:54
  • I don't know what approach Webflow uses, but changing the h1 element after the page has been rendered will probably have no effect. Commented Apr 17, 2023 at 12:01
  • Ah, so this might not be posable? Commented Apr 17, 2023 at 12:03

3 Answers 3

5

You can use querySelector and use a proper CSS selector to match only <h1> elements inside .the-class:

for (let header of document.querySelectorAll('.the-class h1')) {
    // I gave these variables real names, very good practice
    var new_header = document.createElement('h2');
    new_header.innerHTML = header.innerHTML;

    header.parentNode.replaceChild(new_header, header);
}
<h1>Don't change this</h1>
<div class="the-class">
  <h1>Replace this with h2</h1>
</div>

This will replace all h1 elements anywhere inside .the-class

Sign up to request clarification or add additional context in comments.

1 Comment

very elegant and clean :) before "header.parentNode.replaceChild(new_header, header);" one could also move classes and attributes from the old node to the new_header.
0

querySelectorAll to select the h1s inside of a class, createElement to make the new h2, and replaceWith to swap.

document.querySelectorAll('.the-class h1').forEach(h1 => { 
  const h2 = document.createElement('h2');
  h2.innerHTML = h1.innerHTML;
  h1.replaceWith(h2);
});
h1 {
  color: red;
}

h2 {
  color: blue;
}
<h1>Don't change this</h1>
<div class="the-class">
  <h1>Replace this with h2</h1>
</div>
<div class="the-class">
  <h1>And Replace this with h2</h1>
</div>

Comments

0

[edit 2023/04/18] Here is a utility function to change the name of any tag, whilst maintaining the properties of the original. It replaces the tagname part of outerHTML.

Note: the browser automagically replaces the end tag.

See also.

/* 
   Simplified alternative: a generic function 
   to change the tag name of an element by 
   changing its outerHTML.
   This conserves attributes/classNames of the
   original element
*/
const replaceElem = (elem, nwTag) => 
  elem.outerHTML = elem.outerHTML
    .replace(RegExp(`^<${elem.tagName}`, `i`), `<${nwTag}`);

document.querySelectorAll(`.the-class h1`)
   .forEach(h1 => replaceElem(h1, `h2`));
document.querySelectorAll(`div`)
  .forEach(div => replaceElem(div, `span`));

/* 
original snippet
-----------------
document.querySelectorAll(`.the-class h1`)
  .forEach(h1 => h1.replaceWith( Object.assign(
    document.createElement(`h2`), {
      innerHTML: h1.innerHTML,
      className: [...(h1.classList || [])].join(` `)
    } ) ) );
*/
body {
  font: normal 12px/15px verdana, arial, sans-serif;
}
h1 { color: red; }
h2.italic { font-style: italic; }
h2.blue { color: blue; }
h2[data-header] { background-color: #eee; }
span.the-class { display: block; }
span.the-class::after {
  content: 'Once I was <div> 😔';
  font-size: 1.2rem;
  margin-left: 2rem;
}
<h1>Don't change this</h1>
<div class="the-class">
  <h1>Replace this with h2</h1>
</div>
<div class="the-class">
  <h1 class="blue" data-header="2">Replace this with h2 too</h1>
</div>
<div class="the-class">
  <h1 class="italic blue">He! I want to be replaced too!</h1>
</div>

2 Comments

as there could be spans in h1/h2 titles or even other tags you would remove them by using textContent or am I wrong? Can you use innerHTML here too?
You can use innerHTML too, sure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.