Da'sBlog


  • 首页

  • 分类

  • 归档

  • compass中文手册

  • 搜索
close
Da'sBlog

js-arrow

发表于 2018-03-06

var a = {
b: function() {
console.log(this)
},
c: () => console.log(this),
d() {
console.log(this)
},
e() {
return new Promise(
() => console.log(this)
)
},
f: function() {
return new Promise(
() => console.log(this)
)
},
g: function() {
return new Promise(
() => console.log(this.axios)
)
},

        i() {
            return () => (
                console.log(this.axios)

            )

        },
        h() {
            return () => ({
                i() {
                    console.log(this.axios)
                }
            })
        },
        o() {
            return () => {
                return () => {
                    console.log(this.axios)
                }
            }
        },
        p() {
            return () => {
                return () => ({
                    i() {
                        console.log(this.axios)
                    }
                })
            }
        },
        u: () => ({
            i() {
                console.log(this.axios)
            }
        }),
        y: () => ({
            i: () => (console.log(this))
        }),
    }
    // es6 浏览器隐式调用 strict mode。u内部所在作用于是window但箭头函数内的i的调用caller和argument受到限制,所以返回underfined
a.axios = 1;
axios = "";
阅读全文 »
Da'sBlog

apache卸载添加模块

发表于 2018-01-24

1.安装apache2
安装命令:sudo apt-get install apache2
启动/停止/重启apache2: service apache2 start/stop/restart

  1. 卸载apache2
    之前卸载重新安装后找不到apache2.conf配置文件,测试使用一下方式卸载后可用。
    (1) $ sudo apt-get –purge remove apache2
    $ sudo apt-get --purge remove apache2.2-common
    $ sudo apt-get autoremove
    

(2) (关键一步)找到没有删除掉的配置文件,一并删除
$ sudo find /etc -name “apache“ -exec rm -rf {} \;
$ sudo rm -rf /var/www

然而,在安装成功准备运行的时候,却出现了问题如下所示:
[Fri Oct 14 20:27:03.977120 2016] [core:warn] [pid 4445] AH00111: Config variable ${APACHE_LOCK_DIR} is not defined

[Fri Oct 14 20:27:03.977236 2016] [core:warn] [pid 4445] AH00111: Config variable ${APACHE_PID_FILE} is not defined

[Fri Oct 14 20:27:03.977267 2016] [core:warn] [pid 4445] AH00111: Config variable ${APACHE_RUN_USER} is not defined

[Fri Oct 14 20:27:03.977273 2016] [core:warn] [pid 4445] AH00111: Config variable ${APACHE_RUN_GROUP} is not defined

[Fri Oct 14 20:27:03.977283 2016] [core:warn] [pid 4445] AH00111: Config variable ${APACHE_LOG_DIR} is not defined

[Fri Oct 14 20:27:03.979139 2016] [core:warn] [pid 4445:tid 140654039287680] AH00111: Config variable ${APACHE_LOG_DIR} is not defined

[Fri Oct 14 20:27:03.981408 2016] [core:warn] [pid 4445:tid 140654039287680] AH00111: Config variable ${APACHE_LOG_DIR} is not defined

[Fri Oct 14 20:27:03.981422 2016] [core:warn] [pid 4445:tid 140654039287680] AH00111: Config variable ${APACHE_LOG_DIR} is not defined

AH00526: Syntax error on line 74 of /etc/apache2/apache2.conf:

如果不能正常启动。
这个多半是以前卸载的时候没有卸载干净 重新完整卸载一遍就好。

在apache1时候静态php模块直接编译进核心mod模块
在apache2不再内置。
就意味着不用 Apache 内置的 mod_php,也就是要在 Apache 之外处理 php 程序的解释运行问题。看起来是多引入了一个额外的程序 PHP-FPM,既占 CPU 又占内存。但是这样一来,因为 Apache 可以专心处理除 php 之外的静态网页及元素,反而 httpd 进程本身占用的 CPU 和内存可以显著降低,从而从整体上降低资源消耗。

安装5.6 7.1的php后
默认源自动添加了apache2的模块。如果没有需要手动安装添加
例如
sudo apt-get install libapache2-mod-php5.6

apache2通过模块连接到php。

从PHP 5.6 => PHP 7.1

默认PHP 5.6在您的系统上设置,您需要切换到PHP 7.1。

Apache: –

$ sudo a2dismod php5.6
a2dismod关闭5.6模块
$ sudo a2enmod php7.1
a2enmod开启7.1的模块

