Support » Fixing WordPress » Collapsible button inside a ul list does work in jsfiddle but not in WP

  • Resolved giannit

    (@giannit)


    I implemented a collapsible button, it works well in WP, but if I insert it in a ul list it doesn’t work, that is the button does not open.

    Then I tried to run the code in jsfiddle and there it does work.

    The only difference between the WP code and the jsfiddle code is in the javascript

    • on WP the var content is defined by this.parentElement.nextElementSibling;
    • on jsfiddle the var content is defined by this.nextElementSibling;

    This is due to the fact that

    • by removing parentElement on WP the button will break
    • by adding parentElement on jsfiddle the button will break

    Just for information, the javascript on WP is loaded in the footer.

    Is it possibile to fix the problem? Here is the jsfiddle demo.

    ____________________________________________________________________

    Below you can see jsfiddle vs WP

Viewing 10 replies - 1 through 10 (of 10 total)
  • Joy

    (@joyously)

    Is your HTML the same? (block editor might change it)
    Did you put your script inside a IIFE so that your variables are not global (or using existing globals)?

    giannit

    (@giannit)

    @joyously Thank you for the reply!

    Is your HTML the same?

    The only different thing is the <hr> line.

    Did you put your script inside a IIFE so that your variables are not global

    I’m not sure really sure about the IIFE thing, what I did is to put this script

    <script type="text/javascript">
    var coll = document.getElementsByClassName("col");
    var i;
    
    for (i = 0; i < coll.length; i++) {
      coll[i].addEventListener("click", function() {
        this.classList.toggle("active");
        var content = this.parentElement.nextElementSibling;
        if (content.style.maxHeight){
          content.style.maxHeight = null;
        } else {
          content.style.maxHeight = content.scrollHeight + "px";
        } 
      });
    }
    </script>

    in the site footer (using the “Insert headers & footers” plugin).
    Is it ok?

    • This reply was modified 1 month ago by  giannit.
    Joy

    (@joyously)

    Well, you didn’t say whether you used the Visual view or the Code view to enter the HTML (or even which editor), so that’s still an open question of the HTML being the same.

    The theme you use for WP could have defined one of the classes you are using (col or con or active), or even a plugin could have defined one, which could mess things up.

    For the JS, you have 3 global variables, and you shouldn’t have any. You can wrap your JS in a function so that they won’t be global.

    ( function() {
    //your code here
    } )();

    This defines the function and immediately calls it. That’s why it’s IIFE : Immediately Invoked Function Expression

    giannit

    (@giannit)

    @joyously Thank you for the support. The theme installed is underscore (downloaded from https://underscores.me/).

    I have tried again and done the following:

    • I copied the HTML from jsfiddle and pasted it in the Classic Editor (using the Classic Editor plugin)
    • I changed the names of the classes, now they are long and surely unique

    but still nothing happens when I click the button in the ul list.

    Now I’m about to change the JS as you said, but I’m not sure, should I delete the 3 variables? How to it properly?

    <script type="text/javascript">
    ( function() {
    var coll = document.getElementsByClassName("classecol");
    var i;
    
    for (i = 0; i < coll.length; i++) {
      coll[i].addEventListener("click", function() {
        this.classList.toggle("active");
        var content = this.parentElement.nextElementSibling;
        if (content.style.maxHeight){
          content.style.maxHeight = null;
        } else {
          content.style.maxHeight = content.scrollHeight + "px";
        } 
      });
    }
    } )();
    </script>
    • This reply was modified 1 month ago by  giannit.
    • This reply was modified 1 month ago by  giannit.
    giannit

    (@giannit)

    @joyously I found the problem

    HTML FROM CHROME INSPECT TOOL

    <div class="entry-content">
            <p>Does <button class="col">this</button> work?</p>
    <div class="con space" style="">
    <p>Yes!</p>
    <p></p></div>
    <hr>
    <ul>
    <li>Does <button class="col">this</button> work?
    <div class="con space">
    <p>Only in jsfiddle, not in WP!</p>
    </div>
    </li>
    <li style="">another line</li>
    </ul>
        </div>

    HTML FROM WP CLASSIC EDITOR

    Does <button class=col>this</button> work?
    <div class="con space"><p>Yes!<p/></div>
    
    <hr>
    
    <ul>
      <li>Does <button class=col>this</button> work?
          <div class="con space"><p>Only in jsfiddle, not in WP!</p></div></li>
      <li>another line</li>
    </ul>

    WP is inserting <p> tags, which are causing the problem. The first button is surrounded by p tags, so the .col and .con elements are no longer siblings, while the second button isn’t surrounded by p tags and so the elements are sibling.
    All the buttons work if I remove parentElement from the JS and I manually (using chrome inspect tool) remove the paragraph tags that were automatically added by the WP editor.

    So by placing this in the JS

    var content = this.nextElementSibling;
    if (!content) {
      content = this.parentElement.nextElementSibling;
    }

    both cases work.
    Do you think is still a good idea to put the script inside a IIFE? If yes, how to do it?

    • This reply was modified 1 month ago by  giannit.
    • This reply was modified 1 month ago by  giannit.
    Joy

    (@joyously)

    Good. I thought the HTML would be different.
    Yes, you should use the IIFE. It looks good from your previous post.

    giannit

    (@giannit)

    @joyously Thank you very much! There is another small problem, since somehwere in the text I have equations placed as images <img src...>, I noticed that if there are equations between .col and .con then the button doesn’t work anymore.
    How can I edit the JS in order to let the button work in this case too?

    Joy

    (@joyously)

    Instead of using the nextSibling, you could find the child .con.
    but have you ever seen <details> and <summary>?
    https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary
    https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details

    giannit

    (@giannit)

    @joyously Yes I already tried using details and summary but when I click on the details button the text surrounding it is moved down.
    I asked about this few days ago.

    Is it possibile to find the child .con even if it is not inside the .col?

    I tried with this, but the console says that conte is undefined

    ( function() {
    var coll = document.getElementsByClassName("col");
    var cont = document.getElementsByClassName("con");
    var i;
    
    for (i = 0; i < coll.length; i++) {
      coll[i].addEventListener("click", function() {
        this.classList.toggle("active");
        var content = this.parentElement.nextElementSibling;
        var conte = cont[i];
        console.log(content)
        console.log(conte)
        if (content.style.maxHeight){
          content.style.maxHeight = null;
        } else {
          content.style.maxHeight = content.scrollHeight + "px";
        } 
      });
    }
    } )();
    • This reply was modified 1 month ago by  giannit.
    giannit

    (@giannit)

    This seems to solve all the problems

    coll = document.getElementsByClassName("col");
    conn = document.getElementsByClassName("con");
    var i;
    for (i = 0; i < coll.length; i++) {
        coll[i].setAttribute('data-id', 'con' + i);
        conn[i].setAttribute('id', 'con' + i);
        coll[i].addEventListener("click", function() {
            this.classList.toggle("active");
            var content = document.getElementById(this.getAttribute('data-id'));
            if (content.style.maxHeight) {
                content.style.maxHeight = null;
            } else {
                content.style.maxHeight = content.scrollHeight + "px";
            }
        });
    }
Viewing 10 replies - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.