分类目录应用开发

Sass 概要

前端开发中最大的坑之一莫过于写css,流水账式的写法让众多码农们头痛不已。好在有了sass,写css不再死板。sass对css的增强如下:

宏定义

宏定义的优点在于一处定义,多处使用,需要修改的时候只需要修改定义的地方即可。虽然sass没有明确的说明,但其实以下几种语法与C语言中的宏定义非常类似:

  1. 变量
    sass中的变量适用于替换css中参数的值。例如:

     
     
    scss:
    $basic-margin: "10px 20px";
    #box01 {
      margin: $basic-margin;
    }
    #box02 {
      margin: $basic-margin;
    }
    css:
    #box01 {
      margin: "10px 20px";
    }
    #box02 {
      margin: "10px 20px";
    }

    sass允许根据变量,选择性的输出css,类似于开关,例如:

     
     
    scss:
    $rounded-corners: false;
    .button {
      border: 1px solid black;
      border-radius: if($rounded-corners, 5px, null);
    }
    css:
    .button {
      border: 1px solid black;
    }

    sass 也允许在子模块中给变量设置默认值,引用的时候可以再重新定义变量的值

     
     
    _module.scss:
    $userColor: red !default;
    .bass {
      padding: 0 20px;
      color: $userColor;
    }
    test.scss:
    $userColor: black;
    @import "module";
    test.css:
    .bass {
      padding: 0 20px;
      color: black;
    }
     
     
    test.scss:
    @import "module";
    test.css
    .bass {
      padding: 0 20px;
      color: red;
    }

    使用!global可以在局部环境中设置全局变量的值,例如:

     
     
    test.scss:
    $color: red;
    .text {
      $color: black !global;
    }
    .box {
      color: $color;
    }
    test.css:
    .box {
      color: black;
    }
  2. mixin
    sass中的mixin类似于支持参数的代码片段,可以很方便的将一段常用的代码片段插入到css规则中去,例如:

     
     
    scss:
    @mixin normal-font($fontfamily) {
      font-size: 18px;
      font-family: $fontfamily;
    }
    .box {
      width: 200px;
      height: 200px;
      @include normal-font("IBM Plex Sans");
    }
    css:
    .box {
      width: 200px;
      height: 200px;
      font-size: 18px;
      font-family: "IBM Plex Sans";
    }
  3. 扩展与继承
    sass中的扩展相当于不带参数的代码片段,适用于同一组件的不同状态,语法如下:

     
     
    scss:
    %message-shared {
      border: 1px solid #ccc;
      padding: 10px;
      color: #333;
    }
    .message {
      @extend %message-shared;
    }
    .success {
      @extend %message-shared;
      border-color: green;
    }
    .error {
      @extend %message-shared;
      border-color: red;
    }
    .warning {
      @extend %message-shared;
      border-color: yellow;
    }
    css:
    .warning, .error, .success, .message {
      border: 1px solid #ccc;
      padding: 10px;
      color: #333;
    }
    .success {
      border-color: green;
    }
    .error {
      border-color: red;
    }
    .warning {
      border-color: yellow;
    }

     

模块化

sass也借鉴了编程语言中的模块化思想,允许文件引入。以下划线开头的文件类似于子模块,不会被被sass编译为css,只能被其他scss文件引用。例如:

 
 
_module.scss:
.bass {
  padding: 0 20px;
}
test.scss:
@import "module";
$basic-margin: "10px 20px";
#box01 {
  margin: $basic-margin;
}
#box02 {
  margin: $basic-margin;
}
test.css:
.bass {
  padding: 0 20px;
}
#box01 {
  margin: "10px 20px";
}
#box02 {
  margin: "10px 20px";
}

语法简化

