Javascript中的screen对象

Javascript中的location对象

  • window.location === document.location // true
  • location的属性列表
  • 修改location的属性会导致页面刷新并产生新的历史记录
  • window.location = “URL” 和 location.href=”URL”效果一样,都会调用location.assign(URL)
  • location.replace(URL)不会产生新的历史记录,而且会禁用后退
  • location.reload(true): 重新加载页面,参数可以选择是否从服务器加载(而不是从缓存加载)

Javascript中的window对象

window对象的两个作用:

  • 表示浏览器的一个实例
  • ECMAscript中的Global对象
    直接定义Global变量与在window上定义Global变量的区别是:直接定义的Global变量的[[configurable]]特性为false,也就是说,它不能用delete删除

窗口关系及框架

  • 如果html中包含框架(frame),那么每个框架都有自己的window对象,它们从上到下,从左到右,依次存放于window.frames数组中。可以通过window.frames[index]或者window.frames[frame_name]来获取frame的window对象
  • window.name为frame的name
  • top对象表示最外层html的window对象
  • parent对象表示上层frame的window对象
  • self表示frame自身的window对象

窗口位置

  • window.screenLeft window.screenTop 或者firefox中的window.screenX window.screenY表示窗口左上角的位置
     
     
        var left = (typeof window.screenLeft == "number") ? window.screenLeft: window.screenX;
        var top = (typeof window.screenTop == "number") ? window.screenTop: window.screenY;
       
  • window.outerHight window.outerWidth 表示窗口的高和宽
  • window.innerHight window.innerWidth 表示页面视图的高和宽

打开新窗口

  • window.open(URL, target, args, is_replace)
    URL: 新窗口打开的网址
    target: 目标frame的名字,或者_self, _parent,_top,_blank
    args: is_replace: 是否替代当前窗口
  • window.close() : 关闭一个窗口
  • window.closed: 布尔值,window是否已经关闭
  • window.opener: 表示打开本窗口的窗口window对象

超时调用与间歇调用

  • var id = setTimeout(function, ms)  ; clearTimeout(id);
  • var id = setInterval(function, ms) ; clearInterval(id);

系统对话框

  • alert(‘string’)
  • var boolean = confirm(“string”);
  • var result_string = prompt(“string”, “default_answer”);

Javascript中的函数表达式

  • 函数声明 有提升 而函数表达式没有,因此不应该通过if…else来声明函数
     
     
        if (condition) {
            function sayHi() {}
        } else {
            function sayHi() {}
        }
       
  • 在递归函数中使用arguments.callee可以避免因函数名改变产生的错误。
     
     
        function factorial(num) {
            if (num 
                return 1;
            } else {
                return num * arguments.callee(num - 1);
            }
        }
       
  • 闭包是指函数中定义的函数,闭包的作用域链中包含父函数的执行环境(变量对象),所以即使父函数退出,如果闭包仍然被引用,那么父函数的变量对象就一直存在于内存中。所以,过度的使用闭包会导致内存占用过多
  • 闭包的另外一个副作用是闭包只能取得父函数中变量的最后一个值,例如:
     
     
        function createFunctions() {
            var result = new Array();
            for(var i = 0; i < 10; i++) {
                result[i] = function() {
                    return i;
                }
            }
            return result;
        }
       

    调用result中的每个函数都会返回10

  • 闭包如果是匿名函数,则该函数中的this指向全局对象
  • 可以用定义一个立即执行函数来模仿块级作用域:
     
     
            (function(){
            //块级作用域                                   
            })();                                        
       

Javascript中的对象

属性的类型

1.1 数据类属性

数据类属性的属性——特性为:

  • [[Configurable]]: 默认为true。表示能否通过delete删除属性,能否修改属性的特性。
  • [[Enumerable]]: 默认为true。表示在用for-in迭代对象时,能否迭代出该属性。
  • [[Writable]]: 默认为true。表示能否修改属性的值。
  • [[Value]]: 默认为undefined。保存属性的值。

1.2 访问器类属性

访问器类属性的特性为:

  • [[Configurable]]: 默认为true。表示能否通过delete删除属性,能否修改属性的特性。
  • [[Enumerable]]: 默认为true。表示在用for-in迭代对象时,能否迭代出该属性。
  • [[Get]]: 默认为undefined。读取属性时调用的函数。
  • [[Set]]: 默认为undefined。写入属性时调用的函数。

使用访问器类型的属性的常用方法是写入该属性时往往会导致其他属性也跟着变化。

 

1.3 对特性的操作方法:

Object.defineProperty(Object, propertyName, {attributes}): 设置属性的特性。
Object.defineProperties(Object, {propertyName: {attributes},}): 设置多个属性的特性。
Object.getOwnPropertyDescriptor(Object, propertyName);

 

创建对象的方法

2.1 工厂模式

 
 
function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var sen = createPerson('sen', 19, 'programer');

缺点:无法识别一个对象属于哪一个类

 
 
alert(sen instanceof createPerson) // false

2.2 构造函数模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function() {
        alert(this.name);
    }
}
var sen = new Person("sen", 19, "programer");
alert(sen instanceof Person) // true
alert(sen.constructor === Person) // true

缺点:每个对象都会有独立的函数定义

 
 
var sen1 = new Person("sen1", 19, "player");
alert(sen1.sayName == sen.sayName) // false

2.3 原型模式

 
 
function Person() {
}
Person.prototype.name = "sen";
Person.prototype.age = "19";
Person.prototype.job = "programer";
Person.prototype.sayName = fucntion() {
    alert(this.name);
}
var sen = new Person();
Person.prototype.constructor === Person // true
Person.prototype.isPrototypeOf(sen) // true
Object.getPrototypeOf(sen) === Person.prototype // true
sen.hasOwnProperty("name") // false
"name" in sen // true

判断属性是不是在原型对象中:

 
 
!sen.hasOwnProperty("name") && ("name" in sen)

原型模式更简洁的写法:

 
 
function Person(){};
Person.prototype = {
    constructor = Person,
    name: "sen",
    age: 19,
    job: "programer",
    sayName: function() {
        alert(this.name);
    }
}
Object.defineProperty(Person.prototype, {
    enumerable: false,
    value: Person
});

缺点:

1. 省略了传递初始化参数
2. 如果原型中的属性为引用类型,则所有对象会共用这个引用类型

2.4 组合使用构造模式和原型模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
}
Person.prototype.sayName = function() {
    alert(this.name)
}

缺点: 构造函数和原型是独立的

2.5 动态原型模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    if (typeof this.sayName !== "function") {
        Person.prototype.sayName = function() {
            alert(this.name);
        };
    }
}

2.6 寄生构造函数模式

 
 
