简体   繁体   中英

JavaScript loop throught and hide all divs except one

I have a big list of getElementsById that looks like this:

let ahSummerCamps = document.getElementById("aH-summerCamps");
let ahTrekking = document.getElementById("aH-trekking");
let bpLongDistanceHiking = document.getElementById("bp-longDistanceHiking");
let bpThruHiking = document.getElementById("bp-thruHiking");
let cOceanCruising = document.getElementById("c-oceanCruising");
let cRiverCruising = document.getElementById("c-riverCruising");
let eRecreationsEvent = document.getElementById("e-recreationsEvent");
let eSportsEvent = document.getElementById("e-sportsEvents");
let phEscortedTours = document.getElementById("ph-escortedTours");
let phIndependentTours = document.getElementById("ph-independentTours");
let sPhotographicSafari = document.getElementById("s-photographicSafari");
let sCyclingSafari = document.getElementById("s-cyclingSafari");
let sAsBackcountrySkiing = document.getElementById("sAs-backcountrySkiing");
let sAsDownhillSkiing = document.getElementById("sAs-downhillSkiing");
let vChildcare = document.getElementById("v-childcare");
let vConservationAndEnvironment = document.getElementById("v-conservationAndEnvironment");

I won't go into details, is there any way that I can loop throught all of them and for example hide all except bpLongDistanceHiking and bpThruHiking .

I had this function but that is not good way for sure:

function hideAllExceptbP() {
ahSummerCamps.style.display = "none";
ahTrekking.style.display = "none";
/* ... and for all of them like this except bpLongDistanceHiking and bpThruHiking  */
}

So on that way I need function for every element like:

