Random Joke Generator
Relevant source files
The following files were used as context for generating this wiki page:
The Random Joke Generator is a core interactive feature of the Norm Macdonald Archive redesign. Its primary purpose is to surface content from the joke database in an engaging way, allowing users to quickly view a random joke without searching or browsing the entire collection. The feature is implemented in several distinct ways across the site, including a prominent modal on the main jokes page, a "Featured Joke" on the homepage, and a "Spotlight Joke" in the alternative codex-design.
This system is built with vanilla JavaScript, fetching joke data from a static JSON file and dynamically updating the DOM. It includes functionality for displaying the joke, showing its metadata, fetching another joke, and sharing it.
Sources: README.md:10-13, redesign/README.md:10-13, redesign/jokes.html:80-89, redesign/index.html:117-133, codex-design/index.html:25-35
Core Implementations
The Random Joke Generator appears in three different forms across the project, each tailored to its context.
| Feature Name | Location | User Interface | Trigger |
|---|---|---|---|
| Random Joke Modal | jokes.html | A full-screen modal overlay. | Random Joke button, Another One button, 'R' key. |
| Featured Joke | index.html | A static card on the homepage. | Another Joke button, clicking the card, auto-refreshes every 15s. |
| Spotlight Joke | codex-design/index.html | A static card in the "Spotlight" section. | Shuffle Spotlight button. |
Sources: redesign/jokes.html:81, redesign/index.html:118, 127, 305, codex-design/index.html:26-27
Architecture and Logic
The generator's logic is primarily handled by client-side JavaScript, which manages state, fetches data, and manipulates the DOM.
Sources: redesign/script.js, redesign/index.html:222-311
State Management
A global state object is used to manage the application's data, including the currently displayed random joke.
// redesign/script.js:5-13
const state = {
jokes: [],
filteredJokes: [],
currentPage: 1,
jokesPerPage: 10,
searchTerm: '',
selectedGuest: '',
currentRandomJoke: null
};
The currentRandomJoke property holds the complete joke object currently displayed in the modal, which is essential for the "Share" functionality.
Sources: redesign/script.js:5-13, 595-597
Data Flow and Joke Selection
The process begins with the user's action, which triggers a JavaScript function to select a joke from the master list and render it to the UI.
This diagram illustrates the sequence of events when a user requests a random joke from the jokes.html page.
Key Functions
The core logic is encapsulated in several key functions within redesign/script.js and the inline script in redesign/index.html.
| Function | File | Description |
|---|---|---|
init() | redesign/script.js | Initializes the application, including event listeners and data loading. |
loadJokes() | redesign/script.js | Asynchronously fetches jokes-data.json and populates state.jokes. |
showRandomJoke() | redesign/script.js | Selects a random joke, updates the modal's DOM elements, and displays the modal. |
closeRandomJoke() | redesign/script.js | Hides the random joke modal and restores body scroll. |
loadFeaturedJoke() | redesign/index.html | Fetches joke data and manages the display and auto-rotation of the "Featured Joke" on the homepage. |
shareJoke() | redesign/script.js | Uses the navigator.share API or falls back to copyToClipboard to share the current joke text. |
Sources: redesign/script.js:61-75, 405-439, 445-457, 609-613, redesign/index.html:222-311
Event Handling
User interactions are managed through event listeners set up in the initEventListeners function.
This flowchart shows how user input is handled.
UI Components
The generator relies on specific HTML elements defined in redesign/jokes.html and redesign/index.html.
Random Joke Modal (#random-modal)
The modal is the primary UI for the random joke feature on the jokes.html page. It is a container that is hidden by default and becomes visible by adding an active class.
<!-- redesign/jokes.html:201-248 -->
<div id="random-modal" class="modal">
<div class="modal-overlay"></div>
<div class="modal-content">
<button class="modal-close" aria-label="Close modal">
<!-- ... svg ... -->
</button>
<div class="modal-body">
<!-- ... quote icon svg ... -->
<blockquote id="random-joke-text" class="random-joke-text"></blockquote>
<div id="random-joke-meta" class="random-joke-meta"></div>
</div>
<div class="modal-actions">
<button id="another-joke-btn" class="btn btn-primary">
<!-- ... svg ... -->
Another One
</button>
<button id="share-joke-btn" class="btn btn-secondary">
<!-- ... svg ... -->
Share
</button>
</div>
</div>
</div>
Key elements within the modal:
| Element ID / Class | Description |
|---|---|
#random-modal | The main container for the modal. |
.modal-overlay | The semi-transparent background. Closes the modal on click. |
.modal-close | The 'X' button to close the modal. |
#random-joke-text | The <blockquote> element where the joke text is rendered. |
#random-joke-meta | Container for metadata badges (e.g., guest, episode). |
#another-joke-btn | Button to load and display a new random joke within the modal. |
#share-joke-btn | Button to trigger the share functionality. |
Sources: redesign/jokes.html:201-248, redesign/script.js:587-597
Keyboard Shortcuts
For improved accessibility and user experience, keyboard shortcuts are available.
| Key | Action | Context |
|---|---|---|
R | Shows the random joke modal. | Global, except when an input field is focused. |
Escape | Closes the random joke modal if it is open. | Global. |
This functionality is implemented via a keydown event listener on the document.
// redesign/script.js:599-606
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
closeRandomJoke();
}
if (e.key === 'r' && !e.ctrlKey && !e.metaKey && document.activeElement.tagName !== 'INPUT') {
e.preventDefault();
showRandomJoke();
}
});
Sources: redesign/script.js:599-606, redesign/README.md:22
Summary
The Random Joke Generator is a versatile and well-integrated feature that enhances user engagement across The Norm Macdonald Archive. It exists in multiple forms, from an interactive modal to a self-updating homepage card, demonstrating a flexible approach to content discovery. The implementation is self-contained within the project's vanilla HTML/CSS/JS stack, relying on a simple state management object and direct DOM manipulation to provide a fast and responsive user experience.
Sources: README.md:10, redesign/script.js, redesign/index.html