skip to Main Content

So, I’ve got two problems with my javascript code. I’ll try to make it as short as possible and only copy parts that are necessary for the problem.

I have this html code (it’s not my fault that every li looks different):

    <li>
        <span style="font-family:arial, helvetica, sans-serif;">Siehe <a href="Link 1" rel="">Text 1</a>.</span>
    </li>
    <li>
        <span style="font-family:arial, helvetica, sans-serif;">Siehe</span> <a href="Link 1" rel="">Text 2</a>.<span style="font-family:arial, helvetica, sans-serif;"> </span>
    </li>
    <li>
        Siehe <a href="Link 1" rel="">Text 3</a>.
    </li>

And here comes the necessary javascript code for my problems. First, I delete every span element. After that I want to replace the "a href" parts and increase the number of the new string.

var neu = document.getElementById("ausgabe").value;             
var nummer = 0;
function getNextDlcNumber() {
    return ++nummer;
}

var ersetzen = neu
.replace(/<span.*?>(.*?)</span>/g, "$1") // Gets rid of every span
.replace(/s<li>nssSiehes*<a href=".*?" rel="">(.*?)</a>.ns</li>/g, "t<li>nttSiehe <a class="trophiesAnkerLink" href="#dlc" + getNextDlcNumber() + "" rel="">$1</a>.nt</li>")); // Replaces a href with increasing dlc numbers

document.getElementById("ausgabe").value = ersetzen;

There are two problems with this:

  1. The first and third "a href" are replaced successfully. But the second one isn’t and I can’t figure out why. I think it has something to do with the span tag between "Siehe" and the start of the "a" tag, however the span should get deleted due to the first replace so I’m not sure if that’s what causes the problem. I tried using "Siehes*<a", "Siehe <a" as well as an or using | that contained the "</span>" but none of that worked.

  2. The number after "#dlc" isn’t increasing, it just stays at "#dlc1" even for the third one. Do I need to do that in a different way?

Here’s the output after using the js:

    <li>
        Siehe <a class="trophiesAnkerLink" href="#dlc1" rel="">Text 1</a>.
    </li>
    <li>
        Siehe <a href="Link 1" rel="">Text 2</a>. 
    </li>
    <li>
        Siehe <a class="trophiesAnkerLink" href="#dlc1" rel="">Text 3</a>.
    </li>

I hope I posted every necessary information. If not, I can provide more. Thanks for your help in advance 🙂

3

Answers


  1. Actually it’s a very bad idea to manually parse and edit DOM elements contents, you don’t have to complicate your life and reinvent the wheel.

    You can use JS built-in methods to directly access .href attribute of your link elements and change it directly, without even using .replace() method.

    This is how can be your code:

    let elements = Array.from(document.getElementById("ausgabe").querySelectorAll("a"))
    elements.forEach(a => a.href = "#dlc" + getNextDlcNumber());
    

    You can see it can just be a one liner code, to do all what you were trying to achieve.

    Demo:

    var nummer = 0;
    
    function getNextDlcNumber() {
      return ++nummer;
    }
    
    Array.from(document.getElementById("ausgabe").querySelectorAll("a")).forEach(a => a.href = "#dlc" + getNextDlcNumber());
    <div id="ausgabe">
      <li>
        <span style="font-family:arial, helvetica, sans-serif;">Siehe <a href="Link 1" rel="">Text 1</a>.</span>
      </li>
      <li>
        <span style="font-family:arial, helvetica, sans-serif;">Siehe</span> <a href="Link 1" rel="">Text 2</a>.<span style="font-family:arial, helvetica, sans-serif;"> </span>
      </li>
      <li>
        Siehe <a href="Link 1" rel="">Text 3</a>.
      </li>
    
    </div>

    You can check the new values of your linksby hovering them, et voilà.

    Login or Signup to reply.
  2. As others have stated in comments and answers, using the DOM to parse the value in the textarea is much easier to generate the output you want. Below are two versions (DOM and text parsing) so that you can compare the simplicity of using DOM parsing versus text parsing.

    (Both code versions can be rewritten and condensed. They are verbose to make the samples easier to debug.)

    DOM parsing version:

    document.querySelector("#parse-textarea-dom").addEventListener("click", parseDom);
    
    const inputHtml = `<li>
            <span style="font-family:arial, helvetica, sans-serif;">Siehe <a href="Link 1" rel="">Text 1</a>.</span>
        </li>
        <li>
            <span style="font-family:arial, helvetica, sans-serif;">Siehe</span> <a href="Link 1" rel="">Text 2</a>.<span style="font-family:arial, helvetica, sans-serif;"> </span>
        </li>
        <li>
            Siehe <a href="Link 1" rel="">Text 3</a>.
        </li>`;
    
    document.querySelector("#ausgabe").textContent = inputHtml;
    
    let number = 0;
    
    function getNextDlcNumber() {
      return ++number;
    }
    
    function parseDom() {
      number = 0;
      const neu = document.getElementById("ausgabe").value;
      const ulElem = document.createElement("ul");
      ulElem.innerHTML = neu;
      ulElem.querySelectorAll("li").forEach(liElem => {
        getNextDlcNumber();
        const anchElem = liElem.querySelector("a");
        anchElem.href = `#dlc${number}`;
        anchElem.className = "trophiesAnkerLink";
        liElem.removeChild(liElem.firstElementChild);
        liElem.textContent = "Siehe ";
        liElem.appendChild(anchElem);
      });
      document.getElementById("ausgabe-list-dom").appendChild(ulElem);
      document.getElementById("ausgabe-list-dom").scrollIntoView();
      document.getElementById("ausgabe-result").value = ulElem.innerHTML;
    }
    <textarea id="ausgabe" rows="10" cols="50"></textarea>
    <textarea id="ausgabe-result" rows="10" cols="50"></textarea>
    <div>
      <button id="parse-textarea-dom">DOM Parse</button>
    </div>
    <ul id="ausgabe-list-dom"></ul>

    The text parsing version for the same output:

    document.querySelector("#parse-textarea-text").addEventListener("click", parseText);
    
    const inputHtml = `<li>
            <span style="font-family:arial, helvetica, sans-serif;">Siehe <a href="Link 1" rel="">Text 1</a>.</span>
        </li>
        <li>
            <span style="font-family:arial, helvetica, sans-serif;">Siehe</span> <a href="Link 1" rel="">Text 2</a>.<span style="font-family:arial, helvetica, sans-serif;"> </span>
        </li>
        <li>
            Siehe <a href="Link 1" rel="">Text 3</a>.
        </li>`;
    
    document.querySelector("#ausgabe").textContent = inputHtml;
    
    // stackoverflow.com/questions/31412765/regex-to-remove-white-spaces-blank-lines-and-final-line-break-in-javascript
    function condenseHTML(html) {
      return html.split('n')
        .map(s => {
          return s.replace(/^s*|s*$/g, "");
        })
        .filter(x => {
          return x;
        })
        .join("");
    }
    
    function getStringBetween(str, start, end) {
      const result = str.match(new RegExp(start + "(.*)" + end));
      return Array.isArray(result) && result.length > 1 ? result[1] : "";
    }
    
    let number = 0;
    
    function getNextDlcNumber() {
      return ++number;
    }
    
    function parseText() {
      number = 0;
      const neu = document.getElementById("ausgabe").value;
    
      const condensed = condenseHTML(neu);
    
      // Remove every <span> element
      const spanRemoved = condensed.replace(/<span.*?>(.*?)</span>/g, "$1");
    
      const pattern = /<li>(.*?)</li>/gi;
    
      const ersetzen = spanRemoved.replace(pattern, (li) => {
        getNextDlcNumber();
        const anchor = li.match(/<a href=".*?" rel="">(.*?)</a>/gs);
        const anchorText = Array.isArray(anchor) ?
          getStringBetween(anchor[0], '>', '<') : "";
        const replaceStr = `<li>
        Siehe <a class="trophiesAnkerLink" href="#dlc${number}" rel="">${anchorText}</a>.
    </li>`;
        return replaceStr + "n";
      });
    
      document.getElementById("ausgabe-list-text").innerHTML = ersetzen;
      document.getElementById("ausgabe-list-text").scrollIntoView();
      document.getElementById("ausgabe-result").value = ersetzen;
    }
    <textarea id="ausgabe" rows="10" cols="50"></textarea>
    <textarea id="ausgabe-result" rows="10" cols="50"></textarea>
    <div>
      <button id="parse-textarea-text">Text Parse</button>
    </div>
    <ul id="ausgabe-list-text"></ul>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search