function hideAllExceptaH() {
/* ... + 10 lines */

function hideAllExceptC() {
/* ... + 10 lines */

function hideAllExceptE() {
/* ... + 10 lines */

Function

function choice() {
backpacking.addEventListener("click", () => {
    hideBackpacking();
    hideSafari();
    hidePackageHoliday();
    showBackpackingOptions();
    console.log("Backpacking");
});

So as you can see from html I have 8 divs at start, and when user click on backpacking for example function should hide all divs except bpLongDistanceHiking and bpThruHiking

Full code calling function:

HTML:

    <div class="row">

    <!--main divs-->
    <div style="background-color: #4cc9f0" class="column" id="adventureHolidays"><p>Adventure Holidays</p></div>
    <div style="background-color: #4895ef" class="column" id="backpacking"><p>Backpacking</p></div>
    <div style="background-color: #4361ee" class="column" id="cruiseHolidays"><p>Cruise Holidays</p></div>
    <div style="background-color: #4361ee" class="column" id="eventTravel"><p>Event Travel</p>
    </div>
    <div style="background-color: #3a0ca3" class="column" id="packageHoliday"><p>Package Holiday</p></div>
    <div style="background-color: #480ca8" class="column" id="safari"><p>Safari</p></div>
    <div style="background-color: #560bad" class="column" id="skiingAndSnowboarding"><p>Skiing and Snowboarding</p>
    </div>
    <div style="background-color: #7209b7" class="column" id="volunteering"><p>Volunteering</p></div>

    <!--end on main divs-->

    <!--sub divs-->

    <div style="background-color: #4cc9f0" class="column" id="aH-summerCamps"><p>Summer camps</p></div>
    <div style="background-color: #4895ef" class="column" id="aH-trekking"><p>Trekking</p></div>
    <div style="background-color: #4361ee" class="column" id="bP-longDistanceHiking"><p>Long Distance Hiking</p></div>
    <div style="background-color: #4361ee" class="column" id="bP-thruHiking"><p>Thru Hiking</p></div>
    <div style="background-color: #3a0ca3" class="column" id="c-oceanCruising"><p>Ocean Cruising</p></div>
    <div style="background-color: #480ca8" class="column" id="c-riverCruising"><p>River Cruising</p></div>
    <div style="background-color: #560bad" class="column" id="e-recreationsEvent"><p>Recreations Events</p></div>
    <div style="background-color: #7209b7" class="column" id="e-sportsEvents"><p>Sports events</p></div>
    <div style="background-color: #4cc9f0" class="column" id="pH-escortedTours"><p>Escorted Tours</p></div>
    <div style="background-color: #4895ef" class="column" id="pH-independentTours"><p>Independent Tours</p></div>
    <div style="background-color: #4361ee" class="column" id="s-photographicSafari"><p>Photographic Safari</p></div>
    <div style="background-color: #4895ef" class="column" id="s-cyclingSafari"><p>Cycling Safari</p></div>
    <div style="background-color: #3a0ca3" class="column" id="sAs-backcountrySkiing"><p>Backcountry skiing</p></div>
    <div style="background-color: #560bad" class="column" id="sAs-downhillSkiing"><p>Downhill skiing</p></div>
    <div style="background-color: #4361ee" class="column" id="v-childcare"><p>Childcare</p></div>
    <div style="background-color: #4895ef" class="column" id="v-conservationAndEnvironment"><p>Conservation And
        Environment</p></div>
</div>
<script type="text/javascript" th:src="@{/js/index.js}"></script>

js:

    let adventureHolidays = document.getElementById("adventureHolidays");
let backpacking = document.getElementById("backpacking");
let cruiseHolidays = document.getElementById("cruiseHolidays");
let eventTravel = document.getElementById("eventTravel");
let packageHoliday = document.getElementById("packageHoliday");
let safari = document.getElementById("safari");
let skiingAndSnowboarding = document.getElementById("skiingAndSnowboarding");
let volunteering = document.getElementById("volunteering");
/*End of inserting main variables*/

/*sub variables*/

let ahSummerCamps = document.getElementById("aH-summerCamps");
let ahTrekking = document.getElementById("aH-trekking");
let bPLongDistanceHiking = document.getElementById("bP-longDistanceHiking");
let bPThruHiking = document.getElementById("bP-thruHiking");
let cOceanCruising = document.getElementById("c-oceanCruising");
let cRiverCruising = document.getElementById("c-riverCruising");
let eRecreationsEvent = document.getElementById("e-recreationsEvent");
let eSportsEvent = document.getElementById("e-sportsEvents");
let phEscortedTours = document.getElementById("ph-escortedTours");
let phIndependentTours = document.getElementById("ph-independentTours");
let sPhotographicSafari = document.getElementById("s-photographicSafari");
let sCyclingSafari = document.getElementById("s-cyclingSafari");
let sAsBackcountrySkiing = document.getElementById("sAs-backcountrySkiing");
let sAsDownhillSkiing = document.getElementById("sAs-downhillSkiing");
let vChildcare = document.getElementById("v-childcare");
let vConservationAndEnvironment = document.getElementById("v-conservationAndEnvironment");

/*end of subs variables*/

const divs = ["adventureHolidays", "backpacking", "cruiseHolidays", "eventTravel", "packageHoliday", "safari", "skiingAndSnowboarding", "volunteering", "aH-summerCamps", "aH-trekking", "bP-longDistanceHiking", "bP-thruHiking", "c-oceanCruising", "c-riverCruising", "e-recreationsEvent", "e-sportsEvents", "ph-escortedTours", "ph-independentTours", "s-photographicSafari", "s-cyclingSafari", "sAs-backcountrySkiing", "v-conservationAndEnvironment", "sAs-downhillSkiing", "v-childcare"]
    .map(id => document.getElementById(id)); // gives you an array of those elements

function hideAllDivsExcept(id) {
    for (const div of divs) div.hidden = !div.id === id;
}


window.onload = function () {
    choice();
};


/* start of function choice for user clicks*/

function choice() {
    backpacking.addEventListener("click", () => {
        hideAllDivsExcept('adventureHolidays');
        console.log("Backpacking");
    })
}

CSS:

 * {
    box-sizing: border-box;
}

/* Create three equal columns that floats next to each other */
.column {
    float: left;
    width: 33.33%;
    padding: 10px;
}

/* Clear floats after the columns */
.row:after {
    content: "";
    /*
    display: table;
    */
    clear: both;
}

I'm getting:

index.js:38 Uncaught TypeError: Cannot read properties of null (reading 'id')
at hideAllDivsExcept (index.js:38:47)
at HTMLDivElement.<anonymous> (index.js:51:9)

And that is this

    function hideAllDivsExcept(id) {
   this > for (const div of divs) div.hidden = !div.id === id;
}

One approach to the problem is as below, with explanatory comments in the code:

 // defining a named function to handle clicks on the 'filter' elements, that takes one // argument, a reference to the Event Object: const showRelevant = (evt) =>{ // caching a reference to the element to which the function is bound as the // event-handler: let source = evt.currentTarget, // retrieving the attribute-value from the custom data-* attribute, using the // HTMLElement.dataset API: category = source.dataset.category; // retrieving all <div> elements that do not have a "data-category" attribute which // are the children of a .row element; we iterate over that collection using // NodeList.prototype.forEach(): document.querySelectorAll('.row > div:not([data-category])').forEach( // using an Arrow function we pass in a reference to the current // Node of the NodeList over which we're iterating: (el) => { // we split the element's id property-value at the '-' character, // and retrieve the first element of the resulting Array: let prefix = el.id.split('-')[0]; // if the chosen category is exactly equal to 'all': if (category === 'all') { // we want to show all elements, therefore we set the hidden property // of every element to false; so every element is shown: el.hidden = false; } else { // otherwise, if the category is not equal to the prefix (above) the // assessment results in true and so the element is hidden; if the // category is equal to the prefix (therefore the current element is // one we wish to see) the assessment results in false, and so the // element is shown: el.hidden = category !== prefix; } }) }; // here we retrieve all child elements with a "data-category" attribute of a .row element, // and iterate over that NodeList with NodeList.prototype.forEach(): document.querySelectorAll('.row > [data-category]').forEach( // using an Arrow function we pass in a reference to the current Node of the NodeList, // and use EventTarget.addEventListener() to bind the showRelevant() function (note the // deliberate lack of parentheses) as the event-handler for the 'click' event: (el) => el.addEventListener('click', showRelevant) )
 :root { --h-1: 212; --h-2: 194; --s: 84%; --l: 62%; --cl: var(--l); --bgc-l: var(--l); } * { box-sizing: border-box; } .row { /* rather than using float, I've used display: flex: */ display: flex; /* the default of flex elements is: flex-direction: row; flex-wrap: nowrap; flex-flow is a shorthand to update both those values; here I've specified: flex-direction: row; flex-wrap: wrap; */ flex-flow: row wrap; /* adjust to taste, but this replicates the behaviour of floating in that elements on an incomplete row will align to the start of the row: */ justify-content: start; /* placing a 0.2em margin on the block-axis of the element; in a language such as English (left-to-right, top-to-bottom) that aligns to the top (margin-block-start) and bottom (margin-block-end) margins: */ margin-block: 0.2em; } .row > * { box-shadow: inset 0 0 0 3px currentColor, inset 0 0 0 4px #fff; /* basing the width of the elements - using the flex-basis property - to 33%: */ flex-basis: 33%; padding: 10px; } .row > *:nth-child(even) { /* using CSS custom properties to set color and background-color: */ color: hsl(var(--h-1) var(--s) var(--cl)); background-color: hsl(var(--h-2) var(--s) var(--bgc-l)); } .row > *:nth-child(odd) { color: hsl(var(--h-2) var(--s) var(--cl)); background-color: hsl(var(--h-1) var(--s) var(--bgc-l)); } .row > *:nth-child(even):hover, .row > *:nth-child(odd):hover { /* manipulating the CSS custom properties with the calc function to make the color darker (by decreasing the lightness) and the background-color lighter (by increasing the lightness): */ --cl: calc(var(--l)*0.5); --bgc-l: calc(var(--l) * 1.2); }
 <div class="row"> <!--main divs--> <!-- I've added a custom data-* attribute to each of the elements that would constitute a 'filter' element; the attribute-value is all the initial letters of the words written as camel-case, so: 'Adventure Holidays' => 'AH' => 'aH' --> <div id="adventureHolidays" data-category="aH"> <p>Adventure Holidays</p> </div> <div id="backpacking" data-category="bP"> <p>Backpacking</p> </div> <div id="cruiseHolidays" data-category="cH"> <p>Cruise Holidays</p> </div> <div id="eventTravel" data-category="eT"> <p>Event Travel</p> </div> <div id="packageHoliday" data-category="pH"> <p>Package Holiday</p> </div> <div id="safari" data-category="s"> <p>Safari</p> </div> <div id="skiingAndSnowboarding" data-category="sAS"> <p>Skiing and Snowboarding</p> </div> <div id="volunteering" data-category="v"> <p>Volunteering</p> </div> <div data-category="all"> <p>Show all</p> </div> <!--end on main divs--> </div> <!-- this isn't essential, but I prefer to separate the 'filters' from the elements to be filtered: --> <div class="row"> <!--sub divs--> <!-- I've changed the id prefix of these elements to match the 'data-category' value from the 'filter' <div> elements: --> <div id="aH-summerCamps"> <p>Summer camps</p> </div> <div id="aH-trekking"> <p>Trekking</p> </div> <div id="bP-longDistanceHiking"> <p>Long Distance Hiking</p> </div> <div id="bP-thruHiking"> <p>Thru Hiking</p> </div> <div id="cH-oceanCruising"> <p>Ocean Cruising</p> </div> <div id="cH-riverCruising"> <p>River Cruising</p> </div> <div id="eT-recreationsEvent"> <p>Recreations Events</p> </div> <div id="eT-sportsEvents"> <p>Sports events</p> </div> <div id="pH-escortedTours"> <p>Escorted Tours</p> </div> <div id="pH-independentTours"> <p>Independent Tours</p> </div> <div id="s-photographicSafari"> <p>Photographic Safari</p> </div> <div id="s-cyclingSafari"> <p>Cycling Safari</p> </div> <div id="sAS-backcountrySkiing"> <p>Backcountry skiing</p> </div> <div id="sAS-downhillSkiing"> <p>Downhill skiing</p> </div> <div id="v-childcare"> <p>Childcare</p> </div> <div id="v-conservationAndEnvironment"> <p>Conservation and Environment</p> </div> </div>

JS Fiddle demo .

References:

Add an id to your main div with class 'row', ex daDiv then iterate and perform whatever you want checking id attribute of each one

$('#daDiv').children('div').each(function () {
  if ($(this).attr('id') !== 'bP-longDistanceHiking' && $(this).attr('id') !== 'bP-thruHiking') {
    $(this).hide();
  }
});

CodePen

Example

UPDATE

You can even make a function

function hideExcept(arr) {

  $('#daDiv').children('div').each(function () {
    if (!arr.includes($(this).attr('id')))
      $(this).hide();
  });
}

hideExcept(['bP-longDistanceHiking', 'bP-thruHiking']); // hide all except bP-longDistanceHiking and bP-thruHiking

Put your id s in an array, map() to the respective div elements, so you have an iterable list of the divs.

Then use a function that accepts an id string as a parameter, and call it.

const divs = ["aH-summerCamps","aH-trekking","bp-longDistanceHiking","bp-thruHiking","c-oceanCruising","c-riverCruising","e-recreationsEvent","e-sportsEvents","ph-escortedTours","ph-independentTours","s-photographicSafari","s-cyclingSafari","sAs-backcountrySkiing","v-conservationAndEnvironment","sAs-downhillSkiing","v-childcare"]
    .map(id => document.getElementById(id)); // gives you an array of those elements

function hideAllDivsExcept(id) {
    for (const div of divs) div.hidden = !div.id === id;
}

// then call like this e.g.:
hideAllDivsExcept('bp-longDistanceHiking');

I'd use jquery for this

 $("#div1").show()
 $("#div1").hide()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM