用原生js做单页应用

yizhihongxing

下面我将为大家详细讲解如何用原生JS做单页应用的完整攻略。

什么是单页应用?

单页应用(SPA)是指使用Ajax或Websocket等技术,使得网页只需加载一次,就能实现多个页面的效果。

用原生JS做单页应用的步骤

  1. 定义路由
    要实现单页应用,首先需要定义路由,以此来控制页面的跳转和展示。可以使用window.history.pushState()方法或者location.hash来实现路由。

示例代码:

// 定义路由表
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
  { path: '/contact', component: Contact }
]

// 监听路由变化
window.addEventListener('popstate', routeChanged);

// 路由跳转
function navigateTo(path) {
  history.pushState(null, null, path);
  routeChanged();
}

// 路由变化处理函数
function routeChanged() {
  const path = location.pathname;
  const route = routes.find(route => route.path === path) || {component: NotFound};
  document.querySelector('#content').innerHTML = new route.component().render();
}
  1. 定义组件
    为了实现复用和组合,需要将页面拆分成多个组件。每个组件可以由一个HTML模板和一个JS逻辑文件组成。

示例代码:

// Home组件
class Home {
  constructor() {
    this.template = `
      <h1>Welcome to Home Page</h1>
      <p>Home Page Content Here</p>
    `;
  }

  render() {
    return this.template;
  }
}

// About组件
class About {
  constructor() {
    this.template = `
      <h1>About Us</h1>
      <p>About Us Content Here</p>
    `;
  }

  render() {
    return this.template;
  }
}

// Contact组件
class Contact {
  constructor() {
    this.template = `
      <h1>Contact Us</h1>
      <p>Contact Us Content Here</p>
    `;
  }

  render() {
    return this.template;
  }
}

// NotFound组件
class NotFound {
  constructor() {
    this.template = `
      <h1>Not Found</h1>
      <p>404 Page Not Found</p>
    `;
  }

  render() {
    return this.template;
  }
}
  1. 编写事件处理函数和业务逻辑
    单页应用中,事件处理函数和业务逻辑通常写在组件中。可以使用事件委托和事件监听等方法来实现交互效果。

示例代码:

// 定义事件处理函数
function handleClick(event) {
  event.preventDefault();
  const path = event.target.href;
  navigateTo(path);
}

// 组件中使用事件处理函数
class Navigation {
  constructor() {
    this.template = `
      <nav>
        <ul>
          <li><a href="/" class="link">Home</a></li>
          <li><a href="/about" class="link">About</a></li>
          <li><a href="/contact" class="link">Contact</a></li>
        </ul>
      </nav>
    `;
  }

  render() {
    const element = document.createElement('div');
    element.innerHTML = this.template.trim();
    element.addEventListener('click', handleClick); // 事件委托
    return element;
  }
}

// 业务逻辑处理函数
function handleSubmit(event) {
  event.preventDefault();
  const formData = new FormData(event.target);
  const data = Object.fromEntries(formData.entries());
  // 处理提交数据...
}

// 组件中使用业务逻辑处理函数
class Form {
  constructor() {
    this.template = `
      <form>
        <label>
          Name: <input type="text" name="name" required>
        </label>
        <label>
          Email: <input type="email" name="email" required>
        </label>
        <button type="submit">Submit</button>
      </form>
    `;
  }

  render() {
    const element = document.createElement('div');
    element.innerHTML = this.template.trim();
    element.querySelector('form').addEventListener('submit', handleSubmit);
    return element;
  }
}

示例说明

示例一:基础单页应用

下面是一个基础的单页应用示例,实现了路由跳转和组件渲染。

<html>
<head>
  <title>Example SPA</title>
