下面我将为大家详细讲解如何用原生JS做单页应用的完整攻略。
下面我将为大家详细讲解如何用原生JS做单页应用的完整攻略。
什么是单页应用?
单页应用(SPA)是指使用Ajax或Websocket等技术,使得网页只需加载一次,就能实现多个页面的效果。
用原生JS做单页应用的步骤
- 定义路由
要实现单页应用,首先需要定义路由,以此来控制页面的跳转和展示。可以使用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();
}
- 定义组件
为了实现复用和组合,需要将页面拆分成多个组件。每个组件可以由一个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;
}
}
- 编写事件处理函数和业务逻辑
单页应用中,事件处理函数和业务逻辑通常写在组件中。可以使用事件委托和事件监听等方法来实现交互效果。
示例代码:
// 定义事件处理函数
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做单页应用
基础教程推荐
猜你喜欢
- CSS3通过var()和calc()函数实现动画特效 2023-12-23
- css布局绝对定位下margin失效的解决方法 2024-01-25
- uni-app实现视频组件播放和暂停 2023-08-29
- Ajax的特性及乱码问题 2023-02-14
- $.ajax()常用方法详解(推荐) 2023-01-20
- css sprite原理优缺点及使用示例介绍 2024-01-24
- AngularJS2 与 D3.js集成实现自定义可视化的方法 2024-03-10
- 深入理解和应用css中Float属性 2023-12-21
- 【Oracle】【10】去除数据中的html标签 2023-10-26
- HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列 2023-12-21