function Person(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var sen = new Person('sen', 19, 'programer');

寄生构造函数模式一般用于创建特殊的引用类型。例如,创建一个包含toPipedString方法的数组类型。

 
 
function SpecialArray() {
    var arr = new Array();
    arr.push.apply(arr, arguments);
    arr.toPipedString = function() {
        return this.join(" | ");
    }
    return arr;
}
var colors = new SpecialArray("red", "black");
alert(colors.toPipedString());

缺点和工厂模式一样,都无法被instanceof识别

2.7 稳妥构造函数模式

与寄生构造函数类似,区别在于:

  • 不使用this给类添加公共属性
  • 创建对象时不使用new关键字
 
 
  1. function Person(name, age, job) {
  2. var o = new Object();
  3. o.sayName = function() {
  4. alert(name);
  5. }
  6. return o;
  7. }
  8. var sen = Person('sen', 19, 'programer');

缺点和工厂模式一样,都无法被instanceof识别

继承

3.1 原型链

 
 
function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function() {
    return this.property;
}
function SubType() {
    this.subProperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
    return this.subProperty;
}
var obj = new SubType();
alert(obj instanceof SubType) // true
alert(obj instanceof SuperType) // true
alert(obj instanceof Object) // true

缺点:

  • SuperType中的属性如果为引用类型,所以的子类都会共用该属性
  • 创建子类时,如果给父类传递参数,会影响其他的子类

3.2 构造函数继承继承

 
 
function SuperType() {
    this.colors = ['black', 'red'];
}
function SubType() {
    SuperType.call(this);
}

缺点:函数无法复用

3.3 组合继承

 
 
function SuperType(name) {
    this.name = name;
    this.colors = ['black', 'red'];
}
SuperType.prototype.sayName = function() {
    return this.name;
}
function SubType(name) {
    SuperType.call(this, name);
}
SubType.prototype = new SuperType();

3.4 原型式继承

 
 
var person = {
    name: "sen"
}
var newPerson = Object.create(person, {name: {
    value: "yang"
}});

缺点: 原型式继承仅仅是对父类做了一个浅拷贝,并加入了子类自己的属性。所以问题和原型链相同,父类中的引用类型属性会被所有子类共用。

3.5 寄生式继承

 
 
function createAnother(obj) {
    var clone = Object.create(obj);
        clone.sayHi = function() {
        alert('hi');
    }
    return clone;
}

缺点: 函数不能复用

3.6 寄生组合式继承 (常用)

 
 
function inheritPrototype(subType, superType) {
    var prototype = Object.create(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
function SuperType(name) {
    this.name = name;
    this.colors = ['red', 'black'];
}
SuperType.prototype.sayName = function() {
    alert(this.name);
}
function SubType(name) {
    SuperType.call(this, name);
    this.age = age;
}
inheritPrototype(SubType, SuperType);

Javascript中的单体内置对象

Global

  1. encodeURI() encodeURIComponent(): 用utf-8编码替换URI中的无效字符,区别在于encodeURI并不对属于URI的特殊字符进行编码,如:// #?等
  2. eval(“var msg=’hello world'”); alert(msg);
  3. Global对象的属性:
    • undefined
    • NaN
    • Infinity
    • Object
    • Array
    • Function
    • Boolean
    • String
    • Number
    • Date
    • RegExp
    • Error
    • EvalError
    • RangeError
    • ReferenceError
    • SyntaxError
    • TypeError
    • URIError
  4. 可通过window对象来访问global对象的变量和函数
  5. var global = function(){return this;}();

Math

  • Math对象的属性:
    • Math.E
    • Math.LN10
    • Math.LN2
    • Math.LOG2E
    • Math.LOG10E
    • Math.PI
    • Math.SQRT1_2
    • Math.SQRT2
  • Math.min([1, 2, 3]) Math.max([1, 2, 3])
  • Math.ceil()
  • Math.floor()
  • Math.round()
  • Math.random():  [0-1)
  • Math.abs()
  • Math.exp()
  • Math.log()
  • Math.pow(num, power)
  • Math.sqrt()
  • Math.acos(x)
  • Math.asin(x)
  • Math.atan(x)
  • Math.atan2(y, x)
  • Math.cos(x)
  • Math.sin(x)
  • Math.tan(x)

Javascript中的基本包装类型

当读取一个基本类型(Boolean、String、Number)的值时,后台对创建一个对应的基本包装类型,从而让我们可以调用一些方法来操作这些数据。

基本包装类型与引用类型的区别:

  • 生存期。自动创建的包装类型只存在于一行代码存在的瞬间。不能在运行时为基本类型添加属性和方法。

Number类型常用的方法

  • toString()
  • toFixed(2) //小数点后两位
  • toExponential()
  • toPrecision(3)

String类型常用的属性和方法

  • length: 返回字符串的长度
  • charAt(2) charCodeAt(2): 返回字符串中第三个字符/编码
  • concat(“xxx”) 或者 + “xxx”: 字符串拼接
  • slice(start, end) subString(start, end) subStr(start, number): 字符串切片
    当start为负值时,slice和subStr会把它与字符串长度相加得到新的start;而subString则会将其转化为0
    当end/number为负值时,slice会把它与字符串长度相加得到新的end,subStr和subString会将其转化为0
  • indexOf(‘d’, start) 和lastIndexOf(‘d’, start): 从start位置开始向左(右)查找’d’在字符串中的位置
  • trim(): 返回删除字符串左右的空格的新字符串
  • trimLeft() trimRight(): 返回删除字符串左(右)的空格的新字符串
  • toLowerCase() toLocaleLowerCase() toUpperCase() toLocaleUpperCase()
  • match(pattern/RegExp): 返回的数组与RegExp.exec相同
  • search(pattern/RegExp): 返回匹配到的位置
  • replace(old, new):
    如果old为字符串时,仅替换该字符串;如果Old是带’g’标志的pattern时,会替换所有匹配的字符串
    new字符串中可以是下列特殊序列:
    $$: $
    $&: 等价于RegExp.lastMatch
    $’: RegExp.leftContext
    $`: RegExp.rightContext
    $n $nn: 第n个捕获组匹配到的字符串
    new可以是一个函数:function(match, pos, orignialText){return string}
  • var array = “string”.split(‘string/pattern’, number)

Javascript中的函数

函数的定义

  1.  var foo = fucntion(a, b) {}; //函数表达式
  2. function foo(a, b) {}; //函数声明
  3. var foo = new Function(“a”, “b”, “return false”); //不推荐

对于函数声明,可以在声明之前调用该函数;而对于函数表达式,不可以在表达式之前调用该函数。

函数的属性

  • this: 引用的是函数执行的环境对象,全局作用域中的this引用的是window对象
  • arguments: 保存函数参数的数组
  • arguments.callee: 指向该函数的指针
  • caller: 函数的调用者
  • length: 函数希望接收到的命名参数的个数

函数的方法

  • call(obj, arg1, arg2…)  //设置函数的运行环境(改变this的值)
  • apply(obj, [arg1, arg2]) //设置函数的运行环境(改变this的值)
  • bind(obj) //绑定函数的运行环境

Javascript中的正则表达式

1. RegExp类型的创建

var expression = /pattern/flags; 或者

var expression = new RegExp(“pattern”, “flags”);

用创建对象的方式来创建RegExp是需要对”pattern”中的\进行转义,例如:

/\[bc\]at/  => “\\[bc\\]at”

flags 可以是:

  • g :全局匹配
  • i :忽略大小写
  • m :多行模式

2. RegExp实例的属性

  • global: true or false, 表示标志位’g’是否被设置
  • ignoreCase: true or false
  • multiline: true or false
  • lastIndex: 下一次搜索开始的字符位置
  • source: pattern的字符串表示

3. RegExp实例的方法

  • exec(“target_string”)
    • ret.index: 匹配到的字符串的起始位置
    • ret.input: “target_string”
    • ret[0]: 匹配到的字符串
    • ret[1 – n]: 匹配组1-n匹配到的字符串
  • test(“target_string”)
    • true: 匹配到字符串
    • false: 没有匹配到字符串
  • exec和test只有在设置了’g’标志位的情况下才回去更新exp.lastIndex

4. RegExp 构造函数属性

  • input ($_): 最近一次匹配成功的源字符串
  • lastMatch($&): 最近一次的匹配项
  • lastParen($+): 最近一次匹配的捕获组
  • leftContext($`): input字符串中匹配项之前的字符串
  • rightContext($*): input字符串中匹配项之后的字符串
  • $1-9: 第1-9个匹配组

附录:

正则表达式元字符表

Metacharacter Description
^ Matches the starting position within the string. In line-based tools, it matches the starting position of any line.
. Matches any single character (many applications exclude newlines, and exactly which characters are considered newlines is flavor-, character-encoding-, and platform-specific, but it is safe to assume that the line feed character is included). Within POSIX bracket expressions, the dot character matches a literal dot. For example, a.c matches “abc”, etc., but [a.c] matches only “a”, “.”, or “c”.
[ ] A bracket expression. Matches a single character that is contained within the brackets. For example, [abc] matches “a”, “b”, or “c”. [a-z] specifies a range which matches any lowercase letter from “a” to “z”. These forms can be mixed: [abcx-z] matches “a”, “b”, “c”, “x”, “y”, or “z”, as does [a-cx-z].The - character is treated as a literal character if it is the last or the first (after the ^, if present) character within the brackets: [abc-], [-abc]. Note that backslash escapes are not allowed. The ] character can be included in a bracket expression if it is the first (after the ^) character: []abc].
[^ ] Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than “a”, “b”, or “c”. [^a-z] matches any single character that is not a lowercase letter from “a” to “z”. Likewise, literal characters and ranges can be mixed.
$ Matches the ending position of the string or the position just before a string-ending newline. In line-based tools, it matches the ending position of any line.
( ) Defines a marked subexpression. The string matched within the parentheses can be recalled later (see the next entry, \n). A marked subexpression is also called a block or capturing group. BRE mode requires \( \).
\n Matches what the nth marked subexpression matched, where n is a digit from 1 to 9. This construct is vaguely defined in the POSIX.2 standard. Some tools allow referencing more than nine capturing groups.
* Matches the preceding element zero or more times. For example, ab*c matches “ac”, “abc”, “abbbc”, etc. [xyz]* matches “”, “x”, “y”, “z”, “zx”, “zyx”, “xyzzy”, and so on. (ab)* matches “”, “ab”, “abab”, “ababab”, and so on.
{m,n} Matches the preceding element at least m and not more than n times. For example, a{3,5} matches only “aaa”, “aaaa”, and “aaaaa”. This is not found in a few older instances of regexes. BRE mode requires \{m,n\}.

 

Metacharacter Description
? Matches the preceding element zero or one time. For example, ab?c matches only “ac” or “abc”.
+ Matches the preceding element one or more times. For example, ab+c matches “abc”, “abbc”, “abbbc”, and so on, but not “ac”.
| The choice (also known as alternation or set union) operator matches either the expression before or the expression after the operator. For example, abc|def matches “abc” or “def”.

 

POSIX Non-standard Perl/Tcl Vim Java ASCII Description
[:ascii:][30] \p{ASCII} [\x00-\x7F] ASCII characters
[:alnum:] \p{Alnum} [A-Za-z0-9] Alphanumeric characters
[:word:][citation needed] \w \w \w [A-Za-z0-9_] Alphanumeric characters plus “_”
\W \W \W [^A-Za-z0-9_] Non-word characters
[:alpha:] \a \p{Alpha} [A-Za-z] Alphabetic characters
[:blank:] \s \p{Blank} [ [[\t]]] Space and tab
\b \< \> \b (?<=\W)(?=\w)|(?<=\w)(?=\W) Word boundaries
\B (?<=\W)(?=\W)|(?<=\w)(?=\w) Non-word boundaries
[:cntrl:] \p{Cntrl} [\x00-\x1F\x7F] Control characters
[:digit:] \d \d \p{Digit} or \d [0-9] Digits
\D \D \D [^0-9] Non-digits
[:graph:] \p{Graph} [\x21-\x7E] Visible characters
[:lower:] \l \p{Lower} [a-z] Lowercase letters
[:print:] \p \p{Print} [\x20-\x7E] Visible characters and the space character
[:punct:] \p{Punct} [][!"#$%&'()*+,./:;<=>?@\^_`{|}~-] Punctuation characters
[:space:] \s \_s \p{Space} or \s [ \t\r\n\v\f] Whitespace characters
\S \S \S [^ \t\r\n\v\f] Non-whitespace characters
[:upper:] \u \p{Upper} [A-Z] Uppercase letters
[:xdigit:] \x \p{XDigit} [A-Fa-f0-9] Hexadecimal digits

 

常用分组语法
分类 代码/语法 说明
捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

 

常用的反义代码
代码/语法 说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

 

 

 

Javascript中的Date

1. Date类型的创建

  • var date = new Date() //获取当前时间
  • var date = new Date(ms) //根据Unix时间戳来创建Date对象
  • var date = new Date(Date.parse(“string”)) //string为日期时间组成的字符串,符合要求的字符串格式包括:
    • “m/d/y”
    • “January 12, 2004”
    • “Tue May 25 2004 00:00:00 GMT-0700”
    • YYYY-MM-DDTHH:mm:ss.sssZ”
  • var date = new Date(Date.UTC()) // Date.UTC的参数为年、月、日、小时、分钟、秒、毫秒

2. Date类型的操作

var date = new Date();

  • Date.now() 或者+new Date()获取当前的时间戳, “+”操作符可获取Date对象的时间戳
  • date.toDateString(); // “Thu May 17 2018”
  • date.toTimeString(); // “14:37:29 GMT+0800 (CST)”
  • date.toLocaleDateString(); // “2018/5/17”
  • date.toLocaleTimeString(); // “下午2:37:29”
  • date.toUTCString(); // “Thu, 17 May 2018 06:37:29 GMT”
  • date.toLocaleString(); // “2018/5/17 下午2:37:29”
  • date.getTime(); // 1526539049298
  • +date; // 1526539049298
  • date.setTime(1526539049300);
  • date.getFullYear(); // 2018
  • date.getUTCFullYear(); // 2018
  • date.getMonth(); // 0-11
  • date.getUTCMonth(); // 0-11
  • date.getDate(); //1-31
  • date.getUTCDate(); // 1-31
  • date.getDay(); // 0-6 0表示周日
  • date.getUTCDay(); // 0-6 0表示周日
  • date.getHours(); // 0-23
  • date.getUTCHours(); // 0-23
  • date.getMinutes(); // 0-59
  • date.getUTCMinutes(); // 0-59
  • date.getSeconds(); // 0-59
  • date.getUTCSeconds(); // 0-59
  • date.getMilliseconds(); // 0-999
  • date.getUTCMilliseconds(); // 0-999
  • date.getTimezoneOffset(); // -480

[转]A Complete Guide to Flexbox

Background

The Flexbox Layout (Flexible Box) module (currently a W3C Last Call Working Draft) aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word “flex”).

The main idea behind the flex layout is to give the container the ability to alter its items’ width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow.

Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.).

