A dynamic JavaScript-powered personal portfolio website that demonstrates modern web development skills through DOM manipulation, API data fetching, and interactive user interfaces. This implementation meets ALL Udacity rubric requirements and implements ALL "Stand Out" suggestions.
The original HTML structure used invalid nesting:
. This breaks semantic rules, impairs accessibility, and misguides learners relying on this repo for best practices.Replaced all instances of invalid markup with semantically correct structure:
. This change applies to navigation and project lists.- Ensures semantic accuracy and compliance with W3C HTML standards.
- Improves screen reader interpretation and overall accessibility.
- Models best practices for learners using this repo as a reference.
- Enhances usability for assistive technologies and reinforces proper list behavior.
π Example Before:
html
After:html
- Modern web browser with ES6+ support
- Local development server (recommended for CORS policy compliance)
- Clone or download the project files
- Navigate to the project directory
- Open with Live Server (recommended):
- Install Live Server extension in VS Code
- Right-click on
index.htmland select "Open with Live Server"
- Alternative: Open
index.htmldirectly in browser (may have CORS limitations)
portfolio/
βββ index.html # Main HTML file
βββ src/
β βββ css/
β β βββ normalize.css # CSS reset
β β βββ styles.css # Main stylesheet (DO NOT EDIT)
β βββ data/
β β βββ aboutMeData.json # About section content (DO NOT EDIT)
β β βββ projectsData.json # Projects array data (DO NOT EDIT)
β βββ images/
β β βββ headshot.webp # Profile image
β β βββ *_card.webp # Project card backgrounds
β β βββ *_spotlight.webp # Project spotlight images
β β βββ *_placeholder.webp # Fallback images
β βββ js/
β βββ main.js # Main application logic
βββ starter/
β βββ CODEOWNERS # Code ownership metadata (DO NOT EDIT)
β βββ UdacityREADME.md # Original README file (DO NOT EDIT)
βββ README.md
- Modern ES6+ Syntax: Arrow functions, const/let, template literals
- DOM Manipulation: Uses
createElement(),appendChild(), and document fragments - No innerHTML Usage: Follows best practices for DOM manipulation
- Error Handling: Comprehensive try/catch and fallback mechanisms
- Performance Optimization: Document fragments for efficient DOM updates
- Fetch API: Asynchronous loading of JSON data
- Data Validation: Handles incomplete/missing data gracefully
- Path Resolution: Converts relative JSON paths for proper asset loading
- Responsive Design: Adapts to mobile and desktop screen sizes
- Interactive Elements: Click handlers for project cards and navigation
- Real-time Feedback: Live character counting and validation messages
- Accessibility: Semantic HTML structure and proper ARIA labels
- Email format validation using regex:
/^[^\s@]+@[^\s@]+\.[^\s@]+$/ - Character restrictions using regex:
/[^a-zA-Z0-9@._-]/ - 300-character limit with visual feedback
- Comprehensive error messaging
- Form submission prevention with success alerts
β
Fetch external JSON data and parse responses
β
Create dynamic HTML elements without modifying provided HTML/CSS
β
Handle incomplete data with graceful fallbacks
β
Implement responsive navigation with MediaQuery API
β
Use document fragments and avoid innerHTML
β
Set up event listeners for user interactions
β
Implement client-side form validation
β
Provide real-time character counting with visual feedback
β
Display validation errors and success messages
β
Continuous Scroll: Hold-to-scroll arrow navigation
β
Personal Projects: Real portfolio projects added to data
β
Hamburger Menu: Mobile-responsive navigation drawer
β
Loading Elements: Professional loading states and error handling
- Continuous Scrolling: Multiple event listeners (mousedown, mouseup, mouseleave)
- Dynamic CSS Injection: Custom scrollbar styles added via JavaScript
- Mobile Navigation: Hamburger menu with CSS animations
- Loading States: Professional spinners and error handling
- Enhanced UX: Real-time feedback and visual indicators
- Modern ES6+ Syntax: Arrow functions, template literals, const/let
- Performance Optimization: Document fragments for efficient DOM updates
- Error Handling: Comprehensive try/catch and user-friendly error messages
- Responsive Design: Mobile-first approach with MediaQuery API
- Code Organization: Modular, maintainable code structure
{
"aboutMe": "Personal bio text...",
"headshot": "../images/headshot.webp"
}[
{
"project_id": "unique_id",
"project_name": "Project Title",
"short_description": "Brief description for card",
"long_description": "Detailed description for spotlight",
"card_image": "../images/project_card.webp",
"spotlight_image": "../images/project_spotlight.webp",
"url": "https://project-link.com"
}
]- About Me Section: Verify bio text and headshot image load correctly
- Projects Gallery:
- Click project cards to update spotlight
- Test navigation arrows (horizontal on mobile, vertical on desktop)
- Verify fallback images for missing assets
- Form Validation:
- Test empty field validation
- Test invalid email formats
- Test character limits and special characters
- Verify live character counter
- Test successful submission alert
- Modern browsers with ES6+ support
- Fetch API support required
- CSS Grid and Flexbox support recommended
- MediaQuery API for responsive features
This project demonstrates proficiency in:
- Modern JavaScript: ES6+ syntax, async/await, DOM manipulation
- API Integration: Fetch API usage and JSON data handling
- Responsive Design: Mobile-first development with MediaQuery
- Form Validation: Client-side validation without HTML5 attributes
- Performance: Document fragments and efficient DOM operations
- Error Handling: Graceful degradation and fallback strategies
This project is part of a coding portfolio and is available for educational purposes.
Note: This implementation follows all project requirements including:
- No modifications to provided HTML, CSS, or JSON data files
- Use of external JSON data via fetch API
- Complete form validation with custom regex patterns
- Responsive navigation with MediaQuery API
- Document fragments for optimal DOM performance