hashchange事件及其妙用

3年前

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);
3769次阅读,0条评论

ECMAScript 6中的面向对象

3年前

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

类声明与类表达式

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

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

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

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

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

3年前

在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
1462次阅读,1条评论

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

3年前

严格来说,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
1719次阅读,2条评论

深入理解JavaScript中的面向对象(一)

3年前

在学习JavaScript的过程中,面向对象是必须要学会的课题。然而,网络上大部分文章只是简单地讲述如何通过代码实现面向对象,忽略了理论和原理方面的知识。本系列文章将从头开始逐步讲解面向对象编程思想及其在JavaScript中的实现与应用。

从一个简单的需求开始

假设我们需要在程序中计算各种形状的周长,代码可能是这样的:

var rectangle = {
	name: '长方形1',
	type: 'rectangle',
	length: 5,  // 长
	width: 10   // 宽
};
var square = {
	name: '正方形1',
	type: 'square',
	length: 5  // 边长
};
var circle = {
	name: '圆形1',
	type: 'circle',
	radius: 5  // 半径
};

function computePerimeter(shape) {
	var result;
	switch (shape.type) {
        case 'rectangle':
        	// 矩形周长:(长+宽)*2
        	result = (shape.length + shape.width) * 2;
        	break;
        case 'square':
        	// 正方形周长:边长*4
        	result = shape.length * 4;
        	break;
        case 'circle':
        	// 圆形周长:2*PI*半径
        	result = 2 * Math.PI * shape.radius;
        	break;
    }

    return shape.name + '的周长是' + result;
}
2521次阅读,1条评论

JavaScript动画实现原理

3年前

假设有这样一个动画功能需求:把一个div的宽度从100px变化到200px。写出来的代码可能是这样的:

<div id="test1" style="width: 100px; height: 100px; background: blue; color: white;"></div>
function animate1(element, endValue, duration) {
	var startTime = new Date(),
		startValue = parseInt(element.style.width),
		step = 1;
	
	var timerId = setInterval(function() {
		var nextValue = parseInt(element.style.width) + step;
		element.style.width = nextValue + 'px';
		if (nextValue >= endValue) {
			clearInterval(timerId);
			// 显示动画耗时
			element.innerHTML = new Date - startTime;
		}
	}, duration / (endValue - startValue) * step);
}

animate1(document.getElementById('test1'), 200, 1000);

原理是每隔一定时间增加1px,一直到200px为止。然而,动画结束后显示的耗时却不止1s(一般是1.5s左右)。究其原因,是因为setInterval并不能严格保证执行间隔

9134次阅读,1条评论

Micro-Templating性能优化

3年前

这篇文章中,我简单介绍了前端模板引擎。John Resig写的tmpl函数麻雀虽小五脏俱全,足以满足日常开发需要。本文主要探讨一下tmpl的性能优化。

先复习一下tmpl的源代码:

var tmpl = (function() {
	var cache = { };

	return function(str, data) {
		var fn = cache[str];
		if (!fn) {
			fn = new Function("obj",
				"var p=[];" +
				"with(obj){p.push('" +
				str
					.replace(/[\r\t\n]/g, " ")
					.split("<%").join("\t")
					.replace(/((^|%>)[^\t]*)'/g, "$1\r")
					.replace(/\t=(.*?)%>/g, "',$1,'")
					.split("\t").join("');")
					.split("%>").join("p.push('")
					.split("\r").join("\\'")
				+ "');}return p.join('');"
			);
			cache[str] = fn;
		}

		return fn(data);
	};
})();
812次阅读,1条评论

ECMAScript 5中的属性描述符

4年前

属性描述符是ES5中新增的概念,其作用是给对象的属性增加更多的控制。

Object.defineProperty

要研究属性描述符,首先要谈谈 Object.defineProperty 方法。这个方法的作用是给对象定义新属性或修改已存在的属性。其原型如下:

Object.defineProperty(obj, prop, descriptor)

使用示例:

var obj = { };
Object.defineProperty(obj, 'attr', { value: 1 });
979次阅读,1条评论

从千分位格式化谈JS性能优化

4年前

所谓的数字千分位形式,即从个位数起,每三位之间加一个逗号。例如“10,000”。针对这个需求,我起初写了这样一个函数:

// 方法一
function toThousands(num) {
	var result = [ ], counter = 0;
	num = (num || 0).toString().split('');
	for (var i = num.length - 1; i >= 0; i--) {
		counter++;
		result.unshift(num[i]);
		if (!(counter % 3) && i != 0) { result.unshift(','); }
	}
	return result.join('');
}
4593次阅读,6条评论

动态创建iframe在IE下的两个问题

4年前

表单提交到动态创建的iframe

问题描述

以下代码,一般用于在当前页无刷新提交表单,其原理是把表单的target设为页面上某个iframe的id,使该iframe成为提交的目标,避免新开窗口或跳转。但这段代码在IE 6、7下无效。

<form action="http://www.baidu.com/" method="post" target="testframe">
	<input type="submit" value="Submit" />
</form>
<script>
var iframe = document.createElement('iframe');
iframe.id = 'testframe';
iframe.name = 'testframe';
document.body.insertBefore(iframe, document.body.firstChild);
</script>
1295次阅读,1条评论