Note: Flexbox layout is most appropriate to the components of an application, and small-scale layouts, while the Grid layout is intended for larger scale layouts.

Basics and Terminology

Properties for the Parent

display

This defines a flex container; inline or block depending on the given value. It enables a flex context for all its direct children.

.container {
  display: flex; /* or inline-flex */
}

Note that CSS columns have no effect on a flex container.

#flex-direction


This establishes the main-axis, thus defining the direction flex items are placed in the flex container. Flexbox is (aside from optional wrapping) a single-direction layout concept. Think of flex items as primarily laying out either in horizontal rows or vertical columns.

.container {
  flex-direction: row | row-reverse | column | column-reverse;
}
  • row (default): left to right in ltr; right to left in rtl
  • row-reverse: right to left in ltr; left to right in rtl
  • column: same as row but top to bottom
  • column-reverse: same as row-reverse but bottom to top

#flex-wrap

By default, flex items will all try to fit onto one line. You can change that and allow the items to wrap as needed with this property.

.container{
  flex-wrap: nowrap | wrap | wrap-reverse;
}
  • nowrap (default): all flex items will be on one line
  • wrap: flex items will wrap onto multiple lines, from top to bottom.
  • wrap-reverse: flex items will wrap onto multiple lines from bottom to top.

There are some visual demos of flex-wrap here.

#flex-flow (Applies to: parent flex container element)

This is a shorthand flex-direction and flex-wrap properties, which together define the flex container’s main and cross axes. Default is row nowrap.

flex-flow: <‘flex-direction’> || <‘flex-wrap’>

#justify-content


This defines the alignment along the main axis. It helps distribute extra free space left over when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size. It also exerts some control over the alignment of items when they overflow the line.

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
  • flex-start (default): items are packed toward the start line
  • flex-end: items are packed toward to end line
  • center: items are centered along the line
  • space-between: items are evenly distributed in the line; first item is on the start line, last item on the end line
  • space-around: items are evenly distributed in the line with equal space around them. Note that visually the spaces aren’t equal, since all the items have equal space on both sides. The first item will have one unit of space against the container edge, but two units of space between the next item because that next item has its own spacing that applies.
  • space-evenly: items are distributed so that the spacing between any two items (and the space to the edges) is equal.

#align-items


This defines the default behaviour for how flex items are laid out along the cross axis on the current line. Think of it as the justify-content version for the cross-axis (perpendicular to the main-axis).

.container {
  align-items: flex-start | flex-end | center | baseline | stretch;
}
  • flex-start: cross-start margin edge of the items is placed on the cross-start line
  • flex-end: cross-end margin edge of the items is placed on the cross-end line
  • center: items are centered in the cross-axis
  • baseline: items are aligned such as their baselines align
  • stretch (default): stretch to fill the container (still respect min-width/max-width)

#align-content


