jQuery实现网页定位滚动导航条

实际效果

实现原理

主要知识点
滚动事件:scroll

当用户滚动指定的元素时,会发生 scroll 事件。

jQuery 代码:

Select Code
1
$(window).scroll( function() { /* ...do something... */ } );

find()

搜索所有与指定表达式匹配的元素。这个函数是找出正在处理的元素的后代元素的好方法。

位置

  • scrollTop:获取匹配元素相对滚动条顶部的偏移。
  • offset:获取匹配元素在当前视口的相对偏移。返回的对象包含两个整型属性:top 和 left。此方法只对可见元素有效。

attr()

设置或返回被选元素的属性值。

css类

  • addClass:为每个匹配的元素添加指定的类名。
  • removeClass:从所有匹配的元素中删除全部或者指定的类。

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
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
71
72
73
74
75
76
77
78
79
80
81
82
<div id="menu">
<ul>
 	<li><a class="current" href="#item1">1F 男装</a></li>
 	<li><a href="#item2">2F 女装</a></li>
 	<li><a href="#item3">3F 美妆</a></li>
 	<li><a href="#item4">4F 数码</a></li>
 	<li><a href="#item5">5F 母婴</a></li>
</ul>
</div>
<div id="content">
<h1>美丽说</h1>
<div id="item1" class="item">
<h2>1F 男装</h2>
<ul>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="1F.jpg" alt="" /></a></li>
</ul>
</div>
<div id="item2" class="item">
<h2>2F 女装</h2>
<ul>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="2F.jpg" alt="" /></a></li>
</ul>
</div>
<div id="item3" class="item">
<h2>3F 美妆</h2>
<ul>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="3F.jpg" alt="" /></a></li>
</ul>
</div>
<div id="item4" class="item">
<h2>4F 数码</h2>
<ul>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
 	<li><a href="#"><img src="4F.png" alt="" /></a></li>
</ul>
</div>
<div id="item5" class="item">
<h2>5F 母婴</h2>
<ul>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
 	<li><a href="#"><img src="5F.jpg" alt="" /></a></li>
</ul>
</div>
</div>

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
<script>
    $(document).ready(function () {
        $(window).scroll(function () {
            var items = $("#content").find(".item");
            var menu = $("#menu");
            var top = $(document).scrollTop();
            var currentId = "";
            items.each(function () {
                var m = $(this);
                if (top > m.offset().top  - 100) {
                    currentId = "#" + m.attr("id");
                } else {
                    return false;
                }
            });

            var currentLink = menu.find(".current");
            if (currentId && currentLink.attr("href") != currentId) {
                currentLink.removeClass("current");
                menu.find("[href=" + currentId + "]").addClass("current");
            }
        });
    })
</script>

网页从静态到MVC的进化史

一、静态网站
(1个html => 1个页面)
************************************
1. 纯静态页面
举例:
1.html

二、动态网站
(数据库中的1条记录 => 1个网页)
************************************
1. 面向过程,写一个文章管理、发布功能。
(请求:1个php页面 => 1个php模块)
举例:
article.php?id=1
// php代码和html混合式开发:1个php页面,写1次「数据库的天龙八部」。

2. 面向对象:使用Model类,翻页类,模板引擎实现文章管理、发布功能。
(自己封装类,提升代码的可重用性)
举例:
article.php?id=1
// 第一步:使用require_once(‘./lib/Model.class.php’) 引入Model类。引入数据库的配置文件。
// 第二步:实例化一个类,$model = new Model(); 准备好SQL语句:$sql=’SELECT * FROM `article`’。
// 第三步:调用Model类中的方法:$ret = $model->select($sql)。返回查询的结果集。

3. 使用组件式开发:
(自己写太麻烦,使用第三方插件,不重复造轮子了… (*^__^*) 嘻嘻……)
如:数据库、验证码组件:

  • catfan/medoo
  • gregwar/captcha

4. MVC设计模式

  • 模型
  • 视图
  • 控制器

(单一入口,在入口文件引入使用到的类,使用命名空间防止类名重复。加入路由负责请求url映射,请求1个页面,实际上是访问1个函数)

举例:
// 第一步:请求文章页面 ../article/1
// 第二步:URL映射到:article控制器,访问showarticle(1)方法传递了参数:文章id
// 第三步:在方法中,调用了Model模型层,获取结果集。
// 第四步:将返回的结果集,传递给视图层,组装成HTML的字符串。
// 第五步:响应:把HTML字符串传送给浏览器

5. 框架

  • Laravel
  • YII
  • ThinkPHP

集成了一些:管理工具
如:包管理工具、数据库迁移、命令行工具
组件:请求、响应

第一个MVC框架

一、MVC基础知识
1、MVC 是单入口,单入口文件index.php, 引入大量类文件,定义一些常量。
2、通过入口文件,实例化一个控制器类,调用控制器类中的方法。
3、运行过程:通过在访问的控制器中的方法里面,去拿数据(访问Model层中方法),然后把数据传给视图层(模板引擎,view层), 最终通过控制器调用显示(show)的方法。

index.php?controller=控制器名&method=方法名

\index.php

Select Code
1
2
3
4
5
6
7
<?php
require_once('testModel.class.php');	// 引入模型
require_once('testView.class.php');		// 引入视图
require_once('testController.class.php');	// 引入控制器

$obj = new testController();
$obj->show();

\testModel.class.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class testModel
{
    public function get()
    {
        return 'hello mvc';
    }

    public function delete()
    {
//
    }
}

\testView.class.php

Select Code
1
2
3
4
5
6
7
8
<?php
class testView
{
    public function display($data)
    {
    	echo $data;
    }
}

\testController.class.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
<?php
class testController
{
    public function show()
    {
        $model = new testModel();
        $data = $model->get();

        $view = new testView();
        $view->display($data);
    }
}

二、第一个MVC框架
\functions.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
function C($name, $method)
{
    require_once('./libs/Controller/' . $name . 'Controller.class.php');
    eval('$obj = new ' . $name . 'Controller(); $obj->' . $method . '();');
}

function M($name)
{
    require_once('./libs/Model/' . $name . 'Model.class.php');
    eval('$obj = new ' . $name . 'Model();');
    return $obj;
}

function V($name)
{
    require_once('./libs/View/' . $name . 'View.class.php');
    eval('$obj = new ' . $name . 'View();');
    return $obj;
}

\index.php

Select Code
1
2
3
4
5
6
7
8
9
10
<?php
include('./functions.php');

// index.php?controller=控制器&method=方法
// index.php?controller=test&method=list

$controller = $_GET['controller'] ? $_GET['controller'] : 'index';
$method = $_GET['method'] ? $_GET['method'] : 'index';

C($controller, $method);

\libs\Controller\testController.class.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
class testController
{
    public function show()
    {
        $model = M('test');
        $data = $model->get();

        $view = V('test');
        $view->display($data);
    }

    public function list()
    {
        echo 'list方法';
    }

    public function detail()
    {
        echo '详情页面';
    }
}

\libs\Model\testModel.class.php

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
<?php
class testModel extends \PDO
{
    public function __construct()
    {
        $dsn = 'mysql:dbname=web;host=localhost;charset=UTF8';
        $username = 'root';
        $passwd = 'root';
        parent::__construct($dsn, $username, $passwd);
    }

    public function get()
    {
        $sql = "SELECT * FROM `cat`";
        $data = $this->query($sql);
        return $data->fetchAll();
    }

    public function delete()
    {
//
    }
}

\libs\View\testView.class.php

Select Code
1
2
3
4
5
6
7
8
<?php
class testView
{
    public function display($data)
    {
        var_dump($data);
    }
}

命名空间与Traits的使用

一、命名空间
使用场景:
一个大型的项目,由很多人来共同完成的,很多时候会出现类名重复的问题。

解决问题:
命名空间
1. 使用关键字 namespace 声明一个类,它的位置一定是要放在 整个脚本文件的前面,它的前面不能由输出。
2. 使用了命名空间的类的调用,必须在类名前 加上命名空间的值。
3. 可以使用 use 关键字,直接引入类。使用方法就是 use 关键字后面 接上 「命名空间\类名」
4. 使用命名空间中的别名,关键字是 as.

\index.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
<?php
error_reporting(null);
include('Test1.php');
include('Test2.php');

use App\Think\Test;
use App\Laravel\Test as LTest;

$obj1 = new App\Think\Test();                   // 实例化的是Test1中的Test类
$obj2 = new App\Laravel\Test();                 // 实例化的是Test2中的Test类
$obj3 = new Test();                             // 实例化的是Test1中的Test类
$obj4 = new LTest();                            // 实例化的是Test2中的Test类

\Test1.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
<?php

namespace App\Think;

class Test
{
    public function __construct($num1, $num2)
    {
        var_dump("这是Test1文件中的Test类");
    }
}

\Test2.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
<?php

namespace App\Laravel;

class Test
{
    public function __construct()
    {
        var_dump("这是Test2文件中的Test类");
    }
}

二、命名空间的使用
有3个同名的类文件,使用命名空间可以同时使用这些类文件。

\index.php

Select Code
1
2
3
4
5
6
7
8
9
<?php
include('./A.php');
include('./B.php');
include('./C.php');

// 访问 A 中的 getinfo() 方法
$obj1 = (new \App\Apple())->getInfo();
$obj2 = (new \Apple())->getInfo();
$obj2 = (new \C\Apple())->getInfo();

使用了命名空间的类的调用,必须在类名前 加上命名空间的值。

\A.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
<?php

namespace App;

class Apple
{
    public function getInfo()
    {
        echo '这是A文件中的Apple<br>';
    }
}

\B.php

Select Code
1
2
3
4
5
6
7
8
9
<?php

class Apple
{
    public function getInfo()
    {
        echo '这是B文件中的Apple<br>';
    }
}

\C.php

Select Code
1
2
3
4
5
6
7
8
9
10
11
<?php

namespace C;

class Apple
{
    public function getInfo()
    {
        echo '这是C文件中的Apple<br>';
    }
}

三、Traits的使用
提高代码的可复用性

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
<?php

trait OwnerTrait
{
    public function Owner()
    {
        echo "Article Owner";
    }
}

class Article
{
    use OwnerTrait;
}

class Comment
{
    public function Owner()
    {
        echo "Article Owner";
    }
}

(new Article())->Owner();
(new Comment())->Owner();