关于单页应用(SPA)的经验之谈
单页站点优劣
传输数据少
服务可不中断
前后端开发更规范
首次加载数据大耗时长
极差的SEO(搜索引擎优化)
导航需要人为处理
单页应用的实现方式
iframe
ajax+div+historyapi
基于iframe制作单页博客
$('a[target="contentFrame"]').click(function(){
var $this = $(this),
url = $this.attr('href'),
mainHost = location.host,
i = url.indexOf(mainHost);
$active.removeClass('active');
$active = $this.parent('li');
$active.addClass('active');
if(i !== -1){
url = url.substr(i + mainHost.length);
}
window.location.hash = '#' + url;
return false;
});
在iframe页面(子页面)中,也有一段类似的js,为iframe中的页面超链接绑定事件
$('a').click(function(){
var url = $(this).attr('href')
if(url && url != '#' && url.indexOf('http') == 0){
var mainHost = window.parent.location.host,
i = url.indexOf(mainHost);
if(i !== -1){
url = url.substr(i + mainHost.length);
}
window.parent.location.hash = '#' + url;
}
return false;
});
注意这两段代码,修改的都是父文档(顶层窗口)地址栏的hash值。所以,只需要在父文档中监听onhashchange事件,在事件响应中设置iframe的src 进而load子页面。
$container = $('div.page-body > iframe');
window.onhashchange = function(){
$container.attr('src',location.hash.substring(1));
};
iframe高度不能根据内容自适应,需要在子页面load之后刷新iframe的高度
var refreshHeight = function(){
var $this = $container,
minHeight = $('.page-right').height() - $('.top-menu').height() - 20,
contentHeight = $this.contents().find('body').height() + 10;
$this.height(contentHeight < minHeight ? minHeight : contentHeight);
}; $container.load(function(){
refreshHeight();
});
// 首次刷新,否则加载过程中会看到白框
refreshHeight();
到这里基本已经实现任意跳转、回退、前进页面不再刷新整个页面。下面的代码是为了解决当打开多个顶层文档时(开多个窗口),音乐不重复播放,方法也很简单,在localStorage中记录顶层文档的数量,每开一个新窗口加1,关闭时减1,只要记录数大于1便不自动播放。
if(window.localStorage){
var $window = $(window);
$window.on('beforeunload',function(){
console.log('-1');
localStorage.framePage = localStorage.framePage - 1;
}); window.addEventListener("storage", function(e){
console.log("oldValue: "+ e.oldValue + " newValue:" + e.newValue)
});
}
var autoplay = location.host !== 'movesun.qq.com';
if(window.localStorage){
if(Number(localStorage.framePage) >= 1){
autoplay = false;
} if(isNaN(localStorage.framePage) || Number(localStorage.framePage) <= 0) localStorage.framePage = 1;
else {
localStorage.framePage = Number(localStorage.framePage) + 1;
}
}
博客依然有两个问题需要解决
1、目前的浏览器已经支持记录iframe变更的历史记录,通过hash记录历史就显的没有必要了。目前网站每次跳转实际产生了两条历史记录。后面找时间移出hash记录或者禁用iframe历史记录
2、考虑到搜索引擎收录的超链接应该是非hash模式的url,比如用户看到的是movesun.com/#/blog/list ,而实际收录的却是movesun.com/blog/list,通过site:movesun.com指令搜索也可以看到
直接访问这类url地址,将直接打开iframe里的内容,所以,当用户直接点击搜索引擎的结果进入博客时,应该将用户跳转到hash模式,页面才能正常显示,但这样对搜索引擎而言,会陷入一个无限循环,影响搜索引擎收录。
前端因直接面向用户,使得技术也更新迭代的频繁,前端开发人员也需要不断学习以追赶时代的潮流。而反观后台技术,十年来都没什么及其巨大的变化,很多技术经久不衰,后端开发完全有一招鲜吃遍天的架势。这也是的前端人员比较抢手,在一些公司都存在前端与后台人力严重不平衡的现像,十几位后台搭配一位前端的事情,也不是没有,奇货可居,优秀的前端是非常吃香的。
关于单页应用(SPA)的经验之谈的更多相关文章
- 单页应用SPA做SEO的一种清奇的方案
单页应用SPA做SEO的一种清奇的方案 网上有好几种单页应用转seo的方案,有服务端渲染ssr.有预渲染prerender.google抓AJAX.静态化...这些方案都各有优劣,开发者可以根据不同的 ...
- 从单页应用(SPA)到服务器渲染(SSR)
从单页应用(SPA)到服务器渲染(SSR) 情景回顾 在学习Vue开发一个电商网站的管理后台时,使用到了一个组件 vue-quill-editor 主要是一个快捷的一个富文本编辑器 在使用这个组件的组 ...
- 移动前端开发-单页应用(spa)模型
一门新的技术诞生总会引来一番争议,单页Web应用程序也不例外,其最大的优势在于用户体验,对于内容的改动不需要加载整个页面:对服务器压力很小,消耗更少的带宽,与面向服务的架构更好地结合.使用HTML+C ...
- 单页应用SPA的路由
关于单页应用 单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用 ...
- 单页应用SPA开发最佳实践
最近用vue+vue-router做了个单页应用的项目,页面大概有15个左右.积累了一些开发经验在此做一些记录.本文主要从可维护性方面来考虑SPA的开发实践 全站的颜色定义放在一个less或者scss ...
- 《移动Web前端高效开发实战》笔记4--打造单页应用SPA
路由是一个单页应用的核心,大部分前端框架都实现了一个复杂的路由库,包括动态路由,路由钩子,组件生命周期甚至服务器端渲染等复杂的功能.但是对于前端开发者而言,路由组件的核心是URL路径到函数的映射,了解 ...
- 基于jQuery/zepto的单页应用(SPA)搭建方案
这里介绍一个基于jquery或zepto的单页面应用方案,遵循尽可能简单的原则,使大家一目了然,只需配置一个路由,之后完全按照jq日常写法即可完成.可做学习使用,也可修改后用于一些业务逻辑简单的spa ...
- Nodejs之MEAN栈开发(六)---- 用Angular创建单页应用(上)
在上一节中我们学会了如何在页面中添加一个组件以及一些基本的Angular知识,而这一节将用Angular来创建一个单页应用(SPA).这意味着,取代我们之前用Express在服务端运行整个网站逻辑的方 ...
- Senna.js – 速度极快的单页应用程序引擎
Senna.js 是一个速度超快的单页应用程序引擎,提供了几个低级别的 API,可以帮助你打造现代化的基于 Web 的应用程序.更重要的是,搜索引擎蜘蛛应该能够索引相同的内容. 通过使用 HTML5 ...
- seo-mask -- 为单页应用创建一个适合蜘蛛爬取的seo网站
seo-mask seo-mask是利用搜索引擎蜘蛛的爬取原理(蜘蛛只会爬取网页的内容,并不会关心解析网页里的css和js),制作一套专门针对seo的镜像网站,鄙人称它为针对seo的mask,让蜘蛛看 ...
随机推荐
- 用c++实现高精度加法
c++实习高精度加法 最近遇到一个c++实现高精度加法的问题,高精度问题往往十复杂但发现其中的规律后发现并没有那么复杂,这里我实现了一个整数的高精度加法,主要需要注意以下几点: 1:将所需输入的数据以 ...
- [认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)
0 目录 认证授权系列:http://www.cnblogs.com/linianhui/category/929878.html 1 什么是OIDC? 看一下官方的介绍(http://openid. ...
- poi jsp xls
poi jsp xls <%@ page language="java" pageEncoding="UTF-8"import="java.ut ...
- ArrayList实现分组功能
这边只用2个属性来进行分组 定义Object有key与value属性 按照key的不同对于arrayList进行分组 List<Object> tempList=new ArrayList ...
- [.NET跨平台]Jeuxs独立版本的便利与过程中的一些坑
本文环境与前言 之前写过一篇相关的文章:在.NET Core之前,实现.Net跨平台之Mono+CentOS+Jexus初体验 当时的部署还是比较繁琐的,而且需要联网下载各种东西..有兴趣的可以看看, ...
- 关于python编译的一点小结
大家都知道python是脚本语言,源码可以直接执行,有时需要提高执行效率或者保密(因为有时候不想让使用人看到源码文件),那就涉及到python编译了,那么该如何做呢? 有两种方法可以做到. 1.一种是 ...
- (转)Nginx的启动、停止与重启
启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 例如: [root@LinuxServer sbin]# /usr/local/nginx/sbin/nginx -c /us ...
- Java中设计模式之生产者消费者模式-4
引言 生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区.其中一个是生产者,用于将消息放入缓冲区:另 ...
- Spring+SpringMVC+MyBatis深入学习及搭建(六)——MyBatis关联查询
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6923464.html 前面有将到:Spring+SpringMVC+MyBatis深入学习及搭建(五)--动 ...
- Analog/digital converter (ADC)
1.ADC1 and ADC2 are 10-bit successive approximation Anolog to Digital Converters. 所谓successive appro ...