Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <!--
   100 <details> and <summary> tag blocks are created in the JavaScript.
  -->

<link href="https://fonts.googleapis.com/css2?family=Ranchers&display=swap" rel="stylesheet">

<h2>100 Random Dad Jokes out of a Possible <span id="jokeTotal">???</span> Jokes...</h2>
<div id="content">
</div><!-- content -->
<button 
        title="Click to display a Different 100 Dad Jokes!"
        id="pickBtn">Pick Another 100...</button>
              
            
!

CSS

              
                

body {
  background-image: linear-gradient(to right, red, yellow 100%);
}

h2 { 
  font-family: 'Ranchers', cursive;
  font-size:28pt;
  padding-top:1px;
  margin-top:1px;
  margin-left:10px;
  color:#ffdb4d;
  text-shadow: -2px 2px 8px #0033cc;
}

details {
  padding-top:16px;
  padding-bottom:16px;
  padding-left:10px;
  border: solid gray .5px;
  margin-top:8px;
  margin-bottom:8px;
  border-radius:10px;
  font-family:tahoma;
  min-width:550px; 
  color:#ff6600;
  background:white;
  
}

summary:focus {
  outline:none;
  outline-style:none;
  -webkit-box-shadow: none;
  box-shadow: none;
}

#pickBtn {
  position:absolute;
  top:18px;
  right:5px;
  display:none;
  background: #4d79ff;
  border:solid black 1px;
  border-radius:8px;
  width:180px;
  height:40px;
  font-weight:bold;
  color:white;
  font-size:12pt;
  cursor:pointer;
}

.punchline {
  padding-left:55px;
  padding-top:3px;
  color:black;
}


#content {
  position:absolute;
  top:60px;
  padding:6px;
  left:10px;
  display: grid;
  grid-column-gap: 18px;
  grid-row-gap: 2px;
  grid-template-columns: auto auto auto;
}

@media screen and (max-width: 1750px) {  
   #content{
     grid-template-columns: auto auto;
   }  
  
  
}

@media screen and (max-width: 1170) {  
   #content{
     grid-template-columns: auto;
   }  
  
  h2 {
    font-size:22pt;
  }
}

.summaryCntr {
  position:relative;
  left:10px;
  width:75%;
  top:0px;
}

.jokeNum {
  color:black;
  position:absolute;
  left:4px;
  top:-25px;
  color:white;
  font-weight:bold;
  font-size:9pt;
  background:red;
  width:35px;
  height:35px;
  line-height:35px;
  overflow:hidden;
  text-align:center;
  border-radius:15px;
}

.jokeLine {
  color:black;
  position:relative;
  left:45px;
  top:-20px;
}