$ sudo service apache2 restart
命令行:-

$ update-alternatives –set php /usr/bin/php7.1
同时用update-alternatives修改 为7.1的软连接。

从PHP 7.1 => PHP 5.6

默认PHP 7.1在您的系统上设置,您需要切换到PHP 5.6。

Apache: –

$ sudo a2dismod php7.1
$ sudo a2enmod php5.6
$ sudo service apache2 restart
命令行:-

$ sudo update-alternatives –set php /usr/bin/php5.6

如果在a2enmodphp5.6出现 “Module php5.6 does not exist”
多半是apache内 没有加载上模块
我们创建两个文件就好了

文件1
复制下面内容创建 php5.6.conf 在 /etc/apache2/mods-available/ :


AddType application/x-httpd-php .php .phtml .php5
AddType application/x-httpd-php-source .phps

文件2

复制下面内容创建php.load 同样在 /etc/apache2/mods-available/

LoadModule php5_module /usr/lib/apache2/modules/libphp5.so

保存好后退出输入
a2enmod php && /etc/init.d/apache2 restart

阅读全文 »
Da'sBlog

rpx教程

发表于 2018-01-16 | 分类于 微信小程序

rpx默认把屏幕实际宽度分成750份。

那么在750物理宽度的iphone6上,实际宽度是750,1rpx =375/750= 0.5px

那么在640物理宽度的iphone5,实际宽度是640,物理宽度是320, 1rpx= 320/750 = 0.426666666666666px

所以如果你的设计稿假如是640的 就要用iphone5的像素计算,就要先转成实际像素, 然后把他750等分。

工作中我们的数值都是像素

所以要把设计稿的像素转成rpx

也就是说 实际像素320

页面有750份。

那么我们得到1px = 750/320像素 = 2.34375rpx

但我们的设计稿是640

那么我们的换算应该是1px = 750/640像素 = 2.34375rpx/2 = 1.171875rpx;

即在640下,60px的方块。这么计算

60*1.171875rpx; = 70.3125rpx

看似复杂换个角度想,无论任何屏幕都是750份,

那么你也可以估算出1等分大概是多少,计算出实际大小

这个与rem是类似的,

假如rem在375下,分成750份。 那么1rem = 1rpx =375/750= 0.5px
那么750下也是750份。
640下也是750份。

至于原理,
要始终明白一点
有个比值是不变的就是 分割数750,即基数。
即
我把面包分成5份,那么无论面包变大变小,那个分成5份占总体积的大小是不变。

而在这里,我们的的面包是320px大小,我分成了750份,1份大小即1rpx = 320/750。 那么当面包变成了640px,里面还是750份 一份大小 1rpx = 640/750。

好了
为了方便计算。
因为实际有些人喜欢多吃面包,所以不是每人都给一份,因为我有时候给某人多一点。而且我不可能都切完。我就用尺子量下我的面包宽度。要分一个100px的面包
那么640的面包 1px的面包大概是750/640 = 1.17rpx 如果我要给某人100px的面包,那么值就是1.17rpx *100 - 117rpx 也就是只需要给117份。

那么无论变大变小 无都不用管 他都是117份

但是如果是厘米的话我就估算不出来了。因为大小变了。

阅读全文 »
Da'sBlog

learn-thinkcmf

发表于 2017-12-20
  1. 在写样式的时候不要在外部设置高度

  2. lock上传后 一定要加上

  1. 获取请求的category的值,如果没有设置为0,并且转成整形。$categoryId = $this->request->param(‘category’, 0, ‘intval’);
  1. 表达式
    $join = [
        ['__USER__ u', 'a.user_id = u.id']
    ];
    
    user表设置名称为u,判断条件是否相等
    阅读全文 »
Da'sBlog

git-pull错误refusing to merge unrelated histories

发表于 2017-11-06 | 分类于 git

在服务器创建好后 应该先拉到本地 再推。

提前推是会报错的。