</head>
<body>
  <nav>
    <ul>
      <li><a href="/" class="link">Home</a></li>
      <li><a href="/about" class="link">About</a></li>
      <li><a href="/contact" class="link">Contact</a></li>
    </ul>
  </nav>
  <div id="content"></div>
  <script>
    // 定义路由表
    const routes = [
      { path: '/', component: Home },
      { path: '/about', component: About },
      { path: '/contact', component: Contact }
    ];

    // 监听路由变化
    window.addEventListener('popstate', routeChanged);

    // 路由跳转
    function navigateTo(path) {
      history.pushState(null, null, path);
      routeChanged();
    }

    // 路由变化处理函数
    function routeChanged() {
      const path = location.pathname;
      const route = routes.find(route => route.path === path) || {component: NotFound};
      document.querySelector('#content').innerHTML = new route.component().render();
    }

    // Home组件
    class Home {
      constructor() {
        this.template = `
          <h1>Welcome to Home Page</h1>
          <p>Home Page Content Here</p>
        `;
      }

      render() {
        return this.template;
      }
    }

    // About组件
    class About {
      constructor() {
        this.template = `
          <h1>About Us</h1>
          <p>About Us Content Here</p>
        `;
      }

      render() {
        return this.template;
      }
    }

    // Contact组件
    class Contact {
      constructor() {
        this.template = `
          <h1>Contact Us</h1>
          <p>Contact Us Content Here</p>
        `;
      }

      render() {
        return this.template;
      }
    }

    // NotFound组件
    class NotFound {
      constructor() {
        this.template = `
          <h1>Not Found</h1>
          <p>404 Page Not Found</p>
        `;
      }

      render() {
        return this.template;
      }
    }

    // 定义事件处理函数
    function handleClick(event) {
      event.preventDefault();
      const path = event.target.href;
      navigateTo(path);
    }

    // Navigation组件
    class Navigation {
      constructor() {
        this.template = `
          <nav>
            <ul>
              <li><a href="/" class="link">Home</a></li>
              <li><a href="/about" class="link">About</a></li>
              <li><a href="/contact" class="link">Contact</a></li>
            </ul>
          </nav>
        `;
      }

      render() {
        const element = document.createElement('div');
        element.innerHTML = this.template.trim();
        element.addEventListener('click', handleClick); // 事件委托
        return element;
      }
    }

    document.querySelector('#content').appendChild(new Navigation().render());
    routeChanged();
  </script>
</body>
</html>

示例二:表单提交处理

下面是一个实现表单提交处理的单页应用示例,演示了如何在组件中处理交互事件和业务逻辑。

<html>
<head>
  <title>Example SPA</title>
</head>
<body>
  <nav>
    <ul>
      <li><a href="/" class="link">Home</a></li>
      <li><a href="/about" class="link">About</a></li>
      <li><a href="/contact" class="link">Contact</a></li>
    </ul>
  </nav>
  <div id="content"></div>
  <script>
    // 定义路由表
    const routes = [
      { path: '/', component: Home },
      { path: '/about', component: About },
      { path: '/contact', component: Contact }
    ];

    // 监听路由变化
    window.addEventListener('popstate', routeChanged);

    // 路由跳转
    function navigateTo(path) {
      history.pushState(null, null, path);
      routeChanged();
    }

    // 路由变化处理函数
    function routeChanged() {
      const path = location.pathname;
      const route = routes.find(route => route.path === path) || {component: NotFound};
      document.querySelector('#content').innerHTML = new route.component().render();
    }

    // Home组件
    class Home {
      constructor() {
        this.template = `
          <h1>Welcome to Home Page</h1>
          <p>Home Page Content Here</p>
        `;
      }

      render() {
        return this.template;
      }
    }

    // About组件
    class About {
      constructor() {
        this.template = `
          <h1>About Us</h1>
          <p>About Us Content Here</p>
        `;
      }

      render() {
        return this.template;
      }
    }

    // Contact组件
    class Contact {
      constructor() {
        this.template = `
          <h1>Contact Us</h1>
          <p>Contact Us Content Here</p>
          <h2>Feedback Form</h2>
          <div id="form"></div>
        `;
      }

      render() {
        const element = document.createElement('div');
        element.innerHTML = this.template.trim();
        element.querySelector('#form').appendChild(new ContactForm().render());
        return element;
      }
    }

    // NotFound组件
    class NotFound {
      constructor() {
        this.template = `
          <h1>Not Found</h1>
          <p>404 Page Not Found</p>
        `;
      }

      render() {
        return this.template;
      }
    }

    // ContactForm组件
    class ContactForm {
      constructor() {
        this.template = `
          <form>
            <label>
              Name: <input type="text" name="name" required>
            </label>
            <label>
              Email: <input type="email" name="email" required>
            </label>
            <label>
              Message: <textarea name="message" rows="5" required></textarea>
            </label>
            <button type="submit">Submit</button>
          </form>
        `;
      }

      render() {
        const element = document.createElement('div');
        element.innerHTML = this.template.trim();
        element.querySelector('form').addEventListener('submit', handleSubmit);
        return element;
      }
    }

    // 提交处理函数
    function handleSubmit(event) {
      event.preventDefault();
      const formData = new FormData(event.target);
      const data = Object.fromEntries(formData.entries());
      console.log(data);
      // 处理提交数据...
      event.target.reset();
      alert('Submit success.');
    }

    // 定义事件处理函数
    function handleClick(event) {
      event.preventDefault();
      const path = event.target.href;
      navigateTo(path);
    }

    // Navigation组件
    class Navigation {
      constructor() {
        this.template = `
          <nav>
            <ul>
              <li><a href="/" class="link">Home</a></li>
              <li><a href="/about" class="link">About</a></li>
              <li><a href="/contact" class="link">Contact</a></li>
            </ul>
          </nav>
        `;
      }

      render() {
        const element = document.createElement('div');
        element.innerHTML = this.template.trim();
        element.addEventListener('click', handleClick); // 事件委托
        return element;
      }
    }

    document.querySelector('#content').appendChild(new Navigation().render());
    routeChanged();
  </script>