This aligns a flex container’s lines within when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis.

Note: this property has no effect when there is only one line of flex items.

.container {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
  • flex-start: lines packed to the start of the container
  • flex-end: lines packed to the end of the container
  • center: lines packed to the center of the container
  • space-between: lines evenly distributed; the first line is at the start of the container while the last one is at the end
  • space-around: lines evenly distributed with equal space around each line
  • stretch (default): lines stretch to take up the remaining space

Properties for the Children

order


By default, flex items are laid out in the source order. However, the order property controls the order in which they appear in the flex container.

.item {
  order: <integer>; /* default is 0 */
}

#flex-grow


This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.

If all items have flex-grow set to 1, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2, the remaining space would take up twice as much space as the others (or it will try to, at least).

.item {
  flex-grow: <number>; /* default 0 */
}

Negative numbers are invalid.

#flex-shrink

This defines the ability for a flex item to shrink if necessary.

.item {
  flex-shrink: <number>; /* default 1 */
}

Negative numbers are invalid.

#flex-basis

This defines the default size of an element before the remaining space is distributed. It can be a length (e.g. 20%, 5rem, etc.) or a keyword. The auto keyword means “look at my width or height property” (which was temporarily done by the main-size keyword until deprecated). The content keyword means “size it based on the item’s content” – this keyword isn’t well supported yet, so it’s hard to test and harder to know what its brethren max-content, min-content, and fit-content do.

.item {
  flex-basis: <length> | auto; /* default auto */
}

If set to 0, the extra space around content isn’t factored in. If set to auto, the extra space is distributed based on its flex-grow value. See this graphic.

#flex

This is the shorthand for flex-grow,flex-shrink and flex-basis combined. The second and third parameters (flex-shrink and flex-basis) are optional. Default is 0 1 auto.

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

It is recommended that you use this shorthand property rather than set the individual properties. The short hand sets the other values intelligently.

#align-self


This allows the default alignment (or the one specified by align-items) to be overridden for individual flex items.

Please see the align-items explanation to understand the available values.

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

Note that float, clear and vertical-align have no effect on a flex item.

Browser Support

Broken up by “version” of flexbox:

  • (new) means the recent syntax from the specification (e.g. display: flex;)
  • (tweener) means an odd unofficial syntax from 2011 (e.g. display: flexbox;)
  • (old) means the old syntax from 2009 (e.g. display: box;)
Chrome Safari Firefox Opera IE Android iOS
20- (old)
21+ (new)
3.1+ (old)
6.1+ (new)
2-21 (old)
22+ (new)
12.1+ (new) 10 (tweener)
11+ (new)
2.1+ (old)
4.4+ (new)
3.2+ (old)
7.1+ (new)

Blackberry browser 10+ supports the new syntax.

For more informations about how to mix syntaxes in order to get the best browser support, please refer to this article (CSS-Tricks) or this article (DevOpera).

阅读原文

操作系统级虚拟化概述

操作系统级虚拟化

KVM、XEN等虚拟化技术允许各个虚拟机拥有自己独立的操作系统。与KVM、XEN等虚拟化技术不同,所谓操作系统级虚拟化,也被称作容器化,是操作系统自身的一个特性,它允许多个相互隔离的用户空间实例的存在。这些用户空间实例也被称作为容器。普通的进程可以看到计算机的所有资源而容器中的进程只能看到分配给该容器的资源。通俗来讲,操作系统级虚拟化将操作系统所管理的计算机资源,包括进程、文件、设备、网络等分组,然后交给不同的容器使用。容器中运行的进程只能看到分配给该容器的资源。从而达到隔离与虚拟化的目的。

实现操作系统虚拟化需要用到Namespace及cgroups技术。

命名空间(Namespace)

在编程语言中,引入命名空间的概念是为了重用变量名或者服务例程名。在不同的命名空间中使用同一个变量名而不会产生冲突。Linux系统引入命名空间也有类似的作用。例如,在没有操作系统级虚拟化的Linux系统中,用户态进程从1开始编号(PID)。引入操作系统虚拟化之后,不同容器有着不同的PID命名空间,每个容器中的进程都可以从1开始编号而不产生冲突。

目前,Linux中的命名空间有6种类型,分别对应操作系统管理的6种资源:

  • 挂载点(mount point) CLONE_NEWNS
  • 进程(pid) CLONE_NEWPID
  • 网络(net) CLONE_NEWNET
  • 进程间通信(ipc) CLONE_NEWIPC
  • 主机名(uts) CLONE_NEWUTS
  • 用户(uid) CLONW_NEWUSER

将来还会引入时间、设备等对应的namespace.

Linux 2.4.19版本引入了第一个命名空间——挂载点,因为那时还没有其他类型的命名空间,所以clone系统调用中引入的flag就叫做CLONE_NEWNS

与命名空间相关的三个系统调用(system calls)

下面3个系统调用用来操作命名空间:

  • clone() —— 用来创建新的进程及新的命名空间,新的进程会被放到新的命名空间中
  • unshare() —— 创建新的命名空间但并不创建新的子进程,之后创建的子进程会被放到新创建的命名空间中去
  • setns() —— 将进程加入到已经存在的命名空间中

注意:这3个系统调用都不会改变调用进程(calling process)的pid命名空间,而是会影响其子进程的pid命名空间

命名空间本身并没用名字(囧),不同的命名空间用不同的inode号来标识,这也符合Linux用文件一统天下的惯例。可以在proc文件系统中查看一个进程所属的命名空间,例如,查看PID为4123的进程所属的命名空间:

kelvin@desktop:~$ ls -l /proc/4123/ns/
总用量 0
lrwxrwxrwx 1 kelvin kelvin 0 1226 16:28 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 kelvin kelvin 0 1226 16:28 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 kelvin kelvin 0 1226 16:28 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 kelvin kelvin 0 1226 16:28 net -> net:[4026531963]
lrwxrwxrwx 1 kelvin kelvin 0 1226 16:28 pid -> pid:[4026531836]
lrwxrwxrwx 1 kelvin kelvin 0 1226 16:28 user -> user:[4026531837]
lrwxrwxrwx 1 kelvin kelvin 0 1226 16:28 uts -> uts:[4026531838]

下面的代码演示了如何利用上述3个系统调用来操作进程的命名空间:

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/wait.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define STACK_SIZE (10 * 1024 * 1024)

char child_stack[STACK_SIZE];

int child_main(void* args) {
    pid_t child_pid = getpid();
    printf("I'm child process and my pid is %d \n", child_pid);
    // 子进程会被放到clone系统调用新创建的pid命名空间中, 所以其pid应该为1
    sleep(300);
    // 命名空间中的所有进程退出后该命名空间的inode将会被删除, 为后续操作保留它
    return 0;
}

int main() {
    /* Clone */
    pid_t child_pid = clone(child_main, child_stack + STACK_SIZE, \
        CLONE_NEWPID | SIGCHLD, NULL);
    if(child_pid < 0) {
        perror("clone failed");
    }

    /* Unshare */
    int ret = unshare(CLONE_NEWPID); // 父进程调用unshare, 创建了一个新的命名空间,
    //但不会创建子进程. 之后再创建的子进程将会被加入到新的命名空间中
    if (ret < 0) {
        perror("unshare failed");
    }
    int fpid = fork();
    if (fpid < 0) {
        perror("fork error");
    } else if (fpid == 0) {
        printf("I am child process. My pid is %d  \n", getpid());
        // Fork后的子进程会被加入到unshare创建的命名空间中, 所以pid应该为1
        exit(0);
    } else {
    }
    waitpid(fpid, NULL, 0);

    /* Setns */
    char path[80] = "";
    sprintf(path, "/proc/%d/ns/pid", child_pid);
    int fd = open(path, O_RDONLY);
    if (fd == -1)
        perror("open error");
    if (setns(fd, 0) == -1)
    // setns并不会改变当前进程的命名空间, 而是会设置之后创建的子进程的命名空间
        perror("setns error");
    close(fd);

    int npid = fork();
    if (npid < 0) {
        perror("fork error");
    } else if (npid == 0) {
        printf("I am child process. My pid is %d  \n", getpid());
        // 新的子进程会被加入到第一个子进程的pid命名空间中, 所以其pid应该为2
        exit(0);
    } else {
    }
    return 0;
}

运行结果:

$ sudo ./ns
I'm child process and my pid is 1 
I am child process. My pid is 1  
I am child process. My pid is 2 

控制组(Cgroups)

如果说命名空间是从命名和编号的角度进行隔离,而控制组则是将进程进行分组,并真正的将各组进程的计算资源进行限制、隔离。控制组是一种内核机制,它可以对进程进行分组、跟踪限制其使用的计算资源。对于每一类计算资源,控制组通过所谓的子系统(subsystem)来进行控制,现阶段已有的子系统包括:

  • cpusets: 用来分配一组CPU给指定的cgroup,该cgroup中的进程只等被调度到该组CPU上去执行
  • blkio : 限制cgroup的块IO
  • cpuacct : 用来统计cgroup中的CPU使用
  • devices : 用来黑白名单的方式控制cgroup可以创建和使用的设备节点
  • freezer : 用来挂起指定的cgroup,或者唤醒挂起的cgroup
  • hugetlb : 用来限制cgroup中hugetlb的使用
  • memory : 用来跟踪限制内存及交换分区的使用
  • net_cls : 用来根据发送端的cgroup来标记数据包,流量控制器(traffic controller)会根据这些标记来分配优先级
  • net_prio : 用来设置cgroup的网络通信优先级
  • cpu :用来设置cgroup中CPU的调度参数
  • perf_event : 用来监控cgroup的CPU性能

与命名空间不同,控制组并没有增加系统调用,而是实现了一个文件系统,通过文件及目录操作来管理控制组。下面通过一个例子来看一看cgroup是如何利用cpuset子系统来把进程绑定到指定的CPU上去执行的。

1. 创建一个一直执行的shell脚本

#!/bin/bash

x=0

while [ True ];do
    :
done;

2. 在后台执行这个脚本

# bash run.sh &
[1] 20553

3. 查看该脚本在哪个CPU上运行

# ps -eLo ruser,lwp,psr,args | grep 20553 | grep -v grep
root     20553   3 bash run.sh

可以看到PID为20553的进程运行在编号为3的CPU上,下面利用cgroups将其绑定到编号为2的CPU上去执行

4. 挂载cgroups类型的文件系统到一个新创建的目录cgroups中

# mkdir cgroups
# mount -t cgroup -o cpuset cgroups ./cgroups/
# ls cgroups/
cgroup.clone_children   cpuset.memory_pressure_enabled
cgroup.procs            cpuset.memory_spread_page
cgroup.sane_behavior    cpuset.memory_spread_slab
cpuset.cpu_exclusive    cpuset.mems
cpuset.cpus             cpuset.sched_load_balance
cpuset.effective_cpus   cpuset.sched_relax_domain_level
cpuset.effective_mems   docker
cpuset.mem_exclusive    tasks
cpuset.mem_hardwall     notify_on_release
cpuset.memory_migrate   release_agent
cpuset.memory_pressure

5. 创建一个新的组group0

# mkdir group0
# ls group0/
cgroup.clone_children  cpuset.mem_exclusive       cpuset.mems
cgroup.procs           cpuset.mem_hardwall        cpuset.sched_load_balance
cpuset.cpu_exclusive   cpuset.memory_migrate      cpuset.sched_relax_domain_level
cpuset.cpus            cpuset.memory_pressure     notify_on_release
cpuset.effective_cpus  cpuset.memory_spread_page  tasks
cpuset.effective_mems  cpuset.memory_spread_slab

6. 将上面的进程20553加入到新建的控制组中:

# echo 20553 >> group0/tasks 
# cat group0/tasks 
20553

7. 限制该组的进程只能运行在编号为2的CPU上

# echo 2 > group0/cpuset.cpus
# cat group0/cpuset.cpus
2

8. 查看PID为20553的进程所运行的CPU编号

# ps -eLo ruser,lwp,psr,args | grep 20553 | grep -v grep
root     20553   2 bash run.sh

上面的例子简单的展示了如何使用控制组。控制组通过文件和目录来操作,文件系统又是树形结构,因此如果不对cgroups的使用做一些限制的话,配置会变得异常复杂和混乱。因此,在新版的cgroups中做了一些限制。

小结

本文简要介绍了操作系统虚拟化的概念,以及实现操作系统虚拟化的技术——命名空间及控制组。并通过两个简单的例子演示了命名空间及控制组的使用方法。

Javascript中的数组

  • 数组的定义:
    • var colors = new Array(20);
    • var colors = new Array(‘red’);  // [‘red’]
    • var colors = [‘red’, ‘green’];
  • 判断变量是不是数组:
    • colors instanceof Array;  //true
    • Array.isArray(colors); //true
  • 将数组转化为字符串:
    • colors.toString(); // ‘red,green’
    • colors.join(‘ ‘); //’red green’
    • colors = [ “red”, undefined, “green”, null, “yellow” ];
      • colors.toString(); //"red,,green,,yellow"
        
        colors.join(' '); //"red  green  yellow"
        
        colors.join(';'); //"red;;green;;yellow"
  • 栈方法
    • colors.push(‘yellow’); //[‘red’, ‘green’, ‘yellow’]
    • colors.pop(); //[‘red’, ‘green’]
  • 队列方法
    • colors.push(‘yellow’); //[‘red’, ‘green’, ‘yellow’]
    • colors.shift(); //[‘green’, ‘yellow’]
    • colors.unshift(‘black’); //[‘black’, ‘red’, ‘green’]
  • 重新排序
    • colors.reverse(); //[‘green’, ‘red’]
    • colors.sort();
      • 字符串升序排列
        • var nums = [1, 5, 10]; //nums.sort();//[1, 10, 5]
      • colors.sort(function(a,b){return a – b;});升序排列
      • colors.sort(function(a,b){return b – a;});降序排列
  • 操作
    • var ret = colors.concat(‘black’); // ret = [‘red’, ‘green’, ‘black’]
    • var ret = colors.slice(0, 1); //[‘red’] 切片
    • colors.splice(pos, length, item, item…); 在pos处删除length项,然后插入item…
  • 位置
    • indexOf(‘red’); //0
    • lastIndexOf(‘red’); //0
  • 迭代
    • colors.every(function(item, index, array){}); 所有元素返回true则返回true
    • colors.filter(function(item, index, array){}); 返回为true的元素组成的数组
    • colors.forEach(function(item, index, array){}); 无返回值
    • colors.map(function(item, index, array){}); 返回函数调用结果组成的数组
    • colors.some(function(item, index, array){}); 如果有一项返回true则返回true
  • 归并方法
    • var sum = values.reduce(function(prev, cur, index, array){return prev + cur}, 0);
    • reduceRight(); 从后往前循环

Javascript中的基本数据类型

Undefined

  • 在var或者let中声明了变量但没有赋值时,这个变量的值就是undefined.
  • 使用typeof关键字检测未声明变量的类型为undefined.

Null

  • null表示一个空对象指针,所以用typeof检测null时,会返回object
  • undefine派生自null, null == undefined 为true, null === undefined为false

Boolean

  • true false 区分大小写
  • 空字符串、0和NaN、null、undefined转换为boolean的值为false

Number

  • Number表示整数和浮点数
  • 八进制数以0开头,十六进制数以0x开头
  • Number.MIN_VALUE 表示Javascript支持的正的最小数值,Number.MAX_VALUE表示Javascript支持的最大数值
  • 超出最大数值就会被转化为Infinity,如果为负值则会被转化为-Infinity
  • isFinite()函数可以判断一个数值是否在支持的范围之内
  • NaN表示本来该返回数值的操作数未返回数值的情况,如除以0就会返回NaN
  • NaN的数值运算会返回NaN
  • NaN == NaN 为false
  • isNaN()函数可以判断一个数值是不是NaN
  • Number()函数可以将其他类型的值转换为Number类型:
    • Number(true) = 1; Number(false) = 0;
    • Number(null) = 0;
    • Number(“”) = 0; Number(“0x1a”) = 26; Number(‘076’) = 76;
    • Number(‘100hello’) = NaN;
    • 如果是对象,则会调用对象的valueOf()方法,如果返回的是NaN则会先调用toString方法转化为字符串,然后根据字符串的转换规则来转换
  • parseInt()函数:
    • parseInt(‘100hello’) = 100;
    • parseInt(”) = NaN;
    • parseInt(‘0x1a’) = 26;
    • parseInt(‘076’) = 76; parseInt(‘076’, 8) = 62;
  • parseFloat()与parseInt()类似,但有如下区别:
    • parseFloat不能传入第二个参数(进制),不能解析十六进制字符串

String

  • 字符串一旦创建,其值不能改变,如:var lang = ‘Java’; lang += ‘Script’; 会重新创建一个字符串,填充上’JavaScript’, ‘Java’和’Script’都将被销毁
  • 除了null和undefined之外,其他的几个数据类型都有toString()方法,可以将其转换为字符串
  • 数值类型调用toString()方法可以传入进制作为参数,如:var a=20; a.toString(2);
  • String()方法可以将null转化为’null’,把undefined转化为’undefined’

React 概要

React 简介

React 是一个开源的javascript库,用来构建用户接口(UI)。下图是React的一些基本信息:

React 的特点

  1. 单向数据流
    • 数据自上而下
      • Props 不可变
      • States可变
      • 任何数据、函数都可以作为属性(props)传    递给子组件(Props, States, Handlers, Styles)
    • 事件冒泡
      • 子组件触发的事件会传递到父组件
  2. 虚拟DOM
    • Javascript内存中的DOM数据缓存
    • 组件发生变化时渲染虚拟DOM
    • React将虚拟DOM与DOM的差异转化为一系列的DOM操作
    • 将这些操作同步应用到真实的DOM中
  3. JSX
    • 可以使用HTML语法创建Javascript 对象
    • 代码更少
    • 会被转化为Javascript执行
      • Offline – react-tools
      • In-Browser – JSXTransformer
    • 不改变Javascript语义
  4. 其他特点
    • 元素嵌套: 每个组件只允许有一个顶层元素(div, table …)
    • 自定义属性: 除了HTML标签自带属性之外,React也支持自定义属性,自定义属性需要加上data- 前缀
    • JavaScript表达式: 可以通过{}在JSX中使用Javascript表达式
    • 三目运算符: JSX中不能使用if-else但可以使用三目运算符

React元素

const element = <h1>Hello, world</h1>;

  • React 元素 != DOM 元素
  • 将元素渲染到 DOM 中

    ReactDOM.render(element, document.getElementById(‘root’));
     

  • 更新元素 – 重新 Render
  • 更新元素只会更新变化的部分
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}
setInterval(tick, 1000);

