自定义jQuery,理解jQuery核心实现原理

实现核心功能:
1.自定义$(selector)函数,通过$(‘#red’),$(‘.gold’)调用;
2.添加.html,.css, .attr方法;

jQuery优点:
1.隐式迭代(自动循环)
2.完美的链式操作(连贯操作)
3.完美的错误处理(不报错)

自定义jquery代码:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// 自调函数引入
(function(window){
	window.$ = $;
	window.jQuery = $;	//取别名

	function $(selector)
	{
		var mark = selector.substr(0,1);
		var element = selector.substr(1);

		var obj = [];
		switch(mark){
			case '#':
				obj[0] = document.getElementById(element);
				break;

			case '.':
				obj = document.getElementsByClassName(element);
				break;

			default:
				obj = document.getElementsByTagName(element);
				break;
		}
		console.dir(obj);

		obj.html = function(val)
		{
			if (val === undefined) {
				return obj[0].innerHTML;
			} else{
				for(var i=0; i<obj.length; i++)
				{
					obj[i].innerHTML = val;
				}
			}
			//实现连贯操作
			return this;
		}

		//用于修改style样式的方法
		obj.css = function(key,val)
		{
		    if (val === undefined) {
		        return obj[0].style[key];
		    } else {
		        for (var i=0; i<obj.length; i++) {
		            obj[i].style[key] = val;
		        }
		    }
		    //实现连贯操作
		    return this;
		}

		// 修改属性
		obj.attr = function(key, val)
		{
			if (val === undefined) {
				return obj[0][key];
			} else{
				for (var i = 0; i < obj.length; i++) {
					obj[i][key] = val;
				}
			}
			return this;	//实现连贯操作
		}

		return obj;
	}
}(window));

html:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//**********************html部分代码*************/
	<p>111111111111111111</p>
	<p id="red">111111111111111111</p>
	<p class="gold">111111111111111111</p>
	<p>111111111111111111</p>
	<p>111111111111111111</p>
	<p>111111111111111111</p>
	<p id="attr" title="获得属性">111111111111111111</p>
	<p title="2222">111111111111111111</p>
	<p title="3333">111111111111111111</p>
	<p>111111111111111111</p>
	<p>111111111111111111</p>

//**********************js部分代码*************/
<script>
	// 原生js
	// var red = document.getElementById('red');
	// red.style.color = 'red';

	// jQ写法:$('#red').css('color', 'red')
	// $('#red').css('color', 'red');
	$('.gold').css('color', 'red');
	$('#red').html('123');
	// alert($('#red').html());

	// 修改属性
	// alert($('#attr').attr('title'));
	$('#attr').attr('title', '修改属性值');
</script>

源码:https://github.com/webjust/case-study/blob/master/jquery/01custom_my_jquery/js/myjquery.js

图文解析JavaScript如何实现弹弹球效果的过程

弹弹球的最终效果:
03

本文将用图文的方式,解析实现弹弹球效果的关键代码部分。

如表格所示:
弹弹球效果

参数说明:
box.style.top: 小球距离顶部的距离
speed: 表示小球的速度。(speed += 5) 表示小球每次执行操作的时候,速度加5。这从小球每次的speed值可以很直观的看出,不难理解。

关键在于:这里小球距离地面的高度为100px;所以当box.style.top值为100px时,表名小球触地了,这个时候,speed速度值应该反向。

Select Code
1
2
3
4
if(tmp >= 100) {
	speed = -speed;
	tmp = 100;
}

02

举例:小球下落,每次速度加5,到达地面速度为20。这时速度speed值反向,变成-20;然后speed+=5,此时的速度值为-15(负数表示球的运行方向是:向上)。

向上,直到速度变为0,球在上升到最高后,speed值再变为正数,球下落。

01

JS代码如下:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var box = document.getElementById('box');
var timer;
function start()
{
	var speed = 0;
	if (!timer){
		timer = setInterval(function(){
			speed += 5;
			var tmp = parseInt(box.style.top) + speed;
			if(tmp >= 100) {
				speed = -speed;
				tmp = 100;
			}
			box.style.top = tmp + 'px';
			console.log(box.style.top);
			console.log(timer);
		},100);
	}
}

function stop()
{
	clearInterval(timer);
	timer = undefined;
	console.log(timer);
}

完整源代码:https://github.com/webjust/case-study/blob/master/Javascript/002/jump_ball_javascript.html

JavaScript的setInterval()函数写一个来回移动的小球剖析

小球来回移动实现步骤:

小球来回移动1

原理:通过绝对定位,定位小球相对文档的位置,使用left值定位。所以控制小球来回移动,就是(不停的)改变left值的大小。

setInterval()

setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。
setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。

我们假设:小球每秒移动一次,移动到100px然后返回,那么left值的变化过程是(单位是px):

0,10,20,30,40,50,60……100 (每次移动累+10)
然后返回
100……60,50,40,30,20,10,0 (每次移动累-10)

小球来回移动2

Select Code
1
2
3
4
5
6
7
8
9
//每次移动的像素的大小
	step = 10;
	num += step;
	if(num==100 || num==0){
		step = -step;
	}

	//小球的left值
	box.style.left = num + "px";

解释:通过在当num值在最大和最小时,step变为正、负数。而变为累加、累减。

代码:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="box" style="left:0;"></div>

	var box = document.getElementById('box');
	var num=0;
	var step = 10;
	setInterval(function(){
		//在console面板输出num值
		console.log(num);
		box.style.left = num + "px";
		num += step;
		
		//在title输出num值
		document.title = box.style.left;
		
		if(num==100 || num==0){
			step = -step;
		}
	},1000);

图片跟随鼠标效果实现步骤详解(源码分享)

演示效果GIF动画:

图片跟随鼠标效果
图片跟随鼠标效果

图片跟随鼠标效果实现步骤:

1、图片绝对定位,通过修改left和top属性,来移动图片
#img{position: absolute; left: 0; top: 0;}

2、获取图片对象
var img = document.getElementById(‘img’);

3、文档的鼠标移动事件,执行函数
document.onmousemove = function(e){执行代码}

4、代码部分为修改图片的属性
img.style.left = e.clientX + ‘px’;
img.style.top = e.clientY + ‘px’;

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#img{position: absolute; left: 0; top: 0; border:1px solid #ccc;}

<img id="img" src="./123.jpg" alt="" width="200" />
<div>X:<span id="xitem">横坐标</span> / Y:<span id="yitem">纵坐标</span></div>
//script代码开始
var img = document.getElementById('img');
var x = document.getElementById('xitem');
var y = document.getElementById('yitem');

document.onmousemove = function(e)
{
img.style.left = e.clientX + 'px';
img.style.top = e.clientY + 'px';

x.innerHTML = e.clientX;
y.innerHTML = e.clientY;
}
//script代码结束

完整源码见:https://github.com/webjust/case-study/tree/master/Javascript/001

新手要掌握的JavaScript的6种调试方式汇总

console.dir() 在控制面板打印数组

1、alert() 弹窗
2、document.write() 打印,致命的问题是代码执行完毕后,会覆盖页面的内容(等同于PHP中的echo)
3、console.log() 在控制台输出内容(在Chrome浏览器中调试)。(不能解析HTML内容)
4、console.dir() 打印数组。(等同于PHP中的print_r)
5、document.title() 在网页的title标签中输出内容。
6、debugger 断点。在调试工具中,点一步执行一步。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<script>
// 1 弹窗
var num = 1;
num++;
alert(num);

// 2 输出内容
document.write(num);

// 3 在控制面板输出内容
var str = 'i love <br>javascript.'	//原样输出
var str = 'i love \njavascript.'	//换行输出
console.log(str);

// 4 在控制面板打印数组
var list = ['zhangsan', 'Guang Zhou', '1990.12.10'];
console.dir(list);

// 5 在网页标题输出
// document.title='JS的5种调试方式';
document.onmousemove = function(e){
	document.title = 'X: ' + e.clientX + ' Y: ' + e.clientY;
}
/*鼠标属性,事件*/

// 6 debugger
debugger;
</script>

PHP单态设计模式分步骤详解实现过程

单态设计模式的目的:一个类只生成一个实例。

1、动态方法new,每次实例化,都是一个新的对象。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!--?php &lt;br ?--> /**
* 声明一个类
*/
class Model
{

function __construct()
{
echo "初始化对象
";
}

}

$p1 = new Model();
$p2 = new Model();

if ($p1===$p2) {
echo "Y";
} else{
echo "N";
}

/*
输出结果:
初始化对象
初始化对象
N
*/

?>

2、封装构造方法,禁止外部通过new实例化对象,那么通过对象内部的方法来实例化1个对象。(问题:内部的方法,只有通过对象访问)
3、使用static静态化修饰方法,这样可以在外部使用”类名::静态方法名”来访问。
4、/*在静态方法里实例化对象*/ 注意:静态成员时属于类的,而不属于任何对象,所以不能用$this来引用它,所以需要使用关键字”self”来访问其他静态成员。在使用静态方法时,在静态方法中只能访问静态成员。因为非静态的成员必须通过对象的引用才能访问,通常是使用$this完成的。
这一步使用:return new self; 实例化这个类。
每次实例化,还是会创建1个新的类。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!--?php &lt;br ?--> class Model
{

private function __construct()
{
echo "初始化对象
";
}

public static function getModel(){
/*在静态方法里实例化对象*/
// return new $this;会报错,在静态方法中不能使用$this。
return new self;
}

}

$p1 = Model::getModel();
$p2 = Model::getModel();

// var_dump($p1);
// var_dump($p2);

if ($p1===$p2) {
echo "Y";
} else{
echo "N";
}

/*
访问结果:
初始化对象
初始化对象
N
*/
?>

5、增加一个判断。判断如果已经创建了1个对象,则直接返回当前的对象,如果为空则实例化对象。

步骤:(1)、定义一个静态的属性$newObj存储对象;
(2)、使用条件语句判断is_null(self::$newObj),则实例化对象。
备注:在类中声明的方法中,可以使用关键字”self”来访问其他静态成员,在类的成员方法中用来代表本类的关键字。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!--?php &lt;br ?--> class Model
{
static private $newObj = NULL;
private function __construct()
{
echo "初始化对象
";
}

public static function getModel(){
/*在静态方法里实例化对象*/
// return new $this;会报错,在静态方法中不能使用$this。
if (is_null(self::$newObj)) {
return self::$newObj=new self;
} else{
return self::$newObj;
}
// return self::$newObj;

}

}

$p1 = Model::getModel();
$p2 = Model::getModel();

var_dump($p1);
var_dump($p2);

if ($p1===$p2) {
echo "Y";
} else{
echo "N";
}

/*
运行结果:
初始化对象
object(Model)[1]
object(Model)[1]
Y
*/
?>

插曲:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 方法1:正确
public static function getModel(){
if (is_null(self::$newObj)) {
return self::$newObj=new self;
} else{
return self::$newObj;
}
}

// 方法2:正确
public static function getModel(){
if (is_null(self::$newObj)) {
self::$newObj=new self;
}
return self::$newObj;
}

// 方法3:错误
public static function getModel(){
if (is_null(self::$newObj)) {
self::$newObj=new self;
} else{
return self::$newObj;
}
}
// 方法3错误的原因是:$p1为空,没有return返回,所以生成1个NULL值