如果本地已经创建项目 需要合并下。

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
H:\zcll>git remote add zcll https://git.coding.net/da_/zcll.git
H:\zcll>git push -u zcll master
To https://git.coding.net/da_/zcll.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://git.coding.net/da_/zcll.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
H:\zcll>git pull zcll master
From https://git.coding.net/da_/zcll
* branch master -> FETCH_HEAD
fatal: refusing to merge unrelated histories
H:\zcll>git pull zcll master --allow-unrelated-histories
From https://git.coding.net/da_/zcll
* branch master -> FETCH_HEAD
Merge made by the 'recursive' strategy.
README.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 README.md
H:\zcll>git push -u zcll master
Counting objects: 148, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (140/140), done.
Writing objects: 100% (148/148), 3.35 MiB | 673.00 KiB/s, done.
Total 148 (delta 19), reused 0 (delta 0)
remote: Resolving deltas: 100% (19/19), done.
To https://git.coding.net/da_/zcll.git
857afd6..252f11c master -> master
Branch master set up to track remote branch master from zcll.
阅读全文 »
Da'sBlog

js-Class.js学习 源码分析

发表于 2017-10-26 | 分类于 javascript

学习

以下学习需要面向对象基础知识和prototype继承了解

什么是继承

ClassJs提供了完整的继承机制。

为什么要继承

因为父类的功能是不完善的,随着项目的迭代,性能功能上明显不足。

这个时候多个项目栏目可能依赖这个父类,导致你不能修改。

即使修改也会导致项目错乱,一改全部都改。

所以这个时候为了能达到效率和灵活,我们需要用面向对象继承机制。

父类是不完善的,子类通过继承父类的所有,并对不足的予以修订。

所以继承的任务有两个

1. 子类获取父类所有功能    

2. 子类对父类不足的进行修改

继承还有两个特性即单根性和传递性

1. 单根性 (子类只有一个父类)
2. 传递性    (即子类可以作为父类不断传递下去)

教程

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
//首先我们通过Class.extend创造基类person,
var Person = Class.extend({
init: function(isDancing){
this.dancing = isDancing;
},
dance: function(){
return this.dancing;
}
});
var Ninja = Person.extend({
init: function(){
this._super( false );
},
dance: function(){
// Call the inherited version of dance()
return this._super();
},
swingSword: function(){
return true;
}
});
var p = new Person(true);
p.dance(); // => true
var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true

首先用Class.extend创建基类Person并传入prototype

1
2
3
4
5
6
7
8
9
{
//prototype
init: function(isDancing){
this.dancing = isDancing;
},
dance: function(){
return this.dancing;
}
}

因为js没有纯正的面向对象机制,所谓的继承是由prototype来实现。

当执行完Class.extend并传入prototype会返回一个构造函数给Person。这个函数的构造体是我们的Class的构造函数,prototype是我们传入的值。所以返回的构造函数,打印出来会是这样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
console.dir(Person)
function Class()
arguments:null
caller:null
extend:function(prop)
inject:function(prop)
length:0
name:"Class"
prototype:Class
constructor:function Class()
dance:function()
init:function(isDancing)
__proto__:Object
__proto__:function()
<function scope>

当我们运行

1
2
var p = new Person(true);
p.dance(); // => true

把true传入Person那么初始化函数init自动执行,dance所指向的就变成true。
这个时候用dance打印当前域的dance就变成了true

这个时候我们运行

1
2
3
4
5
6
7
8
9
10
11
12
var Ninja = Person.extend({
init: function(){
this._super( false );
},
dance: function(){
// Call the inherited version of dance()
return this._super();
},
swingSword: function(){
return true;
}
});

用于继承Person这个类

这里的init里面的this._super(false)指向的是父类也就是Person内原型里面的init。
子类init和父类init是重名 ,这个时候子类会把对父类传递值得修改,传给父级。即等于
this._super( false ) == (this.dancing = false; )

dance同理

swingSword因为父类没有,所以它来源于自己,直接添加到prototype。

所以运行后的Ninja的构造函数是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
console.dir(Person)
function Class()
arguments:null
caller:null
extend:function(prop)
inject:function(prop)
length:0
name:"Class"
prototype:Class
constructor:function Class()
dance:function()
init:function(isDancing)
swingSword:function()
__proto__:Class
__proto__function:()
<function scope>

这个时候运行

1
2
3
var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true

发现我们的dance变成false 是因为我们修改了原来的类,同时添加了swingSword扩充了父类。

从而实现了继承的特性。

代码分析

ClassJs用于对象的继承,源代码比较小巧90行左右,非常精简。

  1. fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
    test是为了判断字符串是否匹配。所以大部分浏览器对函数内部的数据如果是函数会执行toString保证运行。
    例如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var a = {}
    undefined
    /a/.test(a)
    false
    /a/.test('a')
    true
    /a/.test(function(){a})
    true

    fnTest这里的目的就是为了判断当前浏览器是否支持函数toString,如果支持返回/\b_super\b/,否则返回 /.*/

  2. 首先都在(function(){})()这个自执行里面,防止对全局污染。

  3. 然后用 this.Class = function() {};创建构造函数Class.这里的this.Class的this是指向的window

  4. 然后是在Class类上添加extend方法,该方法用于实现继承,传入一个prop对象,返回Class的原型+prop对象。下面对Class.extend里面代码分析

    1. var _super = this.prototype; 这里 _super就是Class的原型。用于保存原型。
    2. 1
      2
      3
      initializing = true;
      var prototype = new this();
      initializing = false;

      这三段用于初始化,把实例化的Class赋值给prototype

  5. 这是一段for循环用于把prop的属性复制给prototype

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    for (var name in prop) {
    // Check if we're overwriting an existing function
    prototype[name] = typeof prop[name] == "function" &&
    typeof _super[name] == "function" && fnTest.test(prop[name]) ?
    (function(name, fn) {
    return function() {
    var tmp = this._super;
    // Add a new ._super() method that is the same method
    // but on the super-class
    this._super = _super[name];
    // The method only need to be bound temporarily, so we
    // remove it when we're done executing
    var ret = fn.apply(this, arguments);
    this._super = tmp;
    return ret;
    };
    })(name, prop[name]) :
    prop[name];
    }

我们分析下这一段
prototype[name] = typeof prop[name] == “function” && typeof _super[name] == “function” && fnTest.test(prop[name]) ? (function(name, fn){})(name, prop[name]):prop[name]

1. typeof prop[name] == "function" && typeof _super[name] == "function" 用于构造函数中的相应name是不是函数,传递过来的prop中的name是不是也是函数。
2. fnTest.test(prop[name]) 同样也是用于判断传来的prop是否有_super。
3. 如果上面两个都是true那么就把
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
var Class = {}
var result = {}
Class.extend =function(prop){
var _super = this.prototype;
for(var name in prop){
result[name] = /\b_super\b/.test(prop[name])?(function(name, fn) {
return function() {
var tmp = this._super; //把super存入tmp缓存防止覆盖
this._super = _super[name]; //把super方法复制给super,this._super已经变成父类name函数
//这里我们要运行fn即prop[name],然后 return this._super指向当前。然后把return this._super();返回值赋值给result即ret
// dance: function(){
//
// return this._super();
// },
// 例如父级是
// init: function(isDancing){
// this.dancing = isDancing;
// },
// 子是
// init: function(){
// this._super( false );
// },
// 子实例化的时候会传入false,然后返回ret。。。。简单点就是如果是同名的那就继承。
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]):prop[name] //如果函数体里面有super那么就继承来至父级别。否则直接进行赋值
}
return
}
var Person = Class.extend({
init: function(isDancing){
this.dancing = isDancing;
},
dance: function(){
return this.dancing;
}
});
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
83
84
85
(function() {
var fnTest = /xyz/.test(function() { xyz; }) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function() {};
// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn) {
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if (!initializing && this.init)
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
// EXTENSION BY Draw2D.org to inject methods into an existing class to provide plugins or
// bugfixes for further releases
//
Class.inject = function(prop) {
var proto = this.prototype;
var parent = {};
for (var name in prop) {
if (typeof(prop[name]) == "function" && typeof(proto[name]) == "function" && fnTest.test(prop[name])) {
parent[name] = proto[name];
proto[name] = (function(name, fn) {
return function() {
var tmp = this.parent;
this.parent = parent[name];
var ret = fn.apply(this, arguments);
this.parent = tmp;
return ret;
};
})(name, prop[name]);
} else {
proto[name] = prop[name];
}
}
};
return Class;
};
})();
阅读全文 »
Da'sBlog

laravel-migration

发表于 2017-09-25

php artisan make:migration wechat_admin –create=admin

php artisan make:migration create_userNAME 后面跟行为 和表名

阅读全文 »
Da'sBlog

子网掩码怎么理解?

发表于 2017-08-29 | 分类于 网络

掩码的作用是划分区域

子网掩码使用与IP相同的编址格式,子网掩码为1的部分对应于IP地址的网络与子网部分,子网掩码为0的部分对应于IP地址的主机部分。将子网掩码和IP地址作”与”操作后,IP地址的主机部分将被丢弃,剩余的是网络地址和子网地址。例如,一个IP分组的目的IP地址为:10.2.2.1,若子网掩码为:255.255.255.0,与之作”与”运算得:10.2.2.0,则网络设备认为该IP地址的网络号与子网号为:10.2.2.0。

内网中192.168.1.199的前三组是网络号,后一组是主机号,子网掩码就是255.255.255.0

如果IP同样是192.168.1.199 那么子网掩码可以设成255.255.255.192吗,怎么理解

如果在同一个局域网出现这两种掩码可以相互通讯吗

阅读全文 »
Da'sBlog

内网IP与外网的关系?

发表于 2017-08-29 | 分类于 网络

https://www.zhihu.com/question/43517806

本人学习之中碰到余下疑惑,百度、必应都没找到很明确的答案,希望有懂得的人解答一二,谢谢。
1.看别人说内网IP可以随意分配,比如你的外网是个C类的,内网IP可以设A类的。 要是能这样一个C类公网的内网不就能容纳很多主机了,又有人说一个C类网络只能容纳254台主机。
2.现在划分子网时借的主机位能不能全0或全1。 好像现在不用在乎这,可老版的书又不让用,求解答。
3.申请的公网IP是一个具体的IP地址用在与公网连接的路由器上还是一个网段。

我猜测申请的公网是一个具体的IP,用在与公网连接的路由器上,内网随意设置(个别IP除外),然后经过路由器时由路由器转换,不知道猜的对不对。

诚心求解。

谢谢各位的回答,可能是匿名的关系消息也没个提示,看了你们的解答对这几个问题目前没有疑惑了,十分感谢,祝你们万事如意。
还是得多看书,后来发现书上都有。。。

阅读全文 »
Da'sBlog

css-oocss-samcss-sem

发表于 2017-08-21 | 分类于 css

OOCSS

OOCSS 翻译过来意思是 面向对象的css

很多没有接触过面向对象,或者没有理解的朋友可能觉得oocss这个是框架。

其实面向对象分为 面向对象分析 面向对象编程 面向对象语言 面型对象思想 面向对象设计

看着挺复杂,就我的教学经验。初学只需要从思想和代码上认识就可以。

思想上,面向对象,是人认识客观事物的方式。是思想,就是思维方式。 和敲代码没有任何关系。

首先我们要区分类和对象。

我们把马这一种类叫 类。

把小红正在骑的马(客观存在,不以人的意识为转移) 这个叫实例,也就是我们的对象。

我们把大千世界真实存在的马,归为一类 给他们起了名字 叫马。 这是一种抽象概括的过程。

我们从马中找出创建我们的真实存在的马。这叫实例化。

简单点,我是真实存在的,但”人”这个名词是概念。所以我是对象,”人”是类。 我来源与类。

而我们的面向对象,就是面向的一个一个客观存在的实物。你看到的想到的是真实存在的(包括思想).比如还是我,我都能在这打字,是不是真实存在的。包括思想,你在想媳妇,这个想的动作,也是真实存在的。也是对象。

简单点,凡是能意思到,能感受到的都是对象。但人这个名词是我们抽象出来的,我们无从感受到它,它是一个类。

好吧,估计好多小伙伴脑细胞死一半了。我们再简单点。从自身的角度看世界。冥想一下。

我走在原始森林,看到了好多树,这些树都是真实存在的,这是你能感受到的。

回去你给小伙伴说,我看到了好多树, 你们这时候沟通时候,对方是没法意识到你看到的树,对它而言,这个树就是一个概念。也就是我们的类。

然后你继续给小伙伴说,其中在最中央有个撑天大树,很高很大。这个说的也是类。只是类的范围缩小了。

当小伙伴去过去,亲眼看到的时候,它客观存在,这个时候在他意识中就成了对象。

即必须是客观存在,能被意识到。如果意识不到,在人的角度,经过抽象就是一个类。

凡是抽象的都是类。凡是意识到的都是对象。

那梵高的话那么抽象它是类么?

首先来说,梵高抽象的是自己的感情,这里的抽象是他自己真实的感情,抽象的过程是对象,但他画里面的感情是被抽象过的,是一种概括的类。

好吧,现在脑细胞都死掉了吧。哈哈哈哈。其实我写的都是比喻,比较简单了。真的哦。不信你们可以看些教材。然后脑细胞会成负的。。。。

所以在这我建议大家,有个认识就可以,不影响编程。在随后漫长的人生中,细细体味。思想无法传递和跨越,不需要苛求对错。

下面我们说说编程吧

传统的道家学说吸收了阴阳五行。

阴阳化万物,天为阳,地为阴。一动,一静。衍生万物。

这和我们编程有啥关系呢。。

其实面相对象只是阴阳学说的一种表象。我们从头说起吧。

在编程之初,代码是比较简单和可以控制的。就是按顺序一两个人写出来。

但是随着硬件性能的成倍提高,用户对程序的要求也不断提高,对时间,性能,稳定也更苛刻。

传统面向过程(这个是目前大部分小白的写法,就是想到啥写啥,按顺序把需求完成)

无法预估项目,不适合多人开发,时间无法把控。而且维护困难,因为你是一个人从头到尾写的。

上面错了,下面业务可能全乱了。牵一发而动全身。哈哈哈哈哈

想让别人帮忙吧。但你业务都是从上到下写的。只好和小伙伴协商,分开写,导致代码臃肿,突然你写到一半。发现少约定个参数,然后你小伙伴也写了一半。然后就扯淡了。

所以我们要用面向对象编程来解决。

面向对象把业务拆分开。面对的不再是过程,而是对象。

而对象又包含,静态的属性和 动态的方法。

通过 动 和静 演化万众功能。

通过拆分动静, 静的重复利用,动的相同部分也可以利用,

oocss 准确的说 是一种编辑css的思想。又因为没有语法限制,所以片面点讲就是一种书写规范。

很高兴 你能闯过刀山火海来看到这里
我们继续

其实oocss是一种思想,所以每个人理解都是由一种偏差,所以为了学习,我们还是要有个规范
引用wiki的话

OOCSS的重点是将页面元素作为对象,给所有对象设置类名,将类作为样式表中的单个实体处理,并从它中获取。

在这篇文章中,我将通过介绍面向对象的css的概念以及如何帮助提高web页面的性能和可维护性来处理这一经常被忽略的领域。

与任何基于对象的编码方法一样,OOCSS的目的是鼓励代码重用,最终更快捷、更高效的样式表更容易添加和维护。
Object-oriented CSS (OOCSS) 是 CSS的扩展和升级

引用OOCSS之父Nicole Sullivan话来说, 面向对象的CSS有两个原则:

独立的结构和样式

视觉性的特征具有可重复性,比如红色方块连衣裙,那么红色方块这种装饰性的东西,是不是也可以用到红色方块墙体和衣服呢?

而结构往往具有独立和不可重复性。

独立的容器和内容

所谓容器 就是 最外层的盒子 容器本身不包含任何样式 他的样式由内容显示

这样内容的样式具有可以

OOCSS的两大原则

分离结构与皮肤

这意味着将重复的视觉功能(如背景和边框样式)定义为单独的“皮肤”,您可以与不同的对象进行混合和匹配,以实现大量的视觉多样性,但没有太多代码。请参阅模块对象及其皮肤。 分离结构和皮肤也意味着使用类来命名对象及其组件,而不是仅仅依赖于html的语义。例如,媒体对象被命名为类=“媒体”,其组件以类=“img”(用于图像/视频组件)和类=“bd”(为body/text组件)命名。 通过引用样式表中的这些类(表示,而不是直接样式化元素),您的html可以灵活。例如,如果在未来几年中,一个新的媒体元素将会被起飞(例如<;svg>;),它可以集成到html中,而不必触摸css。 分离容器和内容 从本质上讲,这意味着“很少使用位置依赖样式”。无论你把物体放在哪里,物体都应该是一样的。因此,不要使用特定的
进行样式化。myObject{.},创建并应用一个类,该类描述了有关
的问题,如
。 这给了您保证:(1)所有的unclassed
s都会看起来相同;(2)所有具有类别类(称为mixin)的元素都会看起来相同; 3)当实际需要时,不需要为该例创建一个重写样式。myObject看起来像正常的

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
#button {
width: 200px;
height: 50px;
padding: 10px;
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
#box {
width: 400px;
overflow: hidden;
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
#widget {
width: 500px;
min-height: 200px;
overflow: auto;
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

上面的三个元素都有各自独有的样式,并且它们被应用于非可重用的ID选择器中,以定义样式。但他们也有很多风格的共同点。常见的样式可能存在于品牌目的或设计的一致性上。

