Home > Enterprise >  Javascript works until one of the options is choosen
Javascript works until one of the options is choosen

Time:07-21

I have a page that sorts things if you choose one of the options. The list of filters was too long so I added a div that shows/hides options. On page load some of the options are hidden via CSS with display: hidden. Code below just changes display from display: none to display: inline-block based on number of clicks.

var timesClicked = 0;

window.onload = function(){
    document.getElementById("filter_attribute_217").onclick = function(){
    timesClicked  ;
      if (timesClicked%2==0){
        hide();
      } else {
        show();
      }
 };

This is show() function

function show(){
document.getElementById("filter_attribute_69").style.display="inline-block";
document.getElementById("filter_attribute_70").style.display="inline-block";
document.getElementById("filter_attribute_72").style.display="inline-block";

//all those other options

document.getElementById("filter_attribute_217").innerHTML = "less";
document.getElementById("filter_attribute_217").style.borderTop = "1px dashed #e1e4e6";
document.getElementById("filter_attribute_68").style.borderBottom = "none";
document.getElementById("filter_attribute_87").style.borderBottom = "none";
}

And this is hide() function

function hide(){
document.getElementById("filter_attribute_217").innerHTML = "more";
document.getElementById("filter_attribute_217").style.borderTop = "1px dashed #e1e4e6"
document.getElementById("filter_attribute_69").style.display="none";
document.getElementById("filter_attribute_70").style.display="none";

//all those other options

document.getElementById("filter_attribute_103").style.display="none";
}

This is working perfectly until I choose one of the options which means that some other disappear. Then when trying to use more/less button I will get errors like this one:

Uncaught TypeError: Cannot read properties of null (reading 'style')
    at hide (user.js?sci=481:68:50)
    at document.getElementById.onclick (user.js?sci=481:58:9)

Clicking it again shows the same error just with show() function. I've tried checking if element exist in DOM structure with document.body.contains(YOUR_ELEMENT_HERE); but it always shows that all of the options exists. Checked it with

if(document.body.contains(element){
console.log("exists")
} else {
console.log("doesn't exist")
}

Console was always outputting "exists".

I then tried just ignoring the problem to see if others options will show with

function stoperror() {
return true;
};
window.onerror = stoperror;

But with the same result just without the error. I'm at my wit's end and I don't know why this is happening and how can I fix it. I need to add that all I can edit here is JavaScript and CSS. Thats why I made another option (filter_attribute_217) and made it into my show more/less button.

Any help is appreciated even if you tell me it's not possible so I won't think about it.

EDIT: Here's HTML code for basically every option. They only thing that is changing from option to option is id and href.

<div data-limit="3"  id="filter_attribute_104">
<h5>
Transparent
</h5>
<ul>
<li  style="margin-right:15px;">
<a title="tak" href="/pl/c/Balls/119/1/default/1/f_at_104_0/1">
<i src="/libraries/images/1px.gif" alt=""  ></i>
<span>tak </span>
<em>(56)</em>
</a>
</li>
</ul>

<div data-limit="3"  id="filter_attribute_68">
<h5>
White
</h5>
<ul>
<li  style="margin-right:15px;">
<a title="tak" href="/pl/c/Balls/119/1/default/1/f_at_68_0/1">
<i src="/libraries/images/1px.gif" alt=""  ></i>
<span>tak </span>
<em>(208)</em>
</a>
</li>
</ul>

I also have this in my JS code

window.addEventListener("DOMContentLoaded",(event) => {
document.getElementById("filter_attribute_217").innerHTML = "więcej";
 document.getElementById("filter_attribute_217").style.borderTop = "1px dashed #e1e4e6";
});

CodePudding user response:

This is an example with the code you provided. However your question is still not properly stated. I assume the HTML is getting generated dynamically? If so, I would make sure that the elements I'm trying to use are existing for sure while I call my JS. So I got rid of the window.onload you are using. Also, if you want to apply global changes, do not repeat the same things for each ID, just use a querySelectorAll('.classname') with a .forEach. Example:

let timesClicked = 0;

let show = () => {
  document.querySelector('.group-filter').innerHTML = 'LESS';
  document.querySelectorAll('.group-filter').forEach(elem => {
    elem.style.display = 'flex';
    // Other things...
  });
}

let hide = () => {
  document.querySelector('.group-filter').innerHTML = 'MORE';
  document.querySelectorAll('.group-filter').forEach(elem => {
    elem.style.display = 'none';
    // Other things...
  });
  // Restore the first element's display
  document.querySelector('.group-filter').style.display = 'flex';
}

document.getElementById('filter_attribute_104').addEventListener('click', () => {
  timesClicked  ;
  if (timesClicked % 2 == 0) hide();
  else show();
});
.hidden {display:none;}
<div data-limit="3"  id="filter_attribute_104">
  <h5>Transparent</h5>
  <ul>
    <li  style="margin-right:15px;">
      <a title="tak" href="#">
        <i src="/libraries/images/1px.gif" alt=""  ></i>
        <span>tak </span>
        <em>(56)</em>
      </a>
    </li>
  </ul>
</div>

<div data-limit="3"  id="filter_attribute_68">
  <h5>White</h5>
  <ul>
    <li  style="margin-right:15px;">
      <a title="tak" href="#">
        <i src="/libraries/images/1px.gif" alt=""  ></i>
        <span>tak </span>
        <em>(208)</em>
      </a>
    </li>
  </ul>
</div>

<div data-limit="3"  id="filter_attribute_168">
  <h5>Red</h5>
  <ul>
    <li  style="margin-right:15px;">
      <a title="tak" href="#">
        <i src="/libraries/images/1px.gif" alt=""  ></i>
        <span>tak </span>
        <em>(332)</em>
      </a>
    </li>
  </ul>
</div>

  • Related