继续源码的结构分析
首先贴一个结构图
这是 https://www.polymer-project.org/3.0/toolbox/case-study 这个分析文章中的结构图
根据实际的代码,这里 iron-pages 实际指的是这个代码中的main 标签
<main>
<!-- home view -->
<shop-home active?="${_page === 'home'}"></shop-home>
<!-- list view of items in a category -->
<shop-list active?="${_page === 'list'}"></shop-list>
<!-- detail view of one item -->
<shop-detail active?="${_page === 'detail'}"></shop-detail>
<!-- cart view -->
<shop-cart active?="${_page === 'cart'}"></shop-cart>
<!-- checkout view -->
<shop-checkout active?="${_page === 'checkout'}"></shop-checkout>
<shop-404-warning active?="${_page === '404'}"></shop-404-warning>
</main>
前面我们已经分析了其核心是在每次页面跳转或刷新时分析url ,来判断应该使用那个view
对于数据来讲其实是在我们可以看到大致的流程是
访问页面 , 总会调用 updateLocation 方法 然后调用 await dispatch(fetchCategoriesIfNeeded()); 加载基本数据,然后根据page值,也就是不同页面加载不同的视图组件,再详细分析,我要在实际项目开发中进一步来学习了。
下面开始 我会对这个项目逐行做详细分析今天先分析index.html,我们可以认为整个web app就是index.html , 只是中间再加载和处理相关操作等等
先做结构化分析
<!doctype html>
<html lang="en">
<head>
</head>
<body>
</body>
</html>
看起来是一个标准的页面结构,里面唯一要解释的是
这是html5的头声明,其实是一种回归,回归简单声明方式
我们看看 中主要是html的头部内容和 页面直接定义 的css style
我们先看看 css style
body {
margin: 0;
font-family: 'Roboto', 'Noto', sans-serif;
font-size: 13px;
line-height: 1.5;
min-height: 100vh;
}
这里的font-family , font-size 定义页面整体的字体样式,line-height :1.5 是行高为标准值的倍数,margin 是指整体页面的边界,min-height : 100vh, 这个有点意思,
我找到的解释是
Viewport Height (vh) – A percentage of the full viewport height. 10vh will resolve to 10% of the current viewport height.,100vh 可以理解为高度为全屏的意思
/* styling for render while resources are loading */
shop-app[unresolved] {
display: block;
min-height: 101vh;
line-height: 68px;
text-align: center;
font-size: 16px;
font-weight: 600;
letter-spacing: 0.3em;
color: #202020;
padding: 0 16px;
overflow: visible;
}
这个的目的是很明确的 ,在页面加载时页面显示的样式,我们来看看其具体的设定
display: block; 显示 line-height: 68px; 高度,这个不知道为啥时68 而不是其他值,不过68 是个吉利数字,text-align: center; 文字居中,font-size: 16px; font-weight: 600; 字体大小和粗细,letter-spacing: 0.3em; 这个设定了字母的间距,color: #202020; 字的颜色是带一点点灰亮的深黑色,padding: 0 16px; 这个上下为0 左右为16px,这里略微说明一下 margin 和 padding的区别
在CSS中margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离。
在CSS中padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离
我在看看 head中都设定了什么,又引入了那些文件,我会逐行来解释
<meta charset="utf-8">
指明页面字符集为 utf-8 目前这是标准做法,唯一可能的发展看看以后是不是会支持到一个特殊字符的问题,毕竟utf-8 也不能支持所有的字符,包括表情符号
<base href="/">
为页面中所有链接设定一个缺省的url路径
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
这个是自适应页面的标准写法,详细解释大致就是 页面和设备一致,并且初始,最小都不变,用户可以自己放大缩小
<title>SHOP</title>
<meta name="description" content="Polymer Shop Demo">
这两个大家应该明白,而且对网页SEO也很重要,另外两个 name=”keywords” 和 name=”author” 没有
<link rel="shortcut icon" sizes="32x32" href="images/shop-icon-32.png">
这个就是浏览器tab上的小图标
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@Polymer">
<meta property="og:type" content="website">
<meta property="og:site_name" content="SHOP">
<meta name="theme-color" content="#fff">
我们看到5个meta 大多给 索引处理用,其中 property=”og:type”,property=”og:site_name” 是一种 元标记 Meta Tags,网上找到的一段说明:
Meta Property=og标签是什么呢?
og是一种新的HTTP头部标记,即Open Graph Protocol:
The Open Graph Protocol enables any web page to become a rich object in a social graph.
即这种协议可以让网页成为一个“富媒体对象”。
用了Meta Property=og标签,就是你同意了网页内容可以被其他社会化网站引用等,目前这种协议被SNS网站如Fackbook、renren采用。
SNS已经成为网络上的一大热门应用,优质的内容通过分享在好友间迅速传播。为了提高站外内容的传播效率,2010年F8会议上Facebook公布了一套开放内容协议(Open Graph Protocol),任何网页只要遵守该协议,SNS就能从页面上提取最有效的信息并呈现给用户。
<link rel="manifest" href="manifest.json">
这个也是比较重要的,作为web app 型网站的重要描述性文件,比如添加的主屏幕操作就是依赖于这个文件,下面可以看看 manifest.json 的主要内容
{
"name": "SHOP",
"short_name": "SHOP",
"icons": [{
"src": "images/shop-icon-128.png",
"sizes": "128x128",
"type": "image/png"
}, {
"src": "images/shop-icon-192.png",
"sizes": "192x192",
"type": "image/png"
},{
"src": "images/shop-icon-384.png",
"sizes": "384x384",
"type": "image/png"
},{
"src": "images/shop-icon-512.png",
"sizes": "512x512",
"type": "image/png"
}],
"start_url": "/",
"background_color": "#fff",
"display": "standalone",
"theme_color": "#fff"
}
我们可以看到主要内容是图标,另外还可以又其他内容加上
"description": "A simply readable Hacker News app.",
"related_applications": [{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb"
}]
这些东西看起来都在向一个方向努力,一起协同让所有的互联网内容更加有组织化,更加又关联性和协调性,创造更大的价值
继续body中主要分为主体和 js内容
<shop-app unresolved>SHOP</shop-app>
大家应该想起来前面说过的 css style 了吧 shop-app[unresolved] 就是给这个用的
下面来看看 js 相关的部分
第一种是引入js文件
首先是web app 项目最重要的一个js 文件,就是组件化加载
<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
第二个就是 组件自身了,明天我会从这个文件继续做详细分析
<script type="module" src="src/components/shop-app.js"></script>
另外就是直接写的js 其中一个是非常核心的东西,就是 service work 代码的相关处理,关于这一部分我会放到后面做详细分析,分析service-worker.js 文件里面都干了啥
<script>
if ('serviceWorker' in window.navigator) {
window.addEventListener('load', function() {
window.navigator.serviceWorker.register('service-worker.js', {scope: '/'});
});
}
</script>
剩下的js 看起来无关紧要了,但是会对兼容性啥的又影响,不过多解释了
<script>
// HACK(keanulee): The Redux package assumes `process` exists - mock it here before
// the module is loaded.
window.process = {
env: {
NODE_ENV: 'production'
}
};
</script>
<script>
// Subset of fetch polyfill for IE11 (supports GET requests for JSON only).
// Requires Promise to be defined.
window.fetch = window.fetch || function(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve({
json: function() {
return new Promise(function(resolve, reject) {
try {
resolve(JSON.parse(xhr.responseText));
} catch (e) {
reject(e);
}
});
}
});
};
xhr.onerror = reject;
xhr.open('GET', url);
xhr.send();
});
};
</script>
好今天就到这里,明天继续详细分析 src/components/shop-app.js