React组件

组件可以将UI切分成一些的独立的、可复用的部件,这样你就只需专注于构建每一个单独的部件。

  • 如何定义一个组件
    • 函数
      function Welcome(props) {
        return <h1>Hello, {props.name}</h1>;
      }

       

    • class
      class Welcome extends React.Component {
        render() {
          return <h1>Hello, {this.props.name}</h1>;
        }
      }

       

  • 渲染组件
    • const element = <Welcome name=”Sara” />;
  • 组合组件
function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

状态与生命周期

因为react中props为只读,如果需要更新数据,可以使用react中的状态。在使用状态之前,需要把组件函数转变为类。

  • 创建一个名称扩展为 React.Component 的ES6 类
  • 创建一个叫做render()的空方法
  • 将函数体移动到 render() 方法中
  • 在 render() 方法中,使用 this.props 替换 props
  • 删除剩余的空函数声明

将组件函数转化为类之后就可以添加状态了:

  • 在 render() 方法中使用 this.state.date 替代 this.props.date
  • 添加一个类构造函数来初始化状态 this.state
  • 使用 this.setState() 来更新组件局部状
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
  tick() {
    this.setState({
      date: new Date()
    });
  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

事件处理

  • React事件绑定属性的命名采用驼峰式写法,而不是小写。
  • 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法)
  • React不能使用返回 false 的方式阻止默认行为

条件渲染

  • 使用 JavaScript 操作符 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI
  • 使用变量来储存元素
    function Greeting(props) {
      const isLoggedIn = props.isLoggedIn;
      if (isLoggedIn) {
        return <UserGreeting />;
      }
      return <GuestGreeting />;
    }
    ReactDOM.render(
      // Try changing to isLoggedIn={true}:
      <Greeting isLoggedIn={false} />,
      document.getElementById('root')
    );

     

  • &&运算符
    function Mailbox(props) {
      const unreadMessages = props.unreadMessages;
      return (
        <div>
          <h1>Hello!</h1>
          {unreadMessages.length > 0 &&
            <h2>
              You have {unreadMessages.length} unread messages.
            </h2>
          }
        </div>
      );
    }

     

  • 三目运算符
    render() {
      const isLoggedIn = this.state.isLoggedIn;
      return (
        <div>
          The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
        </div>
      );
    }

     

列表渲染

  • React 可以直接渲染列表
  • Keys可以在DOM中的某些元素被增加或删除的时候帮助React识别哪些元素发生了变化。因此应当给数组中的每一个元素赋予一个确定的标识。
  • 元素的key只有在它和它的兄弟节点对比时才有意义
  • jsx中可以使用map
function ListItem(props) {
  return <li>{props.value}</li>;
}
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

表单

  • HTML表单元素与React中的其他DOM元素有所不同,因为表单元素生来就保留一些内部状态
  • 在HTML当中,像<input>,<textarea>, 和 <select>这类表单元素会维持自身状态,并根据用户输入进行更新
  • 在React中,可变的状态通常保存在组件的状态属性中,并且只能用 setState(). 方法进行更新
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };
    this.handleInputChange = this.handleInputChange.bind(this);
  }
  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  }
  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

 

[转]Linux Mint启用VNC

This tutorial was adapted from here.

1. Remove the default Vino server:

sudo apt-get -y remove vino

2. Install x11vnc:

sudo apt-get -y install x11vnc

3. Create the directory for the password file:

sudo mkdir /etc/x11vnc

4. Create the encrypted password file:

sudo x11vnc –storepasswd /etc/x11vnc/vncpwd

You will be asked to enter and verify the password.  Then press Y to save the password file.

5. Create the systemd service file for the x11vnc service:

sudo xed /lib/systemd/system/x11vnc.service

Copy/Paste this code into the empty file:

[Unit]
Description=Start x11vnc at startup.
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/x11vnc -auth guess -forever -noxdamage -repeat -rfbauth /etc/x11vnc/vncpwd -rfbport 5900 -shared

[Install]
WantedBy=multi-user.target

6: Reload the services:

sudo systemctl daemon-reload

7. Enable the x11vnc service at boot time:

sudo systemctl enable x11vnc.service

8. Start the service:

Either reboot or

sudo systemctl start x11vnc.service

CSS概要

CSS 基础知识

语法

CSS全称为“层叠样式表 (Cascading Style Sheets)”,它主要是用于定义HTML内容在浏览器内的显示样式, 如文字大小、颜色、字体加粗等。使用CSS样式的一个好处是通过定义某个样式,可以让不同网页位置的 文字有着统一的字体、字号或者颜色等。

CSS语法
选择符 { 属性:值}

  • 选择符:又称选择器,指明网页中要应用样式规则的元素,如本例中是网页中所有的段(p)的文字将变 成蓝色,而其他的元素(如ol)不会受到影响。
  • 声明:在英文大括号“{}”中的的就是声明,属性和值之间用英文冒号“:”分隔。当有多条声明时,中间 可以英文分号“;”分隔
  1. 最后一条声明可以没有分号,但是为了以后修改方便,一般也加上分号
  2. CSS注释 – /*注释语句*/
  3. CSS的某些样式是具有继承性的。
  4. 为了使用样式更加容易阅读,可以将每条代码写在一个新行内

插入方式

CSS样式可以写在哪些地方呢?从CSS 样式代码插入的形式来看基本可以分为以下3种:内联式、嵌入式和

外部式三种。

  1. 内联式:把css代码用style属性直接写在现有的HTML标签中。如: <p style=”color:red”>这里文字是红色。</p>
  2. 嵌入式:把css样式代码写在<style type=“text/css”></style>标签之间。并且一般情况下嵌入式css样式 写在<head></head>之间。如:<style type=”text/css”> span{ color:red; } </style>
  3. 外部式:把css代码写一个单独的外部文件中,这个css样式文件以“.css”为扩展名,在<head>内(不是在<style>标签内)使用<link>标签将css样式文件链接到HTML文件内。如: <link href=”base.css” rel=”stylesheet” type=”text/css” />

优先级:内联式 > 嵌入式 > 外部式 ?

离被设置元素越近优先级别越高

权值、层叠、重要性

标签的权值为1,类选择符的权值为10,ID选择符的权值最高为100

  • p{color:red;} /*权值为1*/
  • p span{color:green;} /*权值为1+1=2*/
  • .warning{color:white;} /*权值为10*/
  • p span.warning{color:purple;} /*权值为1+1+10=12*/
  • #footer .note p{color:yellow;} /*权值为100+10+1=111*/

层叠就是在html文件中对于同一个元素可以有多个css样式存在,当有相同权重的样式存在时,会根据这些 css样式的前后顺序来决定,处于最后面的css样式会被应用。

p{color:red;}
p{color:green;}
<p class=”first”>hello world</p>

!important语句可以把样式改变为最高权值

p{color:red !important;} p{color:green;}
<p class=”first”>hello world</p>

单位和值

颜色值

  1. 英文命令颜色。 如: p{color:red;}
  2. RGB颜色 p{color:rgb(133,45,200);} 3.十六进制颜色 p{color:#00ffff;}

长度值

  1. 像素。 如: p{font-size: 20px}
  2. em。1 em = 父元素的font-size 如: p{font-size:14px} span{font-size:0.8em;} <p>以这个<span>例子</span>为例。</p>
  3. 百分比 p{font-size:12px;line-height:130%}

CSS 选择器

在{}之前的部分就是“选择器”,“选择器”指明了{}中的“样式”的作用对象,也就是“样式”作用于网页中的哪些元素。

  • 标签选择器 – 标签选择器其实就是html代码中的标签。

  • 类选择器

    .setGreen {
        color:green;
    }

    <span class=”setGreen”>胆小如鼠</span>

  • Id选择器

    #setGreen {
         color:green;
    }

  • 子选择器 – 即大于符号(>),用于选择指定标签元素的第一代子元素

    .food>li{border:1px solid red;}

  • 包含选择器 – 即加入空格,用于选择指定标签元素下的后辈元素

  • 通用选择器 – 它使用一个(*)号指定,它的作用是匹配html中所有标签元素

  • 伪类选择符 – 它允许给html不存在的标签(标签的某种状态)设置样式,如:a:hover{color:red;}

  • 分组选择符 – html中多个标签元素设置同一个样式时,可以使用分组选择符

    h1,span{color:red;}

CSS 排版 

  1. 设置字体: font-family:”宋体”

  2. 设置字号、颜色:font-size:12px;color:#666

  3. 设置文字的样式:粗体、斜体、下划线、删除线:

    • font-weight:bold;

    • font-style:italic

    • text-decoration:underline;

    • text-decoration:line-through;

  4. 设置文字缩进:text-indent:2em;

  5. 设置行高:line-height:2em;

  6. 设置字符间距、单词间距:

    • letter-spacing:50px;

    • word-spacing:50px;

  7. 设置对齐方式:

    • text-align:left;

    • text-align:center;

    • text-align:right;

CSS 布局模型

元素分类 在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素、内联元素(又叫行内元素)和内联块状元素。

常用的块状元素(display: block)有: <div>、<p>、<h1>…<h6>、<ol>、<ul>、<dl>、<table>、<address>、<blockquote> 、<form>

  • 每个块级元素都从新的一行开始,并且其后的元素也另起一行。
  • 元素的高度、宽度、行高以及顶和底边距都可设置。
  • 元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。

常用的内联元素(display: inline)有: <a>、<span>、<br>、<i>、<em>、<strong>、<label>、<q>、<var>、<cite>、<code>

  • 和其他元素都在一行上;
  • 元素的高度、宽度及顶部和底部边距不可设置;
  • 元素的宽度就是它包含的文字或图片的宽度,不可改变。

常用的内联块状元素(display: inline-block)有: <img>、<input>

  • 和其他元素都在一行上;
  • 元素的高度、宽度、行高以及顶和底边距都可设置。

盒子模型

流动模型 flow

流动模型,流动(Flow)是默认的网页布局模式。也就是说网页在默认状态下的 HTML 网页元素都是根据流

动模型来分布网页内容的。 流动布局模型具有2个比较典型的特征:

  • 块状元素都会在所处的包含元素内自上而下按顺序垂直延伸分布,因为在默认状态下,块状元素的 宽度都为100%。实际上,块状元素都会以行的形式占据位置。
  • 在流动模型下,内联元素都会在所处的包含元素内从左到右水平分布显示。

浮动模型 float

浮动模型,浮动(Float)如果想让两个块状元素并排显示,需要用到浮动模型。

Div {
    width:200px;
    height:200px;
    border:2px red solid;
    float:left;
}

<div id=”div1″> </div>
<div id=”div2″> </div>

层模型

什么是层布局模型?层布局模型就像是图像软件PhotoShop中非常流行的图层编辑功能一样,每个图层能够 精确定位操作,但在网页设计领域,由于网页大小的活动性,层布局没能受到热捧。但是在网页上局部使用 层布局还是有其方便之处的

层模型有三种形式:

  1. 绝对定位(position: absolute)
  2. 相对定位(position: relative)
  3. 固定定位(position: fixed)

如果想为元素设置层模型中的绝对定位,需要设置position:absolute(表示绝对定位),这条语句的作用将元 素从文档流中拖出来,然后使用left、right、top、bottom属性相对于其最接近的一个具有定位属性的父包含块 进行绝对定位。如果不存在这样的包含块,则相对于body元素,即相对于浏览器窗口。

如果想为元素设置层模型中的相对定位,需要设置position:relative(表示相对定位),它通过left、right、top、 bottom属性确定元素在正常文档流中的偏移位置。相对定位完成的过程是首先按static(float)方式生成一个元 素(并且元素像层一样浮动了起来),然后相对于以前的位置移动,移动的方向和幅度由left、right、top、 bottom属性确定,偏移前的位置保留不动。

fixed:表示固定定位,与absolute定位类型类似,但它的相对移动的坐标是视图(屏幕内的网页窗口)本身。 由于视图本身是固定的,它不会随浏览器窗口的滚动条滚动而变化,除非你在屏幕中移动浏览器窗口的屏幕 位置,或改变浏览器窗口的显示大小,因此固定定位的元素会始终位于浏览器窗口内视图的某个位置,不会 受文档流动影响

弹性盒布局

详细介绍请参考:https://www.ibm.com/developerworks/cn/web/1409_chengfu_css3flexbox/

.flex-container {
   list-style: none;
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
}
<ul class="flex-container">
<li class="flex-item"><imgsrc="//placehold.it/300&text=1"></li>
<li class="flex-item"><img src="//placehold.it/300&text=2"></li>
<li class="flex-item"><img src="//placehold.it/300&text=3"></li>
<li class="flex-item"><img src="//placehold.it/300&text=4"></li>
<li class="flex-item"><img src="//placehold.it/300&text=5"></li>
<li class="flex-item"><img src="//placehold.it/300&text=6"></li>
</ul>
.flex-item {   
    padding: 5px;
}

CSS 设计技巧

• 水平居中设置-行内元素

通过给父元素设置 text-align:center 来实现的

• 水平居中设置-定宽块状元素

通过设置“左右margin”值为“auto”来实现居中的

• 水平居中设置-不定宽块状元素方法

  1. 加入 table 标签

  2. 设置 display: inline 方法:与第一种类似,显示类型设为 行内元素,进行不定宽元素的属性设置

  3. 设置 position:relative 和 left:50%:利用 相对定位 的方式,将元素向左偏移 50% ,即达到居中的目的

• 垂直居中-父元素高度确定的单行文本

通过设置父元素的 height 和 line-height 高度一致来实现的

• 垂直居中-父元素高度确定的多行文本

  1. 使用插入 table (包括tbody、tr、td)标签,同时设置 vertical-align:middle

  2. 设置块级元素的 display 为 table-cell(设置为表格单元显示),激活 vertical-align 属性

Openstack Trove概要

Trove简介

