You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

静态网站HTML/CSS/JS复用方法及基于Firebase的多Material Design卡片实现问题

Hey there! Let's break down your two questions and walk through practical solutions for each—they’re both common pain points, but totally fixable.


1. Reusing HTML/CSS/JavaScript in Static Sites

Static sites don’t have server-side rendering by default, but there are simple, effective ways to avoid repeating code:

  • Use HTML <template> Tags + Vanilla JS
    The <template> tag is a hidden gem for static sites. It lets you define reusable HTML chunks (like navbars, footers, or card layouts) that stay hidden until you clone and inject them with JS. Example:

    <!-- Define your reusable template -->
    <template id="navbar-template">
      <nav class="site-nav">
        <a href="/">Home</a>
        <a href="/about">About</a>
      </nav>
    </template>
    
    <!-- Where you want the navbar to appear -->
    <div id="navbar-container"></div>
    
    <script>
      // Inject the navbar into the container
      const template = document.getElementById('navbar-template');
      const container = document.getElementById('navbar-container');
      const navbarClone = document.importNode(template.content, true);
      container.appendChild(navbarClone);
    </script>
    
  • Fetch Reusable HTML Snippets
    For larger chunks (like a full footer), save the content as a separate file (e.g., footer.html) and load it with fetch:

    async function loadFooter() {
      const response = await fetch('/footer.html');
      const footerHTML = await response.text();
      document.getElementById('footer-container').innerHTML = footerHTML;
    }
    loadFooter();
    
  • Static Site Generators (SSGs) for Scale
    If your site is growing, use an SSG like Eleventy or Jekyll. These tools let you include reusable components during the build process (so you still get static HTML output). For example, in Eleventy, you can use:

    {% include "navbar.njk" %}
    

    to inject a navbar snippet into every page.

  • CSS/JS Reuse

    • For CSS: Use external stylesheets (link them in every page) and component-based classes (e.g., .mdc-card for all your Material Design cards) to avoid repeating styles.
    • For JS: Extract common functions into a separate file (e.g., utils.js) and import it where needed:
      import { loadNavbar, formatCardData } from './utils.js';
      

2. Dynamically Adding Material Design Cards from Firebase Firestore

Hardcoding cards for each ID is messy—instead, build a system that generates cards on demand when users input an ID. Here’s a step-by-step solution:

Step 1: Set Up Your HTML Structure

First, create a hidden template for your Material Design card, an input area for users, and a container to hold all cards:

<!-- Card template (hidden by default) -->
<template id="md-card-template">
  <div class="mdc-card">
    <div class="mdc-card__content">
      <h3 class="card-id"></h3>
      <p class="card-data"></p>
    </div>
    <div class="mdc-card__actions">
      <button class="remove-btn">Remove Card</button>
    </div>
  </div>
</template>

<!-- User input area -->
<div class="input-section">
  <input type="text" id="doc-id-input" placeholder="Enter Document ID">
  <button id="add-card-btn">Add Card</button>
</div>

<!-- Container for all generated cards -->
<div id="cards-container"></div>

Step 2: Write the Dynamic Card Logic

Use JavaScript to fetch data from Firestore, clone the template, fill it with data, and add it to the container. Include error handling for invalid IDs:

// Get references to DOM elements
const cardTemplate = document.getElementById('md-card-template');
const cardsContainer = document.getElementById('cards-container');
const addBtn = document.getElementById('add-card-btn');
const idInput = document.getElementById('doc-id-input');

// Function to fetch data and create a card
async function createCard(docId) {
  try {
    // Replace with your actual Firestore collection reference
    const docRef = db.collection('your-collection-name').doc(docId);
    const docSnap = await docRef.get();

    if (!docSnap.exists) {
      alert(`Oops! No document found with ID: ${docId}`);
      return;
    }

    // Extract your string data from the document
    const cardText = docSnap.data().your-string-field; // Update to your field name

    // Clone the template and fill in data
    const cardClone = document.importNode(cardTemplate.content, true);
    cardClone.querySelector('.card-id').textContent = `Document ID: ${docId}`;
    cardClone.querySelector('.card-data').textContent = cardText;

    // Add remove functionality
    const removeBtn = cardClone.querySelector('.remove-btn');
    removeBtn.addEventListener('click', () => {
      removeBtn.closest('.mdc-card').remove();
    });

    // Add the card to the container
    cardsContainer.appendChild(cardClone);

    // Clear the input field
    idInput.value = '';
  } catch (error) {
    console.error('Error loading card:', error);
    alert('Failed to load card—check the console for details.');
  }
}

// Add event listener to the "Add Card" button
addBtn.addEventListener('click', () => {
  const docId = idInput.value.trim();
  if (docId) {
    createCard(docId);
  } else {
    alert('Please enter a valid document ID!');
  }
});

// Optional: Let users press Enter to add a card
idInput.addEventListener('keypress', (e) => {
  if (e.key === 'Enter') addBtn.click();
});

Step 3: Add Material Design Styling

Make sure your CSS includes basic Material Design card styles (adjust to match your existing CSS):

.mdc-card {
  max-width: 360px;
  margin: 1rem;
  padding: 1.5rem;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  background: white;
}

.mdc-card__content {
  margin-bottom: 1rem;
}

.card-id {
  margin: 0 0 0.5rem 0;
  font-size: 1.1rem;
  color: #2d3748;
}

.card-data {
  margin: 0;
  color: #4a5568;
  line-height: 1.5;
}

.remove-btn {
  background: none;
  border: none;
  color: #2b6cb0;
  cursor: pointer;
  padding: 0.5rem 1rem;
  text-transform: uppercase;
  font-size: 0.9rem;
}

内容的提问来源于stack exchange,提问作者jonasxd360

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:03:15