.bk1 {
  background-image: linear-gradient(to bottom right, #e6f2ff, #99caff 100%);
}


.bk2 {
  background-image: linear-gradient(lightblue, yellow 100%);
}


.bk3 {
  background-image: linear-gradient(to right, lightblue, yellow 100%);
}


.bk4 {
  background-image: linear-gradient(#00e600, #ccffcc 100%);
}


.bk5 {
  background-image: linear-gradient(#ffe066, #ccccff 100%);
}

.bk6 {
  background-image: linear-gradient(#ff99e6, #f2ffcc 100%);
}
              
            
!

JS

              
                

let nLoadCount = 0;
let bInitJokesDisplayed = false;
let jokesByIndex = [];
let shuffledJokesByIndex = [];
const nJokeLimitPerPage = 30;
let contentNd,pickBtnNd,jokeTotalNd;
let nLastJokeIdx = -1;
let bLoadNextFromBtn = false;


function pageSetup() {
  contentNd = document.getElementById("content");
  pickBtnNd = document.getElementById("pickBtn");
  jokeTotalNd = document.getElementById("jokeTotal");
  
  pickBtnNd.addEventListener('click', pickAnotherClicked);
  
  loadDadJokes()
}


function loadDadJokes() {
  console.log("loadDadJokes() called!")
  loadDadJokePage(1);
}



// See:  https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

function loadDadJokePage(nPageNum) {
  console.log("loadDadJokePage() called!")
  let sUrl = 'https://icanhazdadjoke.com/search?limit='+nJokeLimitPerPage+'&page='+nPageNum;
  console.log("sUrl='"+sUrl+"'")
  let requestHeaders = {Accept: "application/json"};
  let secondParam = {headers:requestHeaders};
  
  console.log("About to attempt fetch...")
	fetch(sUrl, secondParam)
  .then(response => {
    console.log("got a response back")
    return response.json();
  })
  .then(data => {
    const resultsByIndex = data.results;
    const nMax = resultsByIndex.length;
    if (nMax === 0) {
      displayJokeTotal()
      shuffleLoadedJokes()
      pick100Jokes();
      displayPickedJokes()
      return;
    } // end if
    
    for (let n=0;n<nMax;n++) {
      jokesByIndex.push(resultsByIndex[n])
      nLoadCount = nLoadCount + 1      
    } // next n
    
    if (nLoadCount > 99 && !bInitJokesDisplayed) {
        // put 100 jokes up as soon as possible...
        shuffleLoadedJokes() // ... first shuffle the total list...
        pick100Jokes(); // ... then, clear our 100 joke array, then pick the first 100 jokes and put them into that array
        displayPickedJokes() // ... finally, display the jokes in that array
      } // end if
    
    if (nMax===nJokeLimitPerPage) {
      // try to get another page
      loadDadJokePage(nPageNum+1)
      return;
    } else {
      // assume that we have loaded all the pages of jokes!
      displayJokeTotal()
      shuffleLoadedJokes()
      pick100Jokes();
      displayPickedJokes()
    } // end if
    
  })
  .catch(err => {
    console.log("Got a fetch error")
    console.log(err)
    debugger
  })
} // end of loadDadJokePage()



/*
  Just so user knows how many possible jokes there are possible to be displayed...
 */
function displayJokeTotal() {
  jokeTotalNd.innerText = (jokesByIndex.length)+""
} // end of function displayJokeTotal()



/*
  shuffle our overall jokes array
 */
function shuffleLoadedJokes() {
  shuffledJokesByIndex = shuffleIndexedArray(jokesByIndex)
} // end of function shuffleLoadedJokes()



/*
   fetches the next 100 jokes out of the main array and displays them!
 */
function pickAnotherClicked() {
  const s=[];
  
  s.push("<center>")
  s.push("<br>&nbsp;<br><h2>On Moment... <br>")
  s.push("Fetching Another 100 'Jokes'... <br></h2>")
  s.push("</center>")
  contentNd.innerHTML = s.join("")  
  pickBtnNd.style.display = "none";
  bLoadNextFromBtn = true;
  pick100Jokes()
  bLoadNextFromBtn = false;
  setTimeout(displayPickedJokes, 1300); // we want time for the user to read 'One Moment' msg before displaying next 100 jokes.
} // end of function  pickAnotherClicked()




function pick100Jokes() {
  n100JokesByIndex = []; // clear any previous stuff out
    
  // loop 100 times...
  for (let n=0;n<100;n++) {
    nLastJokeIdx = nLastJokeIdx + 1;
    
    if (nLastJokeIdx > shuffledJokesByIndex.length ) {
      if (bLoadNextFromBtn) {
        shuffleLoadedJokes()
      } // end if
      
      nLastJokeIdx = 0;
      
    } // end if (nLastJokeIdx > shuffledJokesByIndex.length )
    
    n100JokesByIndex.push(shuffledJokesByIndex[nLastJokeIdx]);
  } // next n
    
} // end of function pick100Jokes()

//pickBtn

window.addEventListener('load', pageSetup);


// temp
//window.addEventListener('resize', abc);

function abc() {
  pickBtnNd.innerHTML = ""+window.innerWidth;
}

function displayPickedJokes() {
  const nMax = n100JokesByIndex.length
  let s=[];
  
  for (let n=0;n<nMax;n++) {
    let jokeObj = n100JokesByIndex[n];
    let sJokeText = jokeObj.joke;
    let sSummary = "<div class='jokeNum'>#"+(n+1)+":</div>"
    let sPunchLine = sJokeText;
    let nPos = sJokeText.indexOf("?")
    if (nPos > -1 && nPos < sJokeText.length - 3) {
      let jokeParts = sJokeText.split("?")
      sSummary = sSummary + "<span class='jokeLine'> <b>Q:</b> "+jokeParts[0]+"?</span>";
      sPunchLine = "<b>A:</b> "+jokeParts[1];
    } else {
      sSummary = sSummary + "<span class='jokeLine'> Expand to see Joke...</span>";
    } // end if
    
    let nClassNum = intRnd(6)+1;
    
    s.push("<details class='bk"+nClassNum+"'>")
    s.push("<summary>")
    s.push("<div class='summaryCntr'>")
    s.push(sSummary)    
    s.push("</div>"); // summaryCntr
    s.push("</summary>")
    s.push("<div class='punchline'>")
    s.push(sPunchLine)   
    s.push("</div>")
    s.push("</details>")
  } // next n
  
  contentNd.innerHTML = s.join("")
  pickBtnNd.style.display = "block";
  bInitJokesDisplayed = true;
  
} // end of displayPickedJokes()



/*
  for now...
 */
function intRnd(nMax) {
  return Math.floor(Math.random() * nMax);
} // end of function intRnd()



/************************************************************** 
   Return a Randomly Shuffled version of a JavaScript 
   indexed array    that was inputted...

   The optional 2nd param is good for stuff like randomized messages.
   To make it impossible for the first item in the shuffled
   array to be the Same as the last item in the previously
   shuffled array!
 **************************************************************/
 function shuffleIndexedArray(inpArr,niStartPadding) {
    let wrkArr = [];
    let outArr = [];
    let nMax = inpArr.length;
    let nStartPadding = 0;
    
    if (typeof niStartPadding === "number") {
        nStartPadding = niStartPadding;
    } // end if

    // we don't modify the original input array...

    for (let n=0;n<nMax-nStartPadding;n++) {
        wrkArr.push(inpArr[n]);
    } // next n

    do {
        let idx = intRnd(wrkArr.length);
        outArr.push(wrkArr[idx]);
        wrkArr.splice(idx,1); // remove from wrkArr[] !
    } while(wrkArr.length > 0)

    if (nStartPadding > 0) {
        let paddingArr = [];
        for (let n=nMax-nStartPadding;n<nMax;n++) {
            paddingArr.push(inpArr[n])
        } // next n

        let shuffledPaddingArr = shuffleIndexedArray(paddingArr)
        outArr = outArr.concat(shuffledPaddingArr);
    } // end if (nStart > 0)

    return outArr; // return resulting array


 } // end of shuffleIndexedArray()
              
            
!
999px

Console