-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 24 KB
/
content.json
1
{"pages":[{"title":"About Me","text":"少时,爱文字,欲舞文弄墨为生。阴差阳错,入理科,至学建筑。就学中,爱 IT,不可自拔其时所通者,惟装系统也。遂考研,数学差,不得入。毕业前夕,思虑良久,不想身偻发白时言悔之晚矣,故自学代码,自此以键盘为生也好乐,好书,好大觉,好梦志短,惟愿安乐每日,亲朋康安矣 技术栈:Javascript Vue React Babylon.js Node Sass Php MySql(2018) 微信: FYGDream 邮箱:fengyanggang@hotmail.com 欢迎交流","link":"/about/index.html"}],"posts":[{"title":"关于这个博客","text":"很久以前,开始学前端的时候,在 CSDN 放了一个博客,更新每天的笔记。当时当然也菜的不要不要的,每天更新了一堆 css 笔记。后来找到了实习就没时间再更新,于是那个 CSDN 的博客一直空着了。 入了前端之后才发现可以玩的东西有好多好多,在不断的学习过程中,发现只看和练习 demo 是记不住的,当你想给别人解释一个问题的时候,你必须得联系一个概念上下游的所有知识点,才能讲的比较明白。在这个过程中,会逼着你去复习遗忘的东西,去整理、联结零散的知识,于是我发现针对一个主题写下来是一个比较有用的整理知识的方式。 了解过之后,发现用 GitPage 搭一个静态博客最舒服,不需要你整服务器,只要写 markdown 就OK,还可以各种自定义主题。于是申请了一个域名,找到了N年以前在 github 准备的一个仓库,拉了一个 hexo 皮肤下来瞧了瞧,哎哟居然是 ejs 的模版,更舒服了啊,改了大概一天整成了现在这个样子。 原作者英文字体是 Ubuntu 的字体,我也觉得挺好看,但是要从 Goole 拉字体文件,你懂得,于是我去掉了 Ubuntu 字体先尽量保证速度,以后再想办法解决看看,毕竟 美就是生产力,哈哈。 皮肤来自于 hexo-theme-icarus 主要做了以下修改: 为了能使更多精力聚焦在内容而不是左右边栏,将主页调整为两栏 文章页调整布局,去掉边栏,宽度全部占满 比较偏爱 Material-Card 设计,去掉了所有内容块的 border-radius 小小修改了 Footer 改了 profile 的 widget 添加置顶功能 腾讯域名申请了证书,开启了 HTTPS 主要修改地方: 样式 style.styl 注释掉 54 行 border-radius 123456.card overflow: hidden // border-radius: 4px box-shadow: 0 4px 10px rgba(0,0,0,0.05), 0 0 1px rgba(0,0,0,0.1) & + .card,...... 主页放边栏,文章页去掉 修改 layout / layout.ejs 第 22 行处 12345678<% if(page.path === "index.html"){ %> <div class="column <%= main_column_class() %> has-order-2 column-main"><%- body %></div> <%- partial('common/widget', { position: 'left' }) %> <%- partial('common/widget', { position: 'right' }) %><%}else{%><!-- in article page, put arcitle take all width--> <div class="column is-12 has-order-2 column-main"><%- body %></div><%}%> 个人信息栏修改 layout / widget / profile.ejs 第 74 行往下 123456789<% if (socialLinks !== null) { %> <% for (let name in socialLinks) { let link = socialLinks[name]; %> <div class="level is-mobile"> <i class="<%= link.icon %>"></i> <span><%= link.url %></span> </div> <% } %><% } %> 具体配置参考 _config.yml 文件,皮肤放在 GayHub,您也可以拉下去随便玩,有问题可以随时联系我一起玩玩看。 置顶文章 装一个 npm install hexo-generator-index-pin-top --save 先了解一下 front-matter (- -,自己百度一下吧),就是一篇 markdown 最顶上加上一段标记类似这样子: 1234567---title: 关于这个博客date: 2018-12-20 00:00:00......---# 正文内容 明显,用三条短横线做了分隔,这里面添加的一些项目会被 markdown 识别,要置顶文章,在这里面加上 top:true 即可 其他给文章实现分类、多个标签同上,在 front-matter 添加对应的语法,tag 和 目录 如下 : 1234567891011---title: 关于这个博客date: 2018-12-20 00:00:00tags: - hexo - 随便写写categories: - 前端 - 随便写写--- ToDoList: 添加回复块 页内目录 CI 持续集成 搬一份到 Coding Page, 国内访问解析到 Coding Page 添加 sitemap,添加百度索引 有问题 / 意见,可以微信或者邮件我 更新: 18-12-20 添加了 valine 评论模块","link":"/2018/12/20/about-this-blog/"},{"title":"this 绑定丢失及修复","text":"在 Javascript 中, this 关键字经常在我们不注意的时候就被错误引用,得到意料之外的结果,所以我自己对 this 引用丢失及修复的方式整理总结一下。 1 指向哪儿?首先明确一下, this 是一个指向函数被调用时候的执行上下文的指针。 执行上下文中包含了函数的调用栈、函数调用方式、传入的参数等信息 this 的绑定发生在运行时,它指向什么完全取决于函数在哪里被调用 2 this 绑定2.1 默认绑定当在独立函数中使用 this 时,指向全局对象( window / global ): 12345function foo() { console.log(this.a);}var a = 1;foo(); //1 但是 严格模式 下。 this 绑定到 undefined 2.2 隐式绑定 函数引用有上下文对象时,this 会隐式被绑定到 这个上下文对象,而且 对象属性引用链中只有最后一层在调用位置中起作用: 123456789101112131415function foo() { console.log(this.a);}var obj = { a: 0, foo: foo};var obj2 = { a: 1, obj: obj};obj1.obj.foo(); // 0 2.3 new 绑定 使用 new 实例化一个构造函数时,会有以下步骤: 创建一个新对象 把新对象内部的 [[Prototype]] 链接到构造函数的原型对象 将新对象绑定到函数调用的 this 返回新对象或者返回指定的对象 比如: 12345function Foo(a) { this.a = a;}var bar = new Foo(2);console.log(bar.a); // 2 3 绑定丢失在 隐式绑定 中,有些情况下会发生引用丢失的问题 3.1 引用函数时丢失1234567891011function foo() { console.log(this.a);}var obj = { a: 0, foo: foo};var a = \"global\";var baz = obj.foo;baz(); // 'global' on browser undefined on node var baz = obj.foo 的引用,实际上是引用了 foo 函数自身,因此在调用函数 baz 时候,相当于在 全局环境 调用了 foo 3.2 传入回调函数丢失123456789101112131415function foo() { console.log(this.a);}function bar(fn) { // fn 实际上引用的是 foo fn();}var obj = { a: 0, foo: foo};var a = \"global\";bar(obj.foo); // 'global' on browser undefined on node 3.3 setTimeout setTimeout的回调函数会在全局环境( window / global )被执行,即: 12345678var obj2 = { timer() { setTimeout(function() { console.log(this); //window }, 1000); }};obj2.timer(); 4 修改指向为了纠正以上 隐式传递 产生的绑定丢失,我们可以用以下方式来纠正 / 修改 this 指向 4.1 显式绑定( call,apply,bind)即手动、明确的给函数指定一个执行上下文: 比如上面函数传递丢失: 1234567891011function foo() { console.log(this.a);}var obj = { a: 0, foo: foo};var a = \"global\";var baz = obj.foo;baz.call(obj); // 0 call,apply,bind 也是很好玩的三个方法,有空再另写一篇详细区分一下 4.2 arrow function Es6 的 arrow function 会根据外层作用域来决定 this 的指向,从而避免 this 指向丢失: 12345678var obj3 = { timer() { setTimeout(() => { console.log(this); //function timer }, 1000); }};obj3.timer(); 4.3 保存引用这种是 Es6 之前我们常用的方式,即先手动保存一份需要的执行环境的 this,后面再使用: 1234567891011var self = { a: 0, selfFn() { var _self = this; setTimeout(function() { console.log(_self.a); //0 }, 1000); }};self.selfFn(); 因为 this 引用丢失在 Vue 或者 React 中也存在同样问题并且有多种解决方式,另外放在 Vue 和 React 的笔记里面好了。","link":"/2019/01/06/this绑定丢失及修复/"},{"title":"肯定能看懂的jsonp","text":"jsonp是以前我们用来解决跨域问题的主要手段之一,当时刚接触到我是懵逼的,这个东西跟 json 有个毛的关系? 为什么在 Postman 里面可以跑通的接口,浏览器里面就不行了? JSONP首先,浏览器的同源策略要求的正常通信,包括协议、域名、端口号都要完全一致。 跨域 并不是请求发不出去,请求可以正常发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了,比如你可以在 F12 - NetWork - XHR中看到返回的数据 我们晓得, HTML 有一些标签可以填进去 src 属性来加载外面的资源,比如: <script>,<img>,而这些标签加载资源,是可以跨域加载的。 jsonp 就是利用这些标签能跨域加载资源的特性,来获取服务器上的脚本并执行 为什么会被叫做 jsonp ? 它名字的意义是 json + padding,即,把服务器上的数据,以 json 格式拼接 / 附加(padding)成字符串,然后发回来拼接后的函数及参数 流程: 声明一个回调函数,其函数名(如fb)当做参数值要传递给跨域请求数据的服务器,函数形参为要获取的目标数据(服务器返回的data)。 创建一个 <script> 标签,把跨域的接口地址赋给 script 的 src ,在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=fn)。 服务器接收到请求后,会把传递进来的函数名和它需要给你的数据拼接成一个 json 字符串,例如:传递进去的函数名是fn,它准备好的数据是fn([{"name":"test"}])。 最后服务器把准备的数据返回给客户端,浏览器通过 <script> 标签 src 拿到前面拼接好的内容执行,于是我们就可以对拿到的数据进行操作。 比如淘宝这个API:http://suggest.taobao.com/sug有两个参数 q:你要查询的商品名称 callback:你给它的回调函数名字 比如1234567...html<script>function FYGJsonPTest (data) { console.log(data);}</script><script src=\"http://suggest.taobao.com/sug?q=aaa&callback=FYGJsonPTest\"></script> 部分摘自 segmentfault 当然实际可操作的地方更多,根据服务器配合,可以自定义回调函数的名字或者临时组装一个 script 标签用完再删除掉等等(比如 jQuery 的 ajax 的 JSONP 模式就是包装了这些活儿) 在 jQuery 使用 ajax 以 jsonp 获取数据失败时,试试加上1crossDomain: true jsonp的缺点: 仅支持 get请求 JSONP请求一定需要对方的服务器做支持返回 json格式的数据。 CORSCORS 本名曰: Cross-Origin Resource Sharing ,是H5自带的一项特性,规定了浏览器在跨域访问资源时和服务器怎么通信 在检测到跨域访问时,浏览器会检查响应头 Access-Control-Allow-Origin ,如果包含本域,则跨域请求成功,不是则请求失败,我们就拿不到到响应的数据。 它将对服务器的请求分为了 简单请求 和 复杂请求 两种 简单请求:GET、POST 复杂请求:PUT,DELETE等其他类型如application/json的 POST 请求 对于 复杂请求 ,在发送 ajax 之前,浏览器会先发送一个称为 preflighted 的 OPTIONS 请求,询问目标服务器是否接受接下来的请求的方法,服务器响应的 Access-Control-Allow-Methods头中包含将要发送请求的 Method 时,才会继续发送请求,否则将抛出错误 整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与,需要服务器支持 比如一个php服务器的设置:12header(\"Access-Control-Allow-Origin:*\");header(\"Access-Control-Allow-Methods:POST,GET\"); 不过这种设置存在安全性隐患,因为 Allow-Origin 设置成了 * 通配符,会允许所有域,项目上最好设置成自己服务器的域名和目录 常见其他跨域方式: WebSocket postMessage 可以自己了解一下 然后大家可以在研究一下开始的问题: 为什么在 Postman 里面可以跑通的接口,浏览器里面就不行了?","link":"/2018/12/27/肯定能看懂的jsonp/"},{"title":"手机端摇一摇功能实现","text":"概览我们可以用 H5 添加的传感器API判断移动设备的角度、加速度等数据,比如摇一摇这个功能 移动设备利用 陀螺仪 实现重力感应的数据获取。 主要会用到以下接口: DeviceOrientationEvent :获取设备在各个方向的偏转角度 DeviceMotionEvent : 获取设备移动的加速度 你可以从 F12 控制台 右上角 点点点菜单 ——> More tools ——> Sersors 调出谷歌浏览器自带的移动设备传感器的模拟器,然后在下面的 Orientation 里面选任意角度就可以很方便在PC上进行调试 1 偏转角度 DeviceOrientationEventdeviceorientation 中有以下属性: absolute: 设备是提供的旋转数据是否是绝对定位 (true / false) alpha: 绕z轴旋转的角度(范围在0-360之间)的数字 beta: 绕x轴旋转(范围在-180到180之间)的数字 gamma: 绕y轴旋转(范围在-90到90之间)的数字 使用: 123window.addEventListener('deviceorientation', function(event) { console.log(event.alpha + ' : ' + event.beta + ' : ' + event.gamma);}); 2 加速度 DeviceMotionEventdeviceorientation 中有以下对象: acceleration: 设备在 X ,Y ,Z 轴方向上加速度 有 x , y, z 三个值 accelerationIncludingGravity: 设备在 X, Y, Z 轴方向上带重力的加速度 有 x , y, z 三个值 rotationRate: 设备在 alpha,beta, gamma轴方向上旋转的速率 有 alpha , beta, gamma 三个值 interval: 从设备获取数据的频率 accelerationIncludingGravity 是由用户引起的设备的加速度和由重力加速度的总和,它在部分没有陀螺仪的设备中是唯一可用值,所以 需要检测加速度的时候,最好直接用 e.accelerationIncludingGravity 使用: 123456789101112131415161718window.addEventListener(\"devicemotion\", handleMotion, false);function handleMotion(e) { let acceleration = e.acceleration; let accelerationIncludingGravity = e.accelerationIncludingGravity; let rotationRate = e.rotationRate; let interval = e.interval; let x = acceleration.x; let y = acceleration.y; let z = acceleration.z; let a = rotationRate.alpha; let b = rotationRate.beta; let g = rotationRate.gamma; console.log(`【devicemotion】alpha: ${a}---beta: ${b}---gamma: ${g}---刷新频率: ${interval}`) console.log(`【devicemotion acceleration】x: ${x}---y: ${y}---z: ${z}`)} 3 移动设备的摇一摇比如,两种实现监控摇一摇的操作 1234567891011121314//使用DeviceOrientation事件, 本质是计算偏转角if(window.DeviceOrientationEvent){ var lastAcc; // 用来存储上一次的deviceorientation事件 $(window).on('deviceorientation', function(event) { var delA = Math.abs(event.alpha - lastAcc.alpha); // alpha轴偏转角 var delB = Math.abs(event.beta - lastAcc.beta); // beta轴偏转角 var delG = Math.abs(event.gamma - lastAcc.gamma); // gamma轴偏转角 if ( (delA > 15 && delB > 15) || (delA > 15 && delG > 15) || (delB > 15 || delG > 15)) { // 用户设备摇动了,触发响应操作 // 此处的判断依据是任意两个轴篇转角度大于15度 alert('摇了'); } lastAcc = event; // 存储上一次的event }); 12345678910111213141516171819//可以根据加速度去计算)if(window.DeviceMotionEvent) { var speed = 25; // 用来判定的加速度阈值,太大了则很难触发 var x, y, z, lastX, lastY, lastZ; x = y = z = lastX = lastY = lastZ = 0; window.addEventListener('devicemotion', function(event){ var acceleration = event.accelerationIncludingGravity; x = acceleration.x; y = acceleration.y; if(Math.abs(x-lastX) > speed || Math.abs(y-lastY) > speed) { // 用户设备摇动了,触发响应操作 // 此处的判断依据是用户设备的加速度大于我们设置的阈值 alert('摇了'); } lastX = x; lastY = y; }, false);} 其他检测设备是否支持12345if (window.DeviceOrientationEvent) { // Supported} else { // Not supported } 参考: https://juejin.im/post/59741e6f6fb9a06bca0bd7d1#heading-2 https://developer.mozilla.org/zh-CN/docs/Web/API/DeviceOrientationEvent","link":"/2018/12/20/phone-sensor/"},{"title":"地图组件踩坑","text":"Preview需要在项目中插入地图、寻路功能的,常用有以下地图插件可选择 谷歌地图 百度地图 高德地图 (阿里) 腾讯地图 总的来说,插入地图功能需要以下步骤: 总结需求,技术选型 注册相关账号 申请 API 按官方文档,引入 js,设置容器,插入地图 个性化 经过分析,我的项目(KPCV),需要地图、天气功能,所以选择了 高德地图,它提供了地图功能之外的众多扩展功能,如:3天之内天气预报、定位、交通态势等等。 这里,以 高德地图 为例,从0到1简单记录插入地图功能的入门踩的坑,为大家提供参考。 1 申请 API1.1 注册账号首先搜索 高德地图开放平台,找到 高德开放平台 http://lbs.amap.com/ ,右上角注册一个账号。 1.2 申请相关 API申请完账号,会进入到自己的 控制台 ,我们需要先 创建一个新应用: 从左边菜单打开 应用管理 -> 我的应用 ,点击右上角 创建新应用,设置一个名字,选择一个类型,然后在出现的应用框中找到 右上角 添加新Key,可以看到,在新出来的菜单框中 服务平台 中有多个服务平台可选取: 注意:相关地图库都有 Web端,Android,ios等平台,而在 Web端,一般都会分 Web开发 和 Web服务两种API,这两种 API:Web开发:主要提供围绕 地图 的功能,如:地图显示、标注、路线规划、公交线路等等Web服务:主要提供其他附加功能,如:IP定位、地址解析、坐标系转换、天气、地点搜索等等 显而易见,这个菜单框中的 Web端,Web服务这两种 API 我们都需要,我们先给 Web端 创建一个 key: 选择 Web端,自己输入一个名称,要和后面的 Web服务 区分开,以免自己弄混。然后打上下面 我已阅读 高德地图API服务条款 和 高德服务条款及隐私权政策 勾,提交,就可以看到刚才创建的应用框中多出了一个 Key,且标出了它的名称、绑定服务,绑定服务下面是我们刚才选的 Web端,我们也可以点后面查看配额,因为定位、天气等免费的查询次数每天是有限制的,一般情况下也足够用了。 同样操作,创建一个 Web服务 的key,将两个 key复制保存备用。 2 插入地图2.1 引入 js 文件我们先插入一个基础的地图试试: 在 html 文件中引入 js 文件1<script type=\"text/javascript\" src=\"http://webapi.amap.com/maps?v=1.4.2&key=您申请的key值\"></script> 然后用前面复制下来的 Web端 的 key,替换上面链接中 您申请的key值 字符。 js 文件地址及相关说明可以在这里找到:http://lbs.amap.com/api/javascript-api/summary/#version-introduction 2.2 设置一个容器1<div id=\"mapContainer\"></div> 根据你的需求,为容器设置合适的宽高 给容器设置 id,下面初始化时候需要 2.3 开动 js,创建地图使用 AMap.Map() 构造函数即可,填进去你的容器id:1var myMap = new AMap.Map('mapContainer'); 召唤出来的地图会自动定位到你当前位置。 若需要指定地图定位点,使用官方的 坐标拾取器 获取你所要显示的地点的坐标,然后在AMap.Map() 构造函数中补充参数即可: 坐标拾取器:http://lbs.amap.com/console/show/picker,搜索 惟真科技 ,获得坐标 120.163261,30.184492,复制,填到 center 数组属性中 ↓ 12345var myMap = new AMap.Map('mapContainer',{ center: [120.163261,30.184492], resizeEnable: true, // 自动重置地图尺寸 zoom:11, // 设置缩放级别}); zoom : 地图缩放级别,最大为 20 ,最小为 1,可以根据自己需求设置试试看。 3 插件系统高德地图在基础的地图图层和覆盖物功能之外提供了众多接口,这里以定位的 AMap.Geolocation 插件 和 天气插件 ‘AMap.Weather’ 为例: 3.1 定位插件http://lbs.amap.com/api/javascript-api/reference/location 官网提供了多种加载方式,这里以异步为例:1234567891011121314151617181920212223242526272829var myMap = new AMap.Map('mapContainer',{ center: [120.163261,30.184492], resizeEnable: true, // 自动重置地图尺寸 zoom:11, // 设置缩放级别});// 接上面myMap.plugin(['AMap.Geolocation', 'AMap.Weather'], function () { var geolocation = new AMap.Geolocation({ enableHighAccuracy: true, //是否使用高精度定位,默认:true timeout: 10000, //超过10秒后停止定位,默认:无穷大 useNative: true, //是否使用安卓定位 sdk 用来进行定位,默认:false zoomToAccuracy: true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true showMarker: true, //定位成功时是否在定位位置显示一个 Marker showCircle: true, //定位成功并且有精度信息时,是否用一个圆圈 circle 表示精度范围 }); myMap.addControl(geolocation); geolocation.getCurrentPosition(); AMap.event.addListener(geolocation, 'complete', function (response) { //定位完成后的回调 console.log(response) console.log(\"您位于:\"+response.addressComponent.province + response.addressComponent.city + response.addressComponent.district + response.addressComponent.township); }); AMap.event.addListener(geolocation, 'error', function (response) { //定位出错后的回调 });}); 定位成功后返回的对象中,addressComponent 里面是详细地址,你可以看看返回的所有数据~ 3.2 天气插件天气插件用到了 Web服务 的 key,因此,你需要先复制过来Web服务 的 key 查询天气的 API地址为: 1http://restapi.amap.com/v3/weather/weatherInfo?参数&key=“您的key” 其中, key 是必须的参数,其他参数为选填,一个例子: 12345678910$.ajax({ method: \"GET\", url: 'http://restapi.amap.com/v3/weather/weatherInfo?city='杭州市'&extensions=all&key=你的key', dataType: \"json\", // crossDomain: true,}).done(function (res) {// 返回的参数中 res.lives为今日天气 res.forecasts[0] 为预报天气}).fail(function (res) { // 定位失败返回的对象}) 返回具体的数据自己可以看看都有哪些,对应数据代表的含义见官方:http://lbs.amap.com/api/webservice/guide/api/weatherinfo 4 其他服务除了插件, javascript控件自身也带了许多服务,可以实现相同功能,如道路交叉口查询服务AMap.RoadInfoSearch、天气查询 AMap.Weather: 12345 AMap.service('AMap.Weather', function() { var weather = new AMap.Weather(); //查询实时天气信息, 查询的城市到行政级别的城市,如朝阳区、杭州市 weather.getLive('杭州市', function(err, data) { }) 文档参见:http://lbs.amap.com/api/javascript-api/reference/search_plugin 实例:http://lbs.amap.com/api/javascript-api/example/weather-forecast/weather-forecast 补充 所有国产地图插件的套路都是一样的:申请账号、申请key、引入文件、创建容器、插入地图,以上仅仅是最简单的从 0 到 1 实现一个地图,及相关服务、插件的最简单介绍,尽量降低第一次上手地图插件的难度,更详细的用法、详尽的功能,请自己多试试,多看看官网文档 官网文档地址 http://lbs.amap.com/api/webservice/gettingstarted 官方所有例子 http://lbs.amap.com/api/javascript-api/example/map/map-show","link":"/2018/12/19/map-plugin/"}],"tags":[{"name":"javascript","slug":"javascript","link":"/tags/javascript/"},{"name":"phone","slug":"phone","link":"/tags/phone/"},{"name":"前端","slug":"前端","link":"/tags/前端/"},{"name":"hexo","slug":"hexo","link":"/tags/hexo/"},{"name":"map","slug":"map","link":"/tags/map/"},{"name":"ajax","slug":"ajax","link":"/tags/ajax/"}],"categories":[{"name":"前端","slug":"前端","link":"/categories/前端/"}]}