有了一点规划和思考,我们就可以抽象出常见的样式,这样css就会变成这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.button {
width: 200px;
height: 50px;
}
.box {
width: 400px;
overflow: hidden;
}
.widget {
width: 500px;
min-height: 200px;
overflow: auto;
}
.skin {
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

现在所有的元素都是使用类,通常的样式被组合成一个可重用的“皮肤”,而没有必要重复。我们只需要将“皮肤”类应用到所有元素中,结果将与第一个示例所生成的结果相同,除了代码少和用于进一步重用的possiblity之外。
SEPARATION OF CONTAINERS AND CONTENT LINK
在OOCSS GitHub页面上描述的第二个原则是将容器与其内容分离。为了说明为什么这是重要的,请采取以下css:

1
2
3
4
5
6
7
#sidebar h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: .8em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

这些样式将应用于任何#sidebar h3标题。但是,如果我们想将完全相同的样式应用到在footer h3标题,除了不同字体大小和修改后的文本阴影之外,还会怎样呢?

1
2
3
4
5
6
7
8
9
10
11
12
#sidebar h3, #footer h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 2em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
#footer h3 {
font-size: 1.5em;
text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

或者我们可能会有更糟的事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#sidebar h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 2em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
/* other styles here.... */
#footer h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 1.5em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

现在,我们不必要地复制样式,可能不会意识到它(或者根本不关心)。

通过OOCSS,我们被鼓励对不同元素中常见的内容进行更多的思考,然后将这些常见特性分离到模块或对象中,这些模块或对象可以在任何地方重用。

在上述示例中使用子代选择器声明的样式是不可重用的,因为它们依赖于特定的容器(在本例中是#sidebar或#footer)。 当我们使用OOCSS的基于类的模块构建时,我们确保我们的样式不依赖于任何包含元素。这意味着,无论结构上下文如何,它们都可以重用在文档的任何地方。

一个真实世界的例子

为了进一步说明如何使用OOCSS,我将使用类似于我在网站最近的重新设计中所做的事情。在对站点上的内部标头元素进行编码后,我意识到页眉内的基本结构样式可以在页面上的其他元素上重用。 因此,这里有一些我开始设计标题时所拥有的线条:

因此,这里有一些我开始设计标题时所拥有的线条:

.header-inside {
width: 980px;
height: 260px;
padding: 20px;
margin: 0 auto;
position: relative;
overflow: hidden;
}

这里列出的几种样式是唯一的。.header-inside元素。但其余部分可以形成一个可以重用的模块。因此,我可以将结构样式抽象成自己的可重用类。这是结

.globalwidth {
width: 980px;
margin: 0 auto;
position: relative;
padding-left: 20px;
padding-right: 20px;
overflow: hidden;
}

.header-inside {
padding-top: 20px;
padding-bottom: 20px;
height: 260px;
}

A fixed width
Centering using margin: auto
Relative positioning to create a positioning context for child elements
Left and right padding of 20px
Overflow set to “hidden” for clearfixing

固定宽度 用边缘定位:自动 相对定位为子元素创建定位上下文 左的左、右填充 溢出设置为“隐藏”为clearfixing。
现在,我们可以在任何需要相同特性的元素上使用这些样式,只需将该类添加到所需的元素中-而无需编写单独的CSS行。 对于我的站点,我在主内容元素和内页脚元素上重用了这些结构样式。根据设计,这些样式也可以适用于可能出现在页眉和内容之间的水平导航元素,也可以适用于任何具有固定宽度的其他元素,并且需要居中在页面上。 将“globalwidth”样式添加到这些元素后,标记将看起来类似如下:








有些人可能会觉得这种样式抽象会使html变得更加复杂,并且违背了将标记与呈现分离的原则。 但是,抛开任何关于如何影响标记的辩论,没有人可以质疑,这种抽象现在使跟踪和修改用于构造这三个元素的常用样式变得更加容易

媒体对象
OOCSS运动的先驱之一是nicole sullivan。她创建了一个名为媒体对象的可重用模块,正如她所解释的那样,它可以保存数百行代码。

媒体对象是OOCSS强大的一个很好的例子,因为它可以包含任何大小的媒体元素,它的右边有内容。虽然许多适用于其内部内容的样式-甚至媒体元素本身的大小-都可能会发生变化,但是媒体对象本身也有共同的基础样式,以避免不必要的重复

  • Separate structure and skin(分离结构和主题)减少对 HTML 结构的依赖
  • Separate Container and content(分离容器和内容)增加样式的复用性
    OOCSS好处

我已经提到了OOCSS的一些好处。
在这里,我将扩大这些。

更快的网站链接

OOCSS的性能效益应该是相当清楚的

。如果您在css中重复的样式较少,那么这将导致文件大小更小,从而更快地下载这些资源。

的确,标记将更加混乱,从而创建更大的html文件。

但是在许多情况下,标记性能的损失量将大大超过样式表性能中的增益量。

另一个记住的概念是,OOCSS wiki指的是性能赠品。这指的是,每当您在css中重用某些东西时,基本上都会创建一个新的样式元素,这些元素都是CSS代码的零行。对于大型的高流量项目,这些“免费”可能是一个关键的业绩增益。

可维护的STYLESHEETS链接 使用OOCSS,而不是一个不断增长的样式表,充满了特定的战争,您将有一套易于维护的模块,在这些模块中,自然级联扮演了重要角色。 当对现有站点进行添加时,您不会在样式表的底部添加新样式,而不必考虑以前所出现的内容。相反,您将重用现有样式,并根据现有规则集扩展样式。 使用这种forethought,在编写很少的css时创建整个页面是可能的。任何现有的css模块都可以作为所有新页面的基础,并且任何新的css都是最小的。在某些情况下,您甚至可以创建一个新的完全样式的页面,而不编码一个单行的css。 这些可维护性的好处也扩展到样式表的健壮性。

由于样式是模块化的,在新开发人员开始使用样式表时,基于OOCSS构建的页面可能会更少崩溃。 值得注意的要点 OOCSS在社区里引起了大量的讨论,引起了一些争议。在这里,我会试着消除几个常见的误解。 您仍然可以使用ids链接。 如果您决定以一种OOCSS方式工作,那么您的样式将主要基于css类,而您不会使用id选择器来设计元素。 因此,许多人错误地声称,OOCSS鼓励完全放弃使用IDs。但这并不是真的。 避免IDs的规则更具体地说,在选择器中不使用IDs。因此,使用OOCSS原则(从而避免使用id选择器的样式)是完全可以接受的,同时使用IDs中的使用用于javascript钩子和片段标识符。 当然,您可能有一个状态,您已经将一个id应用到一个元素,您知道该元素是页面中唯一的。因此,您可以通过避免向该元素添加类来保存几个字节,并使用选择器选择器来创建它。但即使在这种情况下,依赖于类也更安全,以确保您在将来不会遇到特定的问题。 处理小项目链接 对于较小的站点和应用程序,您可以肯定的是,OOCSS将是多余的。所以,不要把这篇文章作为OOCSS的宣传,在任何情况下都会有所不同,这取决于项目的情况。 尽管如此,我认为这是一个好主意,至少在你的项目中开始考虑OOCSS。一旦你得到了它的窍门,我相信你会发现在更大的项目上工作变得更容易,而这些项目的好处会更显著和更相关。 执行链接的一些指导方针 开始和OOCSS一起工作可能需要时间。我还在研究它,所以我不声称在这方面有所有的答案和经验。 但是这里有一些你可能想要开始做的事情,以帮助你进入一种长期的思维方式: 避免派生选择器(即不使用)。侧栏h3 避免IDs作为样式挂钩 避免将类附加到样式表中的元素(即不做div.header或h1.title)。 除了在一些罕见的情况下,避免使用!重要 使用林特来检查你的css(并知道它有选择和方法去处理它的疯狂) 使用css网格 显然有些时候,这些规则会被打破,但总的来说,这些规则是开发的好习惯,

并且会导致样式表变得更小,更易于维护。 跟随nicole sullivan的工作链接 如果你想继续学习OOCSS,这个行业中最重要的人是妮可沙利文。 除了在她的博客上定期发布张贴文章外,妮可还与随行的幻灯片做了一系列的介绍。下面是一些您可能想要检查的内容: 面向对象的css(Slideshow) 高性能网站:nicole sullivan(视频) 我们最好的做法是杀了我们(Slideshow) css膨胀(Slideshow) 结论链路 许多人害怕OOCSS的意识形态,因为它似乎违背了我们所学到的许多所谓的“最佳实践”。但是一旦了解使用OOCSS的长期好处,我相信很多开发人员都会成为转换者。 总的来说,我认为OOCSS在css开发方面有着光明的未来,这是一个概念,所有开发人员都应该开始融入他们的项目-至少在某种程度上-帮助创建更快的网页,更有效,更容易维护。

阅读全文 »
12…7
Sun Hao

Sun Hao

Whoever wants to be first must be slave of all.

68 日志
26 分类
100 标签
RSS
Creative Commons
© 2018 Sun Hao
Powered by Hexo
Theme - NexT.Mist
本站访客数人次 本站总访问量次