Openstack Trove是openstack为用户提供的数据库即服务(DBaaS)。所谓DBaaS,即trove既具有数据库管理的功能,又具有云计算的优势。使用trove,用户可以:

  • “按需”获得数据库服务器
  • 配置所获得的数据库服务器或者数据库服务器集群
  • 对数据库服务器或者数据库服务器集群进行自动化管理
  • 根据数据库的负载让数据库服务器集群动态伸缩

与openstack的其他组件一样,trove也提供RESTful API,并通过RESTful API和其他组件进行交互。

Trove架构

上图为trove的架构图。Trove API和用户进行交互,当Trove API接收到用户请求时,trove API首先会调用Keystone的API来对用户进行认证,认证通过后才会去执行相应的操作。Trove API会同步处理操作简单的一些请求,复杂的请求则会通过Message Queue (RabbitMQ)交给Task Manager来处理。Task Manager会监听RabbitMQ的一个topic,收到请求后就会进行处理。这些请求通常是分配数据库实例、管理数据库实例的生命周期、操作数据库等。和openstack的其他组件一样,Trove也有一个Infrastructure Database来存储自己本身的数据,如数据库实例的信息等。Trove conductor的主要功能是接收来自guest agent的状态更新信息,这些信息会被存储在Infrastructure database里面或者作为调用结果返回给其他服务。通常这些状态更新信息包括:guest agent心跳包,数据库备份状态等。Guest Agent运营于数据库服务器中(虚拟机),给trove其他组件提供了一套内部使用的API,trove的其他组件通过Message Queue来调用这些API,guest agent收到API调用请求后,执行相应的数据库操作。

Trove的安装部署请参考Openstack官方文档(多坑慎入):

https://docs.openstack.org/project-install-guide/database/ocata/

Trove的基本概念

  • 数据库实例(Instance):包含数据库程序的openstack虚拟机,如果用户创建了一个数据库实例,那么他其实就创建了一台openstack虚拟机,并在该虚拟机上启动了数据库服务。
  • Datastore:用来表示和存储数据库的类型、版本、虚拟机镜像等信息。当用户创建一个数据库实例时需要指定Datastore.
  • 配置组(Configuration Group):数据库参数组成的集合。用户可以将配置组应用到一个或多个数据库实例上,因而避免了大量的重复操作。

Trove的用法

0.添加Datastore

在创建数据库实例时,需要指定Datastore来告诉trove需要用到的镜像、数据库类型及版本信息。所以在创建数据库实例之前需要在系统中创建Datastore.

由于版权问题,openstack官方并没有提供可供下载的镜像,需要用户自己去build。可参考文档:

https://docs.openstack.org/developer/trove/dev/building_guest_images.html

Build好镜像好需要将其上传到glance服务:

ad@ltczhp11:~$ glance image-create --name mysql-5.6 --disk-format=qcow2 --container-format=bare --file=./mysql-5.6.qcow2 --visibility public 
ad@ltczhp11:~$ glance image-list
+--------------------------------------+--------------------------+
| ID                                   | Name                     |
+--------------------------------------+--------------------------+
| 31d60001-c2bf-496e-9f21-069bb411bd3b | CouchDB                  |
| eaf27f1b-3a8a-4efb-827c-697fa065933b | DB2                      |
| 60ca8bfc-28a7-418a-9422-ec6548f23d54 | DIB-Mongodb              |
| 51103b44-2618-4c15-8ded-4371bea8973a | DIB-Postgres             |
| 8bc1a6a2-6ec3-4f37-bb54-91134b903996 | mongodb-lsl              |
| c4c9a58f-bbe6-4640-8488-0c05b52028df | mysql-5.6                |
| 5d800163-3660-467a-a433-e1827924a741 | PostgreSQL               |
| 38291f8f-5af6-4338-82b7-3f18dc355cae | ubuntu16.04-server-s390x |
+--------------------------------------+--------------------------+

使用trove-manage添加Datastore:

root@ltczhp11:~# trove-manage datastore_update mysql "" #创建一个datastore

root@ltczhp11:~# trove-manage datastore_version_update mysql 5.6 mysql c4c9a58f-bbe6-4640-8488-0c05b52028df "" 1 #创建一个dadastore的版本,一个dadastore可以有多个版本

root@ltczhp11:~# trove-manage datastore_update mysql 5.6 #指定默认的datastore版本

1.基本的数据库实例操作

  • 列出所有的数据库实例
    • $ trove list
  • 创建一个数据库实例
    • $ trove create vm1 2 –size 3 –datastore mysql
  • 重启一个数据库实例
    • $ trove restart vm1
  • 删除一个数据库实例
    • $ trove delete vm1
  • 强制删除一个数据库实例
    • $ trove force-delete vm1
  • 调整一个数据库实例的规格
    • $ trove resize-volume vm1 4
    • $ trove resize-instance vm1 3

2.管理数据库用户

  • 列出所有的数据库用户
    • $ trove user-list
  • 创建一个用户
    • $ trove user-create
  • 删除一个用户
    • $ trove user-delete
  • 给一个用户授权访问某个数据库
    • $ trove user-grant-access
  • 吊销用户对于某一个数据库的访问权限
    • $ trove user-revoke-access
  • 显示用户信息
    • $ trove user-show
  • 显示用户的权限
    • $ trove user-show-access

3. 数据库管理

  • 在一个数据库实例中创建一个数据库
    • $ trove database-create
  • 列出一个数据库实例中的所有数据库
    • $ trove database-list
  • 删除一个数据库实例中的某个数据库
    • $ trove database-delete

4. 副本管理

  • 创建一个副本
    • $ trove create  —replica_of
  • 将一个副本从源数据库分离
    • $ trove detach-replica
  • 让一个副本在副本集合中成为源数据库
    • $ trove promote-to-replica-source
  • 删除挂掉的源数据库
    • $ trove eject-replica-source
  • 设置副本亲和性
    • $ trove create  —replica_of  –locality affinity
    • $ trove create  —replica_of  –locality anti-affinity

 

 

ATOM快捷键操作

光标移动

·       Alt+Left or Alt+B – Move to the beginning of word

·       Alt+Right or Alt+F – Move to the end of word

·       Cmd+Left or Ctrl+A – Move to the first character of the current line

·       Cmd+Right or Ctrl+E – Move to the end of the line

·       Cmd+Up – Move to the top of the file

·       Cmd+Down – Move to the bottom of the file

·       Ctrl+P – Go up a single character

·       Ctrl+N – Go down a single character

·       Ctrl+B – Go left to a single character

·       Ctrl+F – Go right to a single character

·       Ctrl+G – Go to a certain line

·       Cmd+R – Jump to a symbol such as a method definition

·       Cmd+Shift+R – Search for symbols across the project

·       Alt+Cmd+Down to go to and Alt+Cmd+Up to return from the declaration of the symbol under the cursor

选择文本

·       Shift+移动快捷键

·       Cmd+A – Select the entire contents of the file

·       Cmd+L – Select the entire line

·       Ctrl+Shift+W – Select the current word

编辑文本

·       Cmd+J – Join the next line to the end of the current line

·       Cmd+Ctrl+Up/Down – Move the current line up or down

·       Cmd+Shift+D – Duplicate the current line

·       Cmd+K Cmd+U – Upper case the current word

·       Cmd+K Cmd+L – Lower case the current word

·       Ctrl+T – Transpose characters. This swaps the two characters on either side of the cursor.

·       Ctrl+Shift+K – Delete current line

·       Alt+Backspace or Alt+H – Delete to beginning of word

·       Alt+Delete or Alt+D – Delete to end of word

·       Cmd+Delete – Delete to end of line

·       Ctrl+K – Cut to end of line

·       Cmd+Backspace – Delete to beginning of line

多光标操作

·       Cmd+Click – Add a new cursor at the clicked location

·       Ctrl+Shift+Up/Down – Add another cursor above/below the current cursor

·       Cmd+D – Select the next word in the document that is the same as the currently selected word

·       Cmd+Ctrl+G – Select all words in the document that are the same as the currently selected word

·       Cmd+Shift+L – Convert a multi-line selection into multiple cursors

查找和替换文本

·       Cmd+F – Search within a buffer

·       Cmd+Shift+F – Search the entire project

 

"