Vue.js踩坑记

2个月前

前言

上一篇文章主要介绍了我们团队的「Vue.js项目模板」的搭建过程,这只是第一步。作为新手,在实际开发过程中,难免还会遇到各种各样奇怪的问题。本文主要介绍问题的起因以及解决方式。

导航栏标题

在单页应用中,由于页面切换不会导致浏览器重新加载页面,所以页面的标题是不会改变的,这时候就要通过Javascript去修改标题。这个操作本来是非常简单的,只需要修改「document.title」即可:

document.title = 'New title';

然而,在iOS的微信和QQ中,这种方法可能无效,具体的现象就是:导航栏上的标题没有改变。这是iOS微信和QQ的bug,解决方法就是在修改「document.title」之后,用「iframe」发送一个请求(任意一个请求)。把相关的代码封装成函数:

function setTitle(title) {
    document.title = title;
	if (isIOS && (isInWeixin || isInQQ)) {
        let iframe = document.createElement('iframe');
        iframe.style.display = 'none';
        iframe.src = '/favicon.ico';
        iframe.onload = () => {
            setTimeout(() => {
                document.body.removeChild(iframe);
            }, 9);
        };
        document.body.appendChild(iframe);
    }
}

据说新版的微信和QQ已经修复了这个bug,但为了兼容旧版本,这段代码还是必须的。

416次阅读,0条评论

Vue.js项目模板搭建

2个月前

前言

从今年(2017年)年初起,我们团队开始引入「Vue.js」开发移动端的产品。作为团队的领头人,我的首要任务就是设计整体的架构。一个良好的架构必定是具备丰富的开发经验后才能搭建出来的。虽然我有多年的前端开发经验,但就「Vue.js」来说,仍然是个新手。所幸「Vue.js」有一个配套工具「Vue-CLI」,它提供了一些比较成熟的项目模板,很大程度上降低了上手的难度。然而,很多具体的问题还是要自己思考和解决的。

项目划分

我们公司的H5产品大部分是嵌套在手机客户端里面的页面。每个项目的功能都比较独立,而且规模不大。这样一来,既可以让这些小项目各自为政,也可以把它们集中放到一个大项目中管理。各自的优缺点如下:

 一个大项目多个小项目
代码仓库一个多个
代码冲突可能性大可能性小
独立发布不可行可行
公共代码共用一份重复维护、加载

考虑到我们团队刚开始使用「Vue.js」,需要逐步摸索出合适的架构。如果做成一个大项目,一旦架构要调整,很可能会伤筋动骨。所以最终的选择是划分成多个小项目

262次阅读,0条评论

X5同层播放器试用报告

4个月前

移动端浏览器中的video元素是比较特别的,早期无论是在iOS还是Android的浏览器中,它都位于页面的最顶层,无法被遮盖。后来这个问题在iOS下得到了解决,但是Android的浏览器则问题依旧。X5是腾讯基于Webkit开发的渲染引擎,它提供了一种名叫「同层播放器」的特殊video元素以解决遮盖问题。

简单使用

同层播放器的使用方式跟普通的video元素差别不大,只是需要加上两个X5的自定义属性:「x5-video-player-type」和「x5-video-player-fullscreen」。

下面做一个测试页面嵌入同层播放器:

body {
	margin: 0;
	background: #000;
	font-size: 0.3rem;
}
.player {
	width: 100%;
	height: 4.22rem;
}
.player .video {
	width: 100%;
	height: 100%;
}
<video id="video" class="video" controls="controls" playsinline x5-video-player-type="h5" x5-video-player-fullscreen="true">
    <source src="video.mp4" />
</video>
591次阅读,0条评论

setTimeout/setInterval的最大延时值

1年前

先来看这样一段代码:

function update() {
    loadData().then(function(data) {
        $('#content').html(data.content);
        var delay = data.nextUpdateTime - new Date();
        if (delay > 0) {
            setTimeout(update, delay);
        }
    });
}

其流程非常简单:通过AJAX加载数据后更新HTML的内容;如果有指定下次更新时间,则通过计时器在该时间点再执行一次整个流程。

要说这段代码有什么隐患的话,那就是data.nextUpdateTime与当前时间的时间差(即delay变量的值)比较小的时候,会导致内容频繁更新。但这是属于正常的业务逻辑,要优化就只能牺牲内容更新的即时性。然而这里我要说的是,当时间差非常大的时候,也会出现同样的问题。

551次阅读,0条评论

安卓版微信Webview中两个页面互相跳转的BUG

1年前