scss也对css的语法做了一些简化,比如说:

  1. 嵌套
    写scss子元素的规则不再另起一条规则,只需要嵌套在父元素中的规则中即可,例如:

     
     
    scss:
    $basic-margin: "10px 20px";
    .bss {
      margin: $basic-margin;
      #dash {
        margin-top: 20px;
        padding-top: 20px;
      }
      .dash {
        margin-top: 20px;
        margin-bottom: 20px;
      }
    }
    css:
    .bss {
      margin: "10px 20px";
    }
    .bss #dash {
      margin-top: 20px;
      padding-top: 20px;
    }
    .bss .dash {
      margin-top: 20px;
      margin-bottom: 20px;
    }

    另一种方式的嵌套:

     
     
    scss:
    .box {
      margin: {
        top: 20px;
        bottom: 10px;
        right: 10px;
        left: 20px;
      }
    }
    css:
    .box {
      margin-top: 20px;
      margin-bottom: 10px;
      margin-right: 10px;
      margin-left: 20px;
    }

可编程化

sass也做了一些工作让css更像一门编程语言而不是一遍作文。其中包括:

  1. 支持运算
    css是不支持运算的,而在scss中可以做一些简单的运算,例如:

     
     
    scss:
    .box {
      width: 100px / 200px * 100%;
    }
    css:
    .box {
      width: 50%;
    }
  2. 数值类型
    scss中的值分为以下几种类型:

    • 数字,例如: 20, 20px
    • 字符串,例如:”IBM Plex Sans”, bold
    • 颜色值,例如:#ffffff, blue
    • 布尔值, true, false
    • 列表,例如:0 20px 30px 40px
    • 字典,例如:(“background”: red, “foreground”: pink)
  3. 操作符
    scss中的操作符包括:

    • == , !=  : 判断两个值是否相等/不相等
    • + – * / %
    • < <= > >=
    • and or not
    • + – / 可用于字符串拼接
    • () 用于优先级设定
    • &父元素选择器
    • #{} 可以将sass表达式插入到css的文本中
  4. 代码注释
    • // 单行注释,不会编译到css中
    • /**/多行注释,一般会被编译进css
    • 压缩模式下,多行注释不会被编译进css,除非以/*!开头
    • ///为文档注释,不会被编译到css中,会被sassdoc工具使用,生成sass的文档
  5. 函数
    scss中的函数主要用于数值计算,例如:

     
     
    scss:
    @function pow($base, $exponent) {
      $result: 1;
      @for $_ from 1 through $exponent {
        $result: $result * $base;
      }
      @return $result;
    }
    .sidebar {
      float: left;
      margin-left: pow(4, 3) * 1px;
    }
    css:
    .sidebar {
      float: left;
      margin-left: 64px;
    }

    Sass中的内建函数详见 https://sass-lang.com/documentation/functions

  6.  流程控制
    • 分支 @if , @else, @else if
      例如:

       
       
      scss:
      @mixin triangle($color, $size, $direction) {
        display: block;
        height: 0;
        width: 0;
        border: $size/2 solid transparent;
        @if $direction == up {
          border-bottom-color: $color;
        } @else if $direction == down {
          border-top-color: $color;
        } @else if $direction == left {
          border-right-color: $color;
        } @else if $direction == right {
          border-left-color: $color;
        } @else {
          @error "wrong direction: #{$direction}";
        }
      }
      .next {
        @include triangle(green, 20px, right);
      }
      css:
      .next {
        display: block;
        height: 0;
        width: 0;
        border: 10px solid transparent;
        border-left-color: green;
      }
    • 循环 @each @for @while
      例如:

       
       
      scss:
      $sizes: 40px, 50px, 80px;
      @each $size in $sizes {
        .icon-#{$size} {
          font-size: $size;
          height: $size;
          width: $size;
        }
      }
      css:
      .icon-40px {
        font-size: 40px;
        height: 40px;
        width: 40px;
      }
      .icon-50px {
        font-size: 50px;
        height: 50px;
        width: 50px;
      }
      .icon-80px {
        font-size: 80px;
        height: 80px;
        width: 80px;
      }
       
       
      scss:
      $base-color: #036;
      @for $i from 1 through 3 {
        ul:nth-child(3n + #{$i}) {
          background-color: lighten($base-color, $i * 5%);
        }
      }
      css:
      ul:nth-child(3n + 1) {
        background-color: #004080;
      }
      ul:nth-child(3n + 2) {
        background-color: #004d99;
      }
      ul:nth-child(3n + 3) {
        background-color: #0059b3;
      }
       
       
      1. scss:
      2. @function scale-below($value, $base, $ratio: 1.618) {
      3. @while $value > $base {
      4. $value: $value / $ratio;
      5. }
      6. @return $value;
      7. }
      8. $normal-font-size: 16px;
      9. sup {
      10. font-size: scale-below(20px, 16px);
      11. }
      12. css:
      13. sup {
      14. font-size: 12.36094px;
      15. }
  7. 数值类型
    sass中的数值类型包括以下几种:数值,字符串,颜色,List, Map,布尔值,null及函数

    • 数值包含数字和单位,sass的强大之处在于支持带单位的运算,例如:
       
       
      @debug 1in + 6px; // 102px or 1.0625in
    • list和map的用法举例:
       
       
      $prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms);
      @function prefixes-for-browsers($browsers) {
        $prefixes: ();
        @each $browser in $browsers {
          $prefixes: append($prefixes, map-get($prefixes-by-browser, $browser));
        }
        @return $prefixes;
      }
      @debug prefixes-for-browsers("firefox" "ie"); // moz ms

获取隐藏元素的宽度

问题描述

如果DOM元素的fu’yu是被隐藏的(display: none),那么无论使用DOM的接口,还是jquery的接口来获取该元素的宽度,得到的结果始终是0. 例如:

 
 
<div id="node">
  <p>
    hello world
  </p>
</div>
 
 
#node {
    display: none;
}
 
 
alert($('#node p').width());

解决方法

在过去元素的宽度之前,临时修改元素的display为block,获取之后再讲其设置回none

例如:

 
 
function get_width(obj) {
  var width = 0;
  obj.parent().css('display', 'block');
  width = obj.width();
  obj.parent().css('display', 'none');
  return width;
}
alert(get_width($('#node p')));

给jquery添加一个函数

参考StackOverflow ,Tim Banks给jquery添加了一个函数,用来获取隐藏元素的宽度和高度信息。

 
 
(function ($) {
$.fn.getHiddenDimensions = function (include_margin) {
    var $item = this,
    props = { position: 'absolute', visibility: 'hidden', display: 'block' },
    dim = { width: 0, height: 0, innerWidth: 0, innerHeight: 0, outerWidth: 0, outerHeight: 0 },
    $hiddenParents = $item.parents().addBack().not(':visible'),
    includeMargin = (include_margin == null) ? false : include_margin;
    var oldProps = [];
    $hiddenParents.each(function () {
        var old = {};
        for (var name in props) {
            old[name] = this.style[name];
            this.style[name] = props[name];
        }
        oldProps.push(old);
    });
    dim.width = $item.width();
    dim.outerWidth = $item.outerWidth(includeMargin);
    dim.innerWidth = $item.innerWidth();
    dim.height = $item.height();
    dim.innerHeight = $item.innerHeight();
    dim.outerHeight = $item.outerHeight(includeMargin);
    $hiddenParents.each(function (i) {
        var old = oldProps[i];
        for (var name in props) {
            this.style[name] = old[name];
        }
    });
    return dim;
}
}($));
alert($('#node p').getHiddenDimensions().width);

在jsFiddle上试一试 ->

Javascript中的DOM节点类型

Node类型

  • node.nodeType:
    • Node.ELEMENT_NODE(1);
    • Node.ATTRIBUTE_NODE(2);
    • Node.TEXT_NODE(3);
    • Node.CDATA_SECTION_NODE(4);
    • Node.ENTITY_PREFERENCE_NODE(5);
    • Node.ENTITY_NODE(6);
    • Node.PROCESSING_INSTRUCTION_NODE(7);
    • Node.COMMENT_NODE(8);
    • Node.DOCUMENT_NODE(9);
    • Node.DOCUMENT_TYPE_NODE(10);
    • Node.DOCUMENT_FRAGMENT_NODE(11);
    • Node.NOTATION_NODE(12);
  • node.nodeName: 标签名
  • node.childNodes[0]  node.childNodes.item(0);
  • node.childNodes.length;
  • node.parentNode;
  • node.nextSibling;
  • node.previousSibling;
  • node.firstChild;
  • node.lastChild;
  • node.appendChild(newNode);
  • node.insertBefore(newNode);
  • node.replaceChild(newNode, oldNode);
  • node.removeChild(node);
  • node.cloneNode(true//深复制)

HTMLDocument类型

  • document.nodeType = 9
  • document.nodeName = “#document”
  • document.nodeValue = null
  • document.parentNode = null
  • document.ownerDocument = null
  • document.firstChild === document.childNodes[0] === document.documentElement 都指向<html>元素
  • document.body指向<body>元素
  • document.head
  • document.charset
  • document.URL;
  • document.title;
  • document.domain;
  • document.getElementById();
  • document.getElementByClassName();
  • document.getElementsByTagName();
  • document.getElementsByName();
  • document.images;
  • document.anchors;
  • document.links;
  • document.forms;
  • document.createElement(‘div’)
  • document.activeElement: 指向获得焦点的元素
  • document.readyState // loading or complete

Element类型

var elem = document.getElementById(‘elem_id’);

  • elem.nodeType = 1
  • elem.nodeName 为元素的标签名
  • elem.nodeValue = null
  • elem.parentNode 为document或者Element
  • elem.nodeName === elem.tagName
  • elem.getAttribute(“id”)
  • elem.setAttribute(“id”, “new_id”)
  • elem.attributes.getNamedItem(‘id’)
  • elem.attributes.removeNamedItem(‘id’)
  • elem.attributes.setNamedItem(new_attr)
  • elem.getElementsByTagName()
  • elem.dataset // data- 前缀自定义的属性及属性值
  • elem.innerHTML // 元素的内容(所有子节点HTML)
  • elem.scrollIntoView() //将元素滚动至可见视图中
  • elem.style.width
  • elem.style

Text类型

<div>hello world</dev>

var text_node = div.firstChild;

var text_node = document.createTextNode(text);

  • text_node.nodeValue = text_node.data = ‘hello world’
  • text_node.appendData(‘string’);
  • text_node.deleteData(offset, count);
  • text_node.insertData(offset, text);
  • text_node.replaceData(offset, count, new_text);
  • text_node.splitText(offset);
  • text_node.substringData(offset);
  • text_node.length = text_node.data.length = text_node.nodeValue.length;
  • text_node.parentNode.normalize() // 将两个子文本节点合并

Comment类型

<div id=’mydiv’><!– comment –></div>

var mydiv = document.getElementById(‘mydiv’);

var comment = mydiv.firstChild;

var comment = document.createComment(‘comment’);

  • comment类型和Text类型继承自同一个基类,拥有除splitText之外Text的所有属性和方法

Attr类型

elem.attributes中的节点

var attr = document.createAttribute(attr_name);

  • attr.nodeType = 11
  • attr.nodeName 属性名
  • attr.nodeValue 属性值
  • attr.parentNode = null
  • elem.setAttributeNode(attr);

[转]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).

阅读原文

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>
    );
  }
}

 

迁移宁强在线步骤

配置ssh

#mkdir /root/.ssh && cp id_rsa* /root/.ssh/

下载配置脚本

#git clone git@git.oschina.net:wangsen/auto_conf_fc.git

安装基础软件

#cd auto_conf_fc && bash -x ./conf.sh

安装web软件

#yum install net-tools httpd python-django                                   
#yum install python python-pip  python-devel  python-wsgi  mod_wsgi   mariadb-server python-mysql mariadb-devel.x86_64 MySQL-python python-html5lib

克隆网站代码

#cd /var/www/html && git clone git@git.oschina.net:wangsen/TownInfo-.git
#mvTownInfo- nqys
#cd nqys && cp httpd.conf /etc/httpd/conf/httpd.conf

安装pip

#cd ~/auto_conf_fc/nqzx/ && tar xzvf pip-1.5.6.tar.gz && cd pip-1.5.6 && python get-pip.py

安装Python包

# cds && pip install -r ../requirements.txt

启动数据库

#vim /etc/my.cnf
# ## character_set_server=utf8
# systemctl enable mariadb
# systemctl restart mariadb
# mysqladmin -u root password
# mysqladmin -u root -p create nqysdb
# mysql -u root -p
##GRANT ALL PRIVILEGES ON nqysdb.* TO 'django_user'@'localhost' IDENTIFIED BY 'passw0rd'; 

替换django和registration

# cd /usr/lib/python2.7/site-packages && rm -rf django
# git clone git@git.oschina.net:wangsen/django.git
# git clone git@git.oschina.net:wangsen/registration.git

解决头像上传问题

# cd ~/auto_conf_fc/nqzx && tar xzvf Imaging-1.1.7.tar.gz
# yum install zlib zlib-devel libjpeg libjpeg-devel freetype freetype-devel
# cd Imaging-1.1.7 && vim setup.py
修改setup.py:
TCL_ROOT = "/usr/lib64/"
JPEG_ROOT = "/usr/lib64/"
ZLIB_ROOT = "/usr/lib64/"
TIFF_ROOT = "/usr/lib64/"
FREETYPE_ROOT = "/usr/lib64/"
LCMS_ROOT = "/usr/lib64/"
# pip uninstall pillow PIL
# python setup.py install

导入备份数据库

  1. 备份数据库
# mysqldump -u root -p nqysdb > nqzx.db
  1. 导入数据库
# mysql -u root -p nqysdb < nqzx.db

启动web服务

# cds && ../manage.py collectstatic
# ../manage.py syncdb
# service httpd restart

JQuery 摘要

选择符与遍历

  1. $(): $函数接受css选择符作为参数,充当一个工厂函数,返回对应元素的JQuery对象。

  2. 3种基本的选择符:

    • 标签名 $(‘p’)
    • ID $(‘#myid’)
    • 类 $(‘.myClass’)
  3. 子元素组合符>: $(‘#myid > li’)选择id为myid的元素的所有列表项(li).

  4. 否定式伪类: $(‘#myid li:not(.myClass)’)选择id为myid的元素中不属于myClass类的所有列表项(li).

  5. 属性选择符$(‘img[alt]’): 选择所有带有alt属性的img元素.

  6. 属性选择符+类正则匹配:

    • $(‘a[href^=”mailto:”]’): 选择所有URL以mailto:开头的超链接.
    • $(‘a[href$=”.pdf”]’): 选择所有URL以.pdf结尾的超链接.
    • $(‘a[href*=”rose”]’): 选择所有URL中包含rose的超链接.
  7. 自定义选择符:

    • $(‘li:eq(1)’): 选择第二个列表项
    • $(‘li:odd’): 选择奇数的列表项
    • $(‘li:even’): 选择偶数的列表项
    • $(‘li:nth-child(odd)’): 选择从父元素的第一个元素开始计算的所有奇数列表项
    • $(‘li:contain(string)’): 选择包含string的列表项
  8. 表单选择符:

    • :input
    • :button
    • :checked
    • :selected
    • :enabled
    • :disabled
  9. filter: 过滤器,可接选择器和lambda函数

    • $(‘li’).filter(‘:even’)
    • $(‘li’).filter(function(){return this.hostname && this.hostname!=location.hostname})
  10. next,nextALL,prev,prevAll,andSelf,siblings:选择所选元素的下一个元素等

  11. 连缀(chaining)

    • $(‘tr:contains(Henry)’).parent().find(‘td:eq(1)’).addClass(‘myClass’).end().find(‘td:eq(2)’).addClass(‘myClass’);
  12. $(‘#myId’).get(0) 等价于 $(‘myId’)[0]

事件

  1. window.onload vs $(document).ready

    • window.onload 是在页面的全部元素都下载好了之后才能执行,而$(document).ready()则是在DOM树准备好就可以执行了。
    • window.onload只能指定一个函数,而$(document).ready()指定的所有函数都会按顺序执行。
    • $(document).ready(func)可以简写为$(func);
  2. bind(event, func)函数可以为DOM节点绑定事件,以及事件发生时所执行的函数。event可以是:

    • blur
    • change
    • click
    • dbclick
    • error
    • focus
    • keydown
    • keypress
    • keyup
    • load
    • mousedown
    • mousemove
    • mouseout
    • mouseover
    • mouseup
    • resize
    • scroll
    • select
    • submit
    • unload
  3. toggle(func1, func2): 单击时轮流执行func1和func2

  4. toggleClass(“someclass”): 单击时轮流添加或删除someclass.

  5. 事件捕获和事件冒泡:事件捕获是从父节点开始将事件传递给子节点,而事件冒泡则正好相反。JQuery采取事件冒泡的策略。

  6. 事件对象:事件发生时执行的函数可以把事件对象作为参数。

    • event.target属性:保存发生事件的目标元素
    • event.stopPropagation(): 阻止事件继续冒泡
    • event.preventDefault(): 阻止事件的默认操作
  7. $(event.target).is(): 接收一个选择符表达式作为参数,并验证JQuery对象是否满足它。

  8. unbind(): 移除事件处理

  9. 事件命名空间:bind(‘click.sometag’, func) 可以在unbind的时候只解绑指定名字的事件。

  10. trigger(): 使用javascript去触发某个事件

效果

  1. .css(): 参数可以是(“attr”, “value”),也可以是({“attr”: “value”, “attr”: “value”}),修改JQuery对象的css
  2. .hide(): 将JQuery对象的内联css属性”display”设置为”none”
  3. .show(): 将JQuery对象的内联css属性”display”恢复成hide之前的值。hide和show可以传入速度作为参数:”slow”, “normal”, “fast”
  4. fadeIn()和fadeOut(): 淡入和淡出,可传入速度参数。
  5. slideDown()和slideUp(): 滑下和滑上,可传入速度参数。
  6. toggle(): 相当于轮流执行show()和hide()方法,可传入速度参数。
  7. slideToggle(): 相当于轮流执行slideUp()和slideDown(),可传入速度参数。
  8. animate(): 自定义动画。有两种传入参数的方式:
    • ({“attr”: “value”, “attr”, “value}, speed, easing, func):第一个参数是css属性,第二个是速度,第三个是缓动,第四个是动画完成后的回调函数。
    • ({“attr”: “value”, “attr”: “value”}, {duration: “value”, easing: “value”, complete: functiong(){}, queue: true…})
  9. outerWidth(true): 返回width+padding+border+margin的值
  10. outerWidth(), outerWidth(false): 返回width+padding+border的值
  11. innerWidth(): 返回width+padding的值
  12. outerHeight(), innerHeight()与outerWidth(), innerWidth()类似
  13. animate()中指定多个css属性变化可以让动画并发,而用多个效果方法如animate,fadeIn等连缀则可以让动画排队显示。设置queue参数为false则可以让该动画不用排队。
  14. css()方法不属于效果方法,不能排队,但可以用queue()方法将其加入队列,例如:
    • .fadeTo().queue(function(next){$(xxx).css(); next();})
  15. JQuery为每个效果方法都提供了回调函数,可以用来让多个JQuery对象的动画排队执行。

操作DOM

AJAX

apache配置https服务

1、创建自己签名的证书

         #创建CA签名的证书,需要用到openssl
         yum install openssl    
         #创建key   
         openssl genrsa -des3 -out server.key 1024     
         #创建csr(证书签发请求) 
         openssl req -new -key server.key -out server.csr      
         #生成自己签名的证书
         openssl x509 -req  -in server.csr  -signkey server.key -out server.crt       
         #安装证书
         cp  server.crt /etc/ssl/certs
         cp  server.key /etc/ssl/private

2、编辑ssl配置文件

         vim /etc/httpd/conf.d/ssl.conf
         SSLEngine on
         SSLCertificateFile    /etc/ssl/certs/server.crt
         SSLCertificateKeyFile /etc/ssl/private/server.key

3、重启apache服务

        #systemctl restart httpd

mysql数据库及django用户名启用中文的方法

mysql数据库启用中文

在mysql的配置文件/etc/my.cnf的[mysqld]下加入

character_set_server=utf8

Django启用中文用户名

Django默认只能以字母、数字、下划线组成用户名,修改检验用户名的正则表达式可以绕过这一规则:

/usr/lib/python2.7/site-packages/django/contrib/auth/models.py:

class AbstractUser(AbstractBaseUser, PermissionsMixin):
...
validators.RegexValidator(re.compile('^[\w.@+-]+$'), _('Enter a valid username.'), 'invalid')
...

把正则表达式从^[\w.@+-]+$ 改为 ^[\S.@+-]+$即可

"