</body>
</html>

以上就是用原生JS做单页应用的详细攻略,希望对大家有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:用原生js做单页应用 - Python技术站

(1)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 一文了解你不知道的JavaScript生成器篇

    一文了解你不知道的JavaScript生成器篇 简介 JavaScript的生成器(Generator)是ES6新引入的一个特性,可以使我们更加方便地控制异步代码流程,使代码更加简洁易懂。本文将介绍JavaScript生成器的基本语法、使用方法及示例,以帮助开发者快速掌握这一特性。 生成器语法 生成器语法使用function*定义一个生成器函数,通过yiel…

    JavaScript 2023年5月28日
    00
  • JavaScript面向对象编写购物车功能

    当我们在构建一个购物车功能时,可以采用JavaScript面向对象编程的方式来实现。下面是一个完整的攻略: 1. 设计购物车功能 首先要明确购物车的功能和特点,确定购物车所需要存储的数据。 在购物车中,我们需要存储商品的信息,如名称、价格、数量等,同时还需要实现添加、删除、修改商品以及计算购物车总价等功能。 我们可以创建一个Car对象来代表购物车,同时定义一…

    JavaScript 2023年6月11日
    00
  • 如何学习Javascript入门指导

    如何学习 Javascript 入门指导 为什么要学习 Javascript Javascript 是一门前端开发必备的编程语言。通过 Javascript,可以实现交互式的网页,使得用户与网页的互动更加生动有趣。Javascript 的应用还涉及到后端开发、移动应用开发等多个领域。 入门指导 1. 学习基本语法 Javascript 的基本语法是学习的重点…

    JavaScript 2023年5月18日
    00
  • js opener的使用详解

    JavaScript中的opener 在JavaScript中,window.opener是一个全局对象,它代表调用当前窗口的父窗口对象。即如果我们使用一个子窗口来打开一个页面,那么该页面中的window.opener就代表了该子窗口的父窗口对象。opener对象的使用非常灵活,提供了多种用法。下面我们来详细了解一下opener对象。 属性 window.o…

    JavaScript 2023年6月11日
    00
  • JSON 入门教程基础篇 json入门学习笔记

    JSON 入门教程基础篇 json入门学习笔记 本文主要介绍JSON的基础知识,包括JSON是什么、JSON的语法格式、如何解析JSON数据等,读者可以通过本文学习到JSON的基础知识并能够进行简单的JSON数据解析。 什么是JSON JSON全称为JavaScript Object Notation,它是一种轻量级的数据交换格式。JSON以纯文本的形式表示…

    JavaScript 2023年5月27日
    00
  • ASP 正则表达式的应用使用说明

    ASP 正则表达式的应用使用说明 什么是正则表达式 正则表达式是由特殊字符和普通字符组成的模式,主要用于文本的匹配和处理。在 ASP 中,可以使用正则表达式对象(RegExp Object)来进行文本操作。 正则表达式在 ASP 中的应用 正则表达式在 ASP 中的应用极为广泛,主要包括以下两个方面: 1. 验证表单数据 在 ASP 中,我们经常需要对用户的…

    JavaScript 2023年6月10日
    00
  • 使用JS读取XML文件的方法

    使用JS读取XML文件的方法可以分为以下步骤: 创建XMLHttpRequest对象 通过XMLHttpRequest对象发送HTTP请求来获取XML文件 解析XML文件 下面我将详细介绍这三个步骤,并提供两个使用示例。 步骤1:创建XMLHttpRequest对象 使用XMLHttpRequest对象是读取XML文件的标准方式之一。我们可以通过下面的代码创…

    JavaScript 2023年5月27日
    00
  • 详解JavaScript+Canvas绘制环形进度条

    接下来我将详细讲解“详解JavaScript+Canvas绘制环形进度条”的完整攻略。 环形进度条简介 环形进度条是指一个环形背景,根据输入的进度值,填充相应的进度颜色。它可以展示操作的进度、网站的加载进度等等。 环形进度条实现方法 JavaScript+Canvas是一种流行的实现环形进度条的方式。 首先,我们需要在HTML中创建一个Canvas元素: &…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部