都说微信是移动端的IE6,不管你们信不信,反正我信了。最近在开发过程中就遇到了一个极其容易触发的BUG。

复现这个BUG只需要两个页面「a.html」以及「b.html」,并且两个页面都有跳去另一个页面的链接:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>A</title>
</head>

<body>
<h1>I am A.</h1>
<p><a href="b.html">to B</a></p>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>B</title>
</head>

<body>
<h1>I am B.</h1>
<p><a href="a.html">to A</a></p>
</body>
</html>

先打开「a.html」,点击链接跳转到「b.html」,再点击「b.html」中的链接跳转到「a.html」。如此往复点击跳转几次,就会出现无法再次跳转的情况(会出现进度条,但是无法跳转)。

1514次阅读,0条评论

hashchange事件及其妙用

2年前

hash即URL中“#”字符后面的部分。使用浏览器访问网页时,如果网页URL中带有hash,页面就会定位到id(或name)与hash值一样的元素的位置,故而又称之为锚点。hash还有另一个特点,它的改变不会导致页面重新加载,因此在单页应用流行的当下,它的用处就更多了。

而hashchange事件,顾名思义,就是hash改变时触发的事件。在 caniuse.com 上查一下兼容性可以发现,IE8就已经支持该事件,但一直以来应用甚少。

hashchange事件兼容性

hashchange事件触发时,事件对象会有hash改变前的URL(oldURL)和hash改变后的URL(newURL)两个属性:

window.addEventListener('hashchange', function(e) {
	console.log(e.oldURL);
	console.log(e.newURL);
}, false);
2544次阅读,0条评论

网页版简历制作经验分享

2年前

2012年中,因为换工作面试的需要,我得更新旧的简历。但是在Word中排版实在是各种不顺手,于是就发挥了作为前端工程师的优势把简历做成了网页;2014年末想换工作时又对其进行了改版。这份简历曾经受到好几位HR和猎头的好评,所以特地分享制作经验,也算是给想换工作的同行参考。

进入正题之前,先想想HTML简历的好处:

  • 无须下载,直接打开。
  • 可以采用更丰富的设计和更灵活的排版。
  • 可以通过超链接访问其他资源。
  • 可以顺带展示自己设计以及前端方面的技能。

而在此基础上,我还给这份简历定下了以下目标:

  • 一个页面中展示所有内容。
  • Write once, run anywhere. 兼容PC设备与移动设备,最好还能直接打印。
  • 简单实用,最好连JS都不用写。那些用上了各种动画做出来的甚至是做成了小游戏的炫酷简历,其实并不利于阅读。

好了,下面具体讲讲如何打造这样一份简历。

3076次阅读,13条评论

ECMAScript 6中的面向对象

2年前

ECMAScript 6(下面简称ES6)增强了对面向对象的支持,引入了class关键字,并且为类的创建、继承提供了简洁清晰的语法。

类声明与类表达式

毋庸置疑,class关键字就是用来定义类的。

定义类的常用方式是类声明,语法如下:

class ClassName {
	// 构造函数
	constructor() {
		// ...
	}

	// 方法
	method() {
		// ...
	}
}
862次阅读,2条评论

深入理解Javascript中的面向对象(三)

2年前

在Javascript中,虽然借助原型链就可以实现继承,但这里面还是有很多细节问题的要处理的。分析并解决这些问题后,就可以把创建类的过程写成一个通用函数了。

constructor属性

Javascript中的对象都有一个constructor的属性指向其构造函数。例如:

function A() { }
var a = new A();
a.constructor; // A

确切地说,constructor属性是位于构造函数的prototype上。下面的代码可以证实这一规则:

function A() { }

var a = new A();
console.log(a.constructor); // A

delete A.prototype.constructor; // 删除原型上的constructor属性
console.log(a.constructor); // Object
1210次阅读,1条评论

深入理解Javascript中的面向对象(二)

2年前

严格来说,Javascript并不是一门面向对象的语言,因为它没有原生提供完整的面向对象机制。但它的语言特性又允许我们去模拟大部分这些机制。

new操作符

Javascript中也用new操作符创建类的实例,例如:

var arr = new Array(10); // 创建长度为10的数组
var date = new Date; // 不需要传参数给构造函数时,括号可以省略

与C#不同的是,Javascript中new的是函数而不是class,这个函数即为类的构造函数。在构造函数中,可以声明属性和方法。例如:

function Square() {
	this.length = 1;
	this.perimeter = function() {
		return this.length * 4;
	};
}

var square = new Square();
square.perimeter(); // 4
square.length = 10;
square.perimeter(); // 40
1384次阅读,2条评论