2013年12月

零JQ筆記 | jquery-ui

文件結構:
external/jquery.js
jquery-ui.css
jquery-ui.js
jquery-ui.structure.css :特效、背景、邊框等
jquery-ui.theme.css :佈局 架構:

structure.css + theme.css == jquery-ui.css

包含项:

UI Core :UI核心

Core
Widget
Mouse
Position

Interactions :UI交互

Draggable:拖拽
Droppable :拖动释放
Resizable:改变层大小
Selectable:选择元素,通过鼠标拖动,划过选中
Sortable:排序交互

Widgets :控件

Accordion
Autocomplete
Resizable
...

Effects:UI特效

Effects Core
Blind Effect
Bounce Effect
...
多种效果; http://www.w3cschool.cc/jqueryui/api-easings.html
$('div').animate({'width':'100px'},1000,'特效easeOut...')

jqui里removeClass,与addClass也支持特效;

$('div').removeClass('box',1000,'easeInQuad')

并且也支持颜色

$('#div').animate({'backgroundColor':'blue'},1000)

如:show('blind',1000)

See the Pen VembrW by elmok (@elmok) on CodePen.


<script async src="//assets.codepen.io/assets/embed/ei.js"></script>

直接effect()做一次运动特效;

$('div').effect('linear',1000); 

指定中心点运动方向 direction(left|right|up|down)

$('div').toggle('blind',{direction:'left'},1000)



交互:http://www.w3cschool.cc/try/tryit.php?filename=jqueryui-api-draggable

API分為三部分:1、配置參數;2、方法;3、自定義事件


以draggable為例


1、option/Method

$('#div').draggable({
    axis:'x',
    cursor:'crosshair',
    cursorAt:{left:0,top:0},
    handle:'p'
}) //初始化

//如在以上有初始化狀態的元素下:可有:
$('#div').draggable('destroy')  //銷毀
$('#div').draggable('disable')  //禁用
$('#div').draggable('enable')   //啟用
$('#div').draggable('instance')  //獲取對象
$('#div').draggable('widget')  //获取对像 做组件的链式操作

2、Events自定義事件

$('#div2').draggable({
    axis:'x',
    create: function () {
        alert(1); //一上來初始化調1
    },
    start: function () {
        alert(2); //按下後調2
    }
})

draggable與sortable組合使用: http://jqueryui.com/draggable/#sortable


Mothed方法兩種寫法

//寫法一:
$('div').draggable('destroy')

//傳統寫法二:
var obj = $('div').draggable('instance') //得到組件對象
obj.disable()//對象下調方法 ;

Event自定義事件兩種寫法


//寫法一:
$('#div2').draggable({
    axis:'x',
    create: function () {
        alert(1); //一上來初始化調1
    },
    start: function () {
        alert(2); //按下後調2
    }
})

//寫法二:
$('#div2').on('dragcreate', function () {
    alert(2)
})

refresh

<input type="button" value="add"/>
<div id="div1">
    <p>aaa</p>
    <div>111</div>
    <p>bbb</p>
    <div>222</div>
    <p>ccc</p>
    <div>333</div>
</div>

當add即時增加高度時,必須使用refresh參數才能使用高度自動變高而不是出現滾動條;

$('#div1').accordion() //調用手風琴選項卡方法

$('input').click(function () {
    var html = $('#div1').find('div').first().html()
    $('#div1').find('div').first().html(html+'1 <br />')
    $('#div1').accordion('refresh')
})

UI控件自行查看API



UI核心

选择器
:data()
:focusable()
:tabbable()
方法
disableSelection()
enableSelection()
focus()
scrollParent()
jQuery.ui.keyCode
$('div').slice(0,2).data('name','elmok'); //給選中元素添加外部數據
$('div:data(name)').css('background','red') //使用外部數據設css

$('body').children(':focusable').css('background','red') //獲取有光標的
$('body').children(':tabbable').css('background','red') //獲取能接收tab鍵元素的;

$('div').disableSelection() //禁止選擇
$('div').enableSelection()  //開啟選擇

//1s後激活光標位置
$('input').focus(1000, function () {
    this.style.background = 'red'
}) 

//即父級必須具備滾動條才可選中,不一定要有滾動,但需具備,比如設置overflow:hidden,就不具備了;所以是overflow:auto;
$('p').scrollParent().css('background','red') 


$(document).on('keydown', function (ev) {
    if (ev.keyCode == $.ui.keyCode.ENTER) { // ev.keyCode == 13
        alert('回車')
    }
})

position()

<div id="div1">
    <div id="div2"></div>
</div>
    $(function () {
        $('#div2').position({
            my: 'left bottom', //div2內層基點居中
            at: 'right bottom',//div1外層基點
            of: '#div1'//div1外層指定元素
        })
    })

<h2>Widget Factory</h2>

//比如,創建一個方法:testProgressBar(),調用是使用下面這種形式:

$('#div1').testProgressBar({value: 20});

//所以架子應該是:
$.widget('eonon.testProgressBar'{ //不能直接寫,防止衝突 需要加命名空間;
    options:{},
    _create:function(){}
})

稍微豐富點

    $('#div1').testProgressBar({
        value: 20,ut:'px',color:'red'       //value,ut,color作為配置參數
    });


$.widget('eonon.testProgressBar'{ //不能直接寫,防止衝突 需要加命名空間;
    options:{
              value: 0,
              ut: '%',
              color:'pink'
},
    _create:function(){
            var progress = this.options.value + this.options.ut;
            this.element.html(progress).css('color',this.options.color) //this.element == div1
}
})

$.widget(方法名,json擴展)


http://api.jqueryui.com/mouse/


$.ui.mouse指繼承方法,如果不是自定義事件則可不寫


http://api.jqueryui.com/jQuery.widget/#method-_create


自定義事件作為options參數接收;_create:function(){初始化};_mouseUp:function(){接收}


_mouseUp需要在_create裏初始化this._mouseInit()




$(function () {
    $.widget('eonon.testProgressBar', $.ui.mouse , { //不能直接寫,防止衝突 需要加命名空間;  
        options: { //收集配置參數
            value: 0,
            ut: '%',
            color:'pink',
            customMouseUp: function () {} //自定義事件即作為options的屬性,再使用_mouseUp這個默認up方法調用即可
        },
        _create: function () {
            var progress = this.options.value + this.options.ut;
            this.element.html(progress).css('color',this.options.color) //this.element == div1
            this._mouseInit()
        },
        _setOption: function (a,b) { //進行設置操作時走這裏
            //alert(a) //value
            //alert(b) //80

            if(a == 'value'){
                this.element.html(b+this.options.ut)
            }
        },
        aaa: function () { //共用方法,
            alert('aaa')
        },
       _aaa: function () { //帶下劃線是私有方法,外部找到;
            alert('_aaa')
        },
        _mouseUp: function () {
            //alert('_mouseUp')
            this.element.trigger('m.customMouseup')
            this.options.customMouseUp()
        }
    });

    $('#div1').testProgressBar({
        value: 20,ut:'px',color:'red'//value作為配置參數
        ,customMouseUp: function () { //自定義事件;
            alert('觸發了參數定義的mouseUp')
        }
    });

//調用自定義方法:

    $('#div1').on('m.customMouseup', function () {
        alert('on帶up時觸發')
    })
/*
$('#div1').testProgressBar('aaa') //正常彈出
$('#div1').testProgressBar('_aaa') //無法彈出 ,私有
*/

    })

svg入門

<h2>.svg文件架子</h2>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
    <circle cx="100" cy="100" r="40" fill="red"></circle>
</svg>

//html页面引用方式
图片: <img src="svg.svg" alt=""/>
DIV: <div style="background:url(svg.svg);height: 200px;width: 200px;"></div>
IFRAME: <iframe src="svg.svg" frameborder="0"></iframe>

//直接引用到html
<svg  xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <circle cx="100" cy="100" r="40" fill="red"></circle>
</svg>

<h2>circle</h2>

<circle cx="100" cy="100" r="40" style="fill:white;stroke:black;stroke-width:5"></circle>

cx:中心點到x的距離 ;
cy:中心點到y的距離 ;
r:半徑
fill:顏色/transparent/none;
stroke:邊框顏色
stroke-width:邊框粗細
可分開寫=,也可在style裏寫;

<h2>rect</h2>

<rect width="200" height="200" x="100" y="100" fill="red" rx="30" ry="50"></rect>

x:中心點到x的距離 ;
y:中心點到y的距離 ;
rx:矩形產生圓角
ry:矩形產生圓角
<h2>line</h2>

<line x1="50" y1="50" x2="200" y2="300" stroke="black" stroke-opacity="0.5"></line>

stroke-opacity:設置透明度
fill-opacity:設置透明度
<h2>g</h2>
g標籤表示分組,組可,可對整體元素操作共有屬性設置,也可加id屬性,移動需使用transform = 'translate(0,0)'這種

<g stroke-width="3" stroke="red" transform="translate(200,200)"> <!--移到中心点 -->
<circle r="30" ></circle>
<circle r="40" ></circle>
<circle r="50" ></circle>
<circle r="60" ></circle>
<circle r="70" ></circle>
</g>

<h2>text</h2>

<text x="200" y="208" font-size="20" text-anchor="middle">科科科</text>

text-anchor:(start | middle | end) middle即把基準中心點由左邊移動中間;
文字默認y軸方向會有2px下沉,所以垂直居中時需要+(fontSize/2 - 2);

<h2>image</h2>

<image x="150" y="148" width="100" height="103" xlink:href="img/main.png">

<h2>创建标签</h2>
createElementNS 表示必须指定创建的命名空间,接收2参数 document.createElementNS(命名空间,标签)

var svgNS = "http://www.w3.org/2000/svg"
function createTag(tag,objAttr){
    var _tag = document.createElementNS(svgNS,tag)
    for(var attr in objAttr){
        _tag.setAttribute(attr,objAttr[attr]);
    }
    return _tag;
}

<h2>实例:百度图谱</h2>

思路:1、創建中心圓,方法addTag;
2、創建周邊圖,方法addOtherTag;
3、外部獲取數據data = {[中心節點數據,text文本],[其他節點數據:位置x/y值,text文本]}
4、其他位置假設繞中心點360平均分配:則個數是circleNum = 9;每個角度是:angleNum = 360/circleNum;通過三角函數即可算出;5、最後sMove方法做彈性運動,屬性值是:r半徑

var svgNS = "http://www.w3.org/2000/svg"/*命名空间*/
var _parent = document.getElementById('div1')
var _centerX = _parent.offsetWidth / 2; //中心点 注意此处不是offsetLeft与top
var _centerY = _parent.offsetHeight / 2; //中心点

var circleNum = 9; //其他circle個數
var angleNum = 360/circleNum; //每個的角度
var centerR = 150;

var otherData = [];

for(var i=0;i<circleNum;i++){
    var x = Math.cos(i * angleNum * Math.PI / 180) * centerR + _centerX; //郵角度算弧度:* Math.PI /180
    var y = Math.sin(i * angleNum * Math.PI / 180) * centerR + _centerY;
    otherData.push({x: x, y: y, text: i}); //放到數組
}

var data = { //外部獲取數據
    centerNode: {
        text: '斯巴鲁'
    },
    otherNode: otherData
}

function createTag(tag, objAttr) {
    var _tag = document.createElementNS(svgNS, tag)
    for (var attr in objAttr) {
        _tag.setAttribute(attr, objAttr[attr]);
    }
    return _tag;
}
function addTag() { //中心圓
var _svg = createTag('svg', {'xmlns': svgNS, 'height': '100%', 'width': '100%'})

for (var i = 0; i < data.otherNode.length; i++) {
addOtherTag(data.otherNode[i], _svg)
}

var _g = createTag('g', {'style': 'cursor: pointer'})
var _circle = createTag('circle', {
'cx': _centerX,
'cy': _centerY,
'r': 40,
'fill': '#fff',
'stroke': 'red',
'stroke-width': 1
})
var _text = createTag('text', {'x': _centerX, 'y': _centerY + 7, 'text-anchor': 'middle', 'font-size': 18})
_text.innerHTML = data.centerNode.text

_g.appendChild(_circle)
_g.appendChild(_text)
_svg.appendChild(_g)
_parent.appendChild(_svg)
}

function addOtherTag(otherAttr, _svg) { //其他圓

    var _g = createTag('g', {'style': 'cursor: pointer','class':'lineStyle'})
    var _line1 = createTag('line', {
        'x1': otherAttr.x,
        'y1': otherAttr.y,
        'x2': _centerX,
        'y2': _centerY,
        'stroke': '#ccc'
    })
    var _line2 = createTag('line', {
        'x1': otherAttr.x,
        'y1': otherAttr.y,
        'x2': _centerX,
        'y2': _centerY,
        'stroke': 'transparent',
        'stroke-width': 5
    })
    var _rect = createTag('rect', {
        'x': (otherAttr.x + _centerX) / 2 - 10,
        'y': (otherAttr.y + _centerY) / 2 - 10,
        'fill': '#999',
        'height': 20,
        'width': 20,
        'rx': 5
    })
    var _text = createTag('text', {
        'x': (otherAttr.x + _centerX) / 2,
        'y': (otherAttr.y + _centerY) / 2 + 8,
        'fill': '#fff',
        'text-anchor': 'middle',
        'font-size': 18
    })

    _text.innerHTML = "?"

    _g.appendChild(_line1)
    _g.appendChild(_line2)
    _g.appendChild(_rect)
    _g.appendChild(_text)
    _svg.appendChild(_g)

    var _g = createTag('g', {'style': 'cursor: pointer','class':'circleStyle'})
    var _circle = createTag('circle', {
        'cx': otherAttr.x,
        'cy': otherAttr.y,
        'r': 30,
        'fill': '#fff',
        'stroke': 'red',
        'stroke-width': 1
    })
    var _text = createTag('text', {
        'x': otherAttr.x,
        'y': otherAttr.y + 7,
        'text-anchor': 'middle',
        'font-size': 18
    })
    _text.innerHTML = otherAttr.text

    _g.appendChild(_circle)
    _g.appendChild(_text)
    _svg.appendChild(_g)

}/* addOtherTag */

function bindTag(){ //方法
    var __line = document.getElementsByClassName('lineStyle')
    var __circle = document.getElementsByClassName('circleStyle')
    for(var i=0;i<__circle.length;i++){
        __circle[i].onmouseenter = function () {
            sMove(this.getElementsByTagName('circle')[0],30,40) /*thid指g标签*/
            var pervLine = this.previousElementSibling;/*上一节点*/
            pervLine.getElementsByTagName('line')[0].setAttribute('stroke','blue')
            pervLine.getElementsByTagName('rect')[0].setAttribute('fill','red')
        }
        __circle[i].onmouseleave = function () {
            sMove(this.getElementsByTagName('circle')[0],40,30)
            var pervLine = this.previousElementSibling;/*上一节点*/
            pervLine.getElementsByTagName('line')[0].setAttribute('stroke','#ccc')
            pervLine.getElementsByTagName('rect')[0].setAttribute('fill','#999')

        }
    }
    for(var i=0;i<__line.length;i++){
        __line[i].onmouseenter = function () {
            this.getElementsByTagName('line')[0].setAttribute('stroke','blue')
            this.getElementsByTagName('rect')[0].setAttribute('fill','red')

            var nextCircle = this.nextElementSibling; /*下一个节点*/
            sMove(nextCircle.getElementsByTagName('circle')[0],30,40)
        }
        __line[i].onmouseleave = function () {
            this.getElementsByTagName('line')[0].setAttribute('stroke','#ccc')
            this.getElementsByTagName('rect')[0].setAttribute('fill','#999')
            var nextCircle = this.nextElementSibling; /*下一个节点*/
            sMove(nextCircle.getElementsByTagName('circle')[0],40,30)
        }
    }

}/*bindTag*/

See the Pen JGRqGX by elmok (@elmok) on CodePen.


<script async src="//assets.codepen.io/assets/embed/ei.js"></script>

<h2>polyline & polygon</h2>

<polyline stroke="#000" stroke-width="1" fill="none" points="50 50,200 300,300 230,250 200"></polyline>

<polygon stroke="#000" stroke-width="1" fill="none" points="50 50,200 300,300 230,250 200"></polygon>

折線,points = '第1座標,第2,第3....',以空格或,隔開,polygon會自動閉合末端

<h2>实例:百度測量</h2>

window.onload = function () {
    var svgNS = "http://www.w3.org/2000/svg"
    var _parent = document.getElementById('div1')

    var _svg = document.getElementById('svg1')
    var _polyline = null;
    var pointsNum = '';

    function createTag(tag, objAttr) {
        var _tag = document.createElementNS(svgNS, tag)
        for (var attr in objAttr) {
            _tag.setAttribute(attr, objAttr[attr]);
        }
        return _tag;
    }

    _svg.onmousedown = function (ev) { //鼠標按下
        var ev = ev || event;
        if (!_polyline) {
            _polyline = createTag('polyline', {
                'fill': 'none',
                'stroke': 'red',
                'stroke-width': '1'
            })
            _svg.appendChild(_polyline);
        }
        var x = ev.clientX - _parent.offsetLeft;
        var y = ev.clientY - _parent.offsetTop;
        if (pointsNum == '') {
            pointsNum = x + ',' + y
        }
        else {
            pointsNum += ',' + x + ',' + y
        }
        _polyline.setAttribute('points', pointsNum)

        var _circle = createTag('circle', {'cx': x, 'cy': y, 'r': 5, 'fill': '#fff', 'stroke': 'red'})
        _svg.appendChild(_circle);
    }
    _svg.onmousemove = function (ev) { //移動時實時改變polyline值
        var ev = ev || event;
        if (_polyline) {
            var x = ev.clientX - _parent.offsetLeft;
            var y = ev.clientY - _parent.offsetTop;
            _polyline.setAttribute('points', pointsNum + ',' + x + ',' + y)
        }
    }
    _svg.oncontextmenu = function () { //右健取消
        _svg.onmousemove = null;
        return false
    }
}

See the Pen yeaWMd by elmok (@elmok) on CodePen.


<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
<h2>Path</h2>

<path d="M50 100L200 200L100 100ZL300 100" stroke="red" fill="none"></path>
<path d="M50 100H200V-200" stroke="red" fill="none"></path>
<path d="M50 100h200v200" stroke="red" fill="none"></path>
<path d="M100 100 A150 100 00 0 1 200 200" stroke="red" fill="none"></path>

d:所有屬性都在d裏設置
M = moveto(M X,Y):起始,一個M表示一組折線
L = lineto(L X,Y):結束,可以多個連接
Z = closepath() :Z前面的即為一組,自動閉合
H = horizontal lineto(H X):水平绘制,指定x坐标 如H200 == L - 负 值往上
V = vertical lineto(V Y):垂直绘制,指定Y坐标
A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线
A:繪製弧形,必須寫7個參數
'A x半徑rx,y半徑ry 角度,弧長(0小1大),方向(0逆1順) 終點x,終點y'


坐标轴为以(0,0)为中心,X轴水平向右,Y轴水平向下。
所有指令大小写均可。大写绝对定位,参照全局坐标系;小写相对定位,参照父容器坐标系
指令和数据间的空格可以省略
同一指令出现多次可以只用一个

<h2>实例:友盟占比图</h2>
http://umindex.com/social
要点:画静态图,分清哪些是外部数据如:arrNum,设置内外两层半径,设置中心点位置,初始化内外坐标点,后期可push进来;设置每块颜色arrColor,注意,圆形设置好基点后,各角度需要使用累加,总360度;

//先写静态,
<path d="M150 150 A100 150 0 0 1 250 150 L225 175A50 50 0 0 0 175 175Z" stroke="red" fill="none"></path>
//再按静态生成动态
    for (var i = 0; i < outerXY.length; i++) {
        var _path = createTag('path', {
            'fill': arrColor[i],
            'd': "M" + outerXY[i].x + " " + outerXY[i].y + ' ' + 'A' + outerR + ' ' + outerR + ' 0 0 1 ' + outerXY[i + 1].x + ' ' + outerXY[i + 1].y + 'L' + interXY[i + 1].x + ' ' + interXY[i + 1].y + 'A' + interR + ' ' + interR + ' 0 0 0 ' + interXY[i].x + ' ' + interXY[i].y
        })
        _svg.appendChild(_path)
    }
}

See the Pen rxMgoL by elmok (@elmok) on CodePen.


<script async src="//assets.codepen.io/assets/embed/ei.js"></script>

JQ 运动要点 animate(step:function(a,b){ console.log(b.pos) }); b.pos表示在一个运动内,此值由0-1变化,可以当基数实现元素运动效果;

#('xxx').animate({
    move:'auto' //可任意填写
},{
    duration:1000,
    easing:swing
    step:function(a,b){
        //b.pos表示运动从0-1基数的变化,可以起到平均分配的一半
    }
})

See the Pen BjLebb by elmok (@elmok) on CodePen.


<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
<h2>animate</h2>

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">

    <rect width="50" height="200" x="100" y="100" fill="red">
        <animate attributeName="width" dur="1" from="50" to="200" fill="freeze"></animate>
    </rect>

</svg>

attributeName:指定运动属性
dur:时间
form:从..
to:到..
fill = freeze:表示保持运动过后的状态;默认会自动跳回初始状态

See the Pen WrGqJx by elmok (@elmok) on CodePen.


<script async src="//assets.codepen.io/assets/embed/ei.js"></script>

git入門

<h2>建個庫</h2>

登錄 -- > New repositories --> 輸入項目名及描述 -- > public 創建readme.md


所以命令都須切換到項目目錄下執行;下載項目

git clone [url]

設置貢獻者

git config --global user.name "elmok1"
git config --global user.email "elmok1@qq.com"

git config --list //顯示更多信息


master:項目 主分支 的默認名:master

[工作区] //工作文件在这里

[暂存区] //过渡,临时存放

[版本区]

git status //查看工作状态

git add [filename或.]       //工作区-->暂存区
git commit -m "这里是注釋"   //暂存区-->版本库

//或
git commit -a -m "这里是注釋"

git log  //操作日記

红色表示[工作区]--[master +2 ~0 -0 !]:表示[工作区]添加2个新文件,0个修改,0个删除


绿色表示[工作区]--[master +1 ~0 -0 !]:表示[暂存区]添加1个新文件,0个修改,0个删除

<h2>對比</h2>

查看差異---[工作区] && [暂存区]之間

git diff

查看差異---[暫存區] && [版本区]之間

git diff --cached
//或
git diff --staged

查看差異---[工作区] && [版本区]之間

git diff master

<h2>撤销</h2>

從[暫存區]-->撤銷到 [工作區]

//當
git add .

//則撤銷回[工作區]
git reset HEAD [filename]

從[版本區]-->撤銷到 [工作區],即還原文件內容

git checkout -- [filename]

撤銷一次提交

//當要提2文件,只提了一個
git add fname1.js
git commit -m "fname1.js and fname2"  

//把遺漏的add
git add fname2.js

//再合並提交即可
git commit -m "fname1.js and fname2" --amend //把上一次的提交撤銷並到撤銷的與這次提交合併到一起提交

<h2>刪除</h2>

当在[工作区]删除一个文件时,可以使用此命令删除[暂存区]的文件;

git rm [filename]

當文件已放入[暫存區],刪除需兩個區同時刪

git rm -f [filename]

[工作区]文件可以存在,要刪除[暫存區]文件

git rm --cached test.txt

<h2>恢復</h2>

针对文件恢复:[commitID]可通過git log查找

git checkout [commitId] [filename] 

針對版本恢復

get reset --hard [commitID]

//或
get reset --hard HEAD^      //回到以前的版本;向下
get reset --hard HEAD~2     //回到跳两个以前的版本;向下

reflog:打印最近操作行為,可找之前版本的commitID

git reflog

//再即可
get reset --hard [commitID]

<h2>同步到远程仓库</h2>

確保github賬號同步

git remote //遠程倉庫的名字 origin默認名
git remote -v //查看對應地址
git push origin master // 同步名字,同步分支

多人協作時添加權限


+ New collaborators 輸入賬號elmok2


切換另一賬號elmok2


登錄後,https://github.com/watching,即可

git clone https://github.com/elmok/drag

之後流程一致

git status
git add .
git commit -m "elmok2 change"
git push origin master

切換用戶elmok,更新本地

git fetch //只是獲取,但不合並 【建議】
或
git pull  //獲取後自動合並

<h2>多人協作解決衝突</h2>

產生問題,未先更新直接修改易發生衝突,出現衝突時代碼無法提交


所以需要先獲取最新代碼,再與本地對比

git fetch //只是拉取,但不合並
git diff master origin/master //對比 git diff 本地 遠程,即可打印區別
git merge origin/master  //合並後需要手動解決衝突

//解決衝突後再手動提交即可
git commit -a -m "update"
git push origin master

<h2>當無權限時</h2>

1、fork


github.com fork後,即生成https://github.com/elmok2/drag

git clone https://github.com/elmok2/drag

修改後提交本地[版本庫]

git commit -a -m "fixed bug"
git push origin master

2、在github上pull request


elmok2: new pull request -- > create pull request --> "留言" --> 確認即可


elmok1: pull request --> merge pull request --> 確認合併


回覆留言時,選中留言,按r即可引用


<h2>Git分支</h2>

git branch     //查看分支
git branch new1  //創建分支,當創建分支後,所有狀態都為創建時的狀態,如果在不同的分支上修改不會影響這裏;
git checkout new1  //切換分支

//或一步創建及切換分支
git checkout -b new2    

切換到new1,並修改代碼

1.js
var a = 0;

git checkout new1
//之後提交
git commit -a -m "new1 change"

//new1與master合並
git checkout master //注意,運行這裏後,工作區的代碼也會還原,即不會有var a = 0; 這句
//再運行合並
git merge new1   //即master分支下也有var a = 0;

切換到new2

git checkout new2  //加var b = 0;
git commit -a -m "new2 change" //提交

//切換master
git checkout master
git branch --merged //查看我們當前master下面所合並的分支;如new1合併了即會列出
git branch --no-merged //未與master合並的分支

git branch -d new1 //new1已經合併,可以刪除

//假設
git branch -d new2 //失敗因為未合併,所以不能刪除
//所以
git branch -D new2 //大寫D,強制刪除未合併分支

場景:修改代碼,不同分支上修改相同部分,master 及 new1兩分支上分別提交

git checkout master
git commit -a -m "master change" //master 上有版本c6
git checkout new1
git commit -a -m "new1 change" //new1上有版本c7

需要做一個c8版本,先把c6與master合並變為c8

git checkout master  //切換主分支
git merge new1 //merge new1 時出現衝突
git status  //查看衝突文件
//回到工作區文件解決沖突,之後再提交

git commit -a -m "c8"

//後續可以查看分支合併情況
git branch --merged
//已合併且不需要維護的可刪除
git branch -d new1

當開多個分支時,合並時使用git merge,如果有衝突,通過git status列出,再手動去工作區解決衝突,之後再提交即可


<h2>github上的分支</h2>

git branch n1
git checkout n1
git add .
git commit -m "n1 change"
git push origin n1

也可以直接在github上创建分支


branch 输入 n2(在哪个分支上则先切换到哪个分支)


contributors:協作人員


release:標籤,即不同版本;

git tag v1.0
git tag //查看
git push origin v1.0

之後在github是release即可下載v1.0版本;也可以release是直接 Draft a new release,創建一個版本


watch:關注;當有更新時即會提示


<h2>github上创建組織</h2>

+ New organization -- >選擇組織參與人,發起請求,完成;


<h2>github創建博客</h2>

http://jquery.github.io/


https://pages.github.com/


+ New repository -- > Owner Repository name [這裏必須與前面的名字一致]如:Owner為:elmok; 則name:elmok.github.io


勾選:intialize this repository with a README


Add:wordpress (下面那些也可不用設置了,直接本地clone後wordpress上傳即可)


Settings -- > 拉到最下面 AutoMatic Page Generator,自動生成網頁,可能有不同


填寫title及tag等


選擇主題--->發布


elmok.github.io即可


注:如發現404,請稍等,或檢查郵箱是否通過驗證


<h2>git資源</h2>

<a href="http://git.oschina.net/progit/
" target='_blank'>http://git.oschina.net/progit/


http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

Angularjs入門

angularJs资源
http://www.angularjs.org/
https://www.github.com/angular/
http://www.angularjs.cn/
http://www.ngnice.com/
http://woxx.sinaapp.com/
angularJs下载
http://www.bootcdn.cn/angular.js/
npm install angular

以下走示例仅基于angular1.3.0,高版本不兼容

架子

function Aaa($scope,$rootScope){ //$rootScope全局 ,函数的形参
    $scope.name = 'hello' /* M */
    $rootScope.age = 20; //$scope,只会有Aaa起作用
}}            
<div ng-controller="Aaa" ng-app>
    <p>{{name}}</p>
    <p>{{age}}</p>
</div>

angularJs的MVC方式

数据的挂载
ng-controller
双大括号表达式

angularJs的作用域

$scope
$rootScope
依赖注入
服务

angularJs的指令系统

ng- 指令; ng-app:初始化;,不写则不会执行;初始化可以写到任何位置,按标签来启动 ; ng-controller :控制器连接桥梁;

angular双向数据绑定

MVVM; 当M(数据)发生改变时,会自动让视图改变,而视图改变,可以让相关的数据改变,
$timeout
ng-click
ng-model

数据影响视图

function Aaa($scope,$timeout){ //注入$timeout
    $scope.name = 'hello' /* M */
    $timeout(function(){
        $scope.name = 'hi' /* M */
    },2000)//改变后视图也改 ;

    $scope.show = function () {
        $scope.name = 'hahahas'
    }
}
<div ng-controller="Aaa" ng-click="show()">  <!-- C -->  <
    <p>
        {{name}}  <!-- V -->
    </p>
</div>

视图影响数据

function Aaa($scope,$timeout){ //注入$timeout
    $scope.name = 'hello' /* M */
    $timeout(function(){
        $scope.name = 'hi' /* M */
    },2000)//改变后视图也改 ;

    $scope.show = function () {
        $scope.name = 'hahahas'
    }
}
<div ng-controller="Aaa">  <!-- C -->
    <input type="text" name="" id="" ng-model="name"/>  <!-- 输入框改东西会影响到p标签里的name,ng-model指的即为数据 ; -->
    <p>
        {{name}}  <!-- V -->
    </p>
</div>

过滤器

currency

$watch

监听数据变化
三个参数
function Aaa($scope,$timeout){ //注入$timeout
    $scope.iphone = {
        money:50,
        num:1,
        fre:10
    }
    $scope.sum = function(){
        return $scope.iphone.money * $scope.iphone.num
    }
    $scope.$watch('iphone.money',function(newVal,oldVal){ 
    //  ('字符串(不加$scope)',function(){} ,true) //第三个参数针对集合监听,注意字符串也必须是集合;
    //  console.log(newVal); //监听时iphone.money改变时触发 ;
    //  console.log(oldVal); //监听时iphone.money改变时触发 ;
    // newVal :新值,
    // oldVal:  旧值
    },true) 


    $scope.$watch($scope.sum,function(newVal,oldVal){
        console.log(newVal); //监听时iphone.money改变时触发 ;
        console.log(oldVal); //监听时iphone.money改变时触发 ;
        $scope.iphone.fre =   newVal>=100?0:10; //当大于100时运费免费
    })
}
<div ng-controller="Aaa">  <!-- C -->
    <input type="text" name="" id="" ng-model="name"/>  <!-- 输入框改东西会影响到p标签里的name,ng-model指的即为数据 ; -->
    <p>
       价格:<input type="text" name="" id="" ng-model="iphone.money"/>
    </p>
    <p>个数:<input type="text" name="" id="" ng-model="iphone.num"/></p>
    <p>费用:<span>{{sum()| currency:'¥' }}</span></p>
    <p>运费:<span>{{iphone.fre | currency:'¥'}}</span></p>  <!-- html里的代码不需要写$scope -->
    <p>总额度:<span>{{sum()+iphone.fre | currency:'¥'}}</span></p>
</div>



angularJs的模块化

angular.module
压缩的问题

angularJs的工具方法

angular.bind :是当于$.proxy,改this指向;
angular.copy :复制
angular.extend : 对象的复制,相当于继承
var m1 = angular.module('myApp',[]);
    m1.controller('Aaa',['$scope',function($scope){  //m1.controller控制器(函数名,函数内容)
        $scope.name = 'hello'
    }])
function show(n1,n2){
    alert(n1)
    alert(n2)
    alert(this)
}
angular.bind(document,show,3)(4)  //改this为document指向;

var a = { name:'hello' },b = { age:20 };
    var c = angular.copy(a)
    var d = angular.copy(a,b) //a把报有值给了b,相当于 b复制了a;
    console.log(d);


var a = { name:'hello' },b = { age:20 };
    var c = angular.extend(a,b)  //相当于把a 、b 都给了a
    console.log(a);  //所以此时 c == a;

angularJs的工具方法

angular.isArray
angular.isDate
angular.isDefined
angular.isUndefined
angular.isFunction
angular.isNumber
angular.isObject
angular.isString
angular.isElement
angular.version
angular.equals
angular.forEach
angular.fromJson/toJson
angular.identity/noop:传什么输出即什么/空函数
angular.lowercase/uppercase :大小写
angular.element:获取元素,相当于$
angular.bootstrap:初始化的一种方式 动态初始化代替ng-app
angular.injector:注册器,主要在内部使用,外部较少使用
function noop(){} //空函数
//可能的作用如下:如果不传可能出问题;
function transformer(transformationFn,value){
    return (transformationFn || angular.identity(value)) ;
}

//不使用ng-app时
document.onclick = function () {
    var _div = document.getElementsByTagName('div')
    angular.bootstrap(_div[0],['myApp1'])
    angular.bootstrap(_div[1],['myApp2']) //分别初始化调用,(目标元素,加载模块)
  //angular.bootstrap(document,['myApp']) //初始化在document上, 想要触发时再触发发;
}

var _div = document.getElementById('div1')
angular.element(_div).css('background','red')

$scope

$scope.$watch
$scope.$apply

angular.module

controller
run
function Aaa($scope) { //不注入$timeout
    $scope.name = 'hello'
    setTimeout(function(){  //使用原生
        $scope.$apply(function () {  //可以监听函数下的数据是否变化,如果有变化就会影响到视图,可以在第三方的库或原生js直接使用;
            $scope.name = 123
        })
    },2000)
}



angularJs的过滤器

currency
number
lowercase/uppercase
json
limitTo
date
orderBy
filter

过滤器扩展部分

可组合使用过滤器
JS中使用过滤器
$scope/$rootScope/$timeout
$filter
    var m1 = angular.module('myApp',[]);  //模块的写法 模块的写法要带出参数
        m1.controller('Aaa',['$scope',function($scope){
            $scope.name = '456456456.0322021'
            $scope.name = 'heoow'
            $scope.name = {'name':'elmok','age':30}
            $scope.name = ['a','b','c']
            $scope.name ='1231235'
            $scope.name = [   //orderBy,针对下面这种形式,数组里json
                {color:'red',age:20},
                {color:'yeloo',age:22},
                {color:'yeloo',age:23},
                {color:'#f9f9f9',age:24}
            ]
        }])
<div ng-controller="Aaa"> 
    {{name | currency:"¥"}}
    {{name | number :2}} //number只加分隔符 有小数情况下只截取前3位 后面参数代表要保留几位小数点;
    {{name | uppercase}}
    <pre>{{name | json}}</pre> //格式化 注意,需要在pre标签里
    {{name | limitTo:2}}  //后面即代表需要截取几位
    {{ name | date:'yyyy-MM-dd HH:mm:ss Z'}}  //Jan 1, 1970
    {{name | orderBy:'age':true}}  //加true 相反排序 
    {{name |filter:'l'}}   //  针对数据中的value值  加true==整个value值匹配,不能字符匹配
    
</div>

自定义过滤器

angular.module
controller/run
filter
var m1 = angular.module('myApp',[]);

//模块对象下的方法filter调用; 创建首字母变大写的过滤器;
m1.filter('filterUppercase',function(){
    return function (str,num) {
        console.log(num); //2,可找到num了,所以可做下一步操作;
        console.log(str);//返回的是传入的
        return str.charAt(0).toUpperCase() + str.substring(1)
    }
})

//使用
m1.controller('Aaa',['$scope','$filter',function($scope,$filter){
/*
    $scope.name = '456456456.0322021'
    $scope.name = 'heoow'
    $scope.name = {'name':'elmok','age':30}
    $scope.name = ['a','b','c']
    $scope.name ='1231235'
    $scope.name = $filter('uppercase')('heoow') //转大写操作;
    $scope.name = $filter('number')('123456') //转大写操作;
    $scope.name = $filter('number')('123456.12312',1) //转大写操作; //后面为限制小数点个数
    $scope.name = $filter('date')('4512312123','hh') //转日期;
*/
    $scope.name = $filter('filterUppercase')('heoow','2')
}])

ng-repeat指令

遍历集合, 通过in的方式遍历每一项, $index :$index每一项返回index
$first :$first 第一项返回true,其它返回false
$middle: $middle,除非第一项与最后一项,其它返真
$last: $last 最后一项返回true,其它返回true;
$even :偶数行返回true,奇数行返回false
$odd :与上相反
ng-repeat-start : 只循环一个li
ng-repeat-end
var m1 = angular.module('myApp',[])
    m1.controller('Aaa',['$scope',function($scope){
        $scope.dataList = [
                'aaa','bbb','ccc'
        ]
    }])
 <li ng-repeat="d in dataList">{{d}}</li> <!-- d 循环中的每一项 -->

表格小例

var m1 = angular.module('myApp',[])
m1.controller('Aaa',['$scope','$filter',function($scope,$filter){
    var oriArr = [
        {name:'red',age:'29'},
        {name:'black',age:'22'},
        {name:'blue',age:'23'},
        {name:'yellow',age:'24'}
    ];;
    $scope.dataList =oriArr;
    $scope.fnSort = function (arg) {
        //函数挂属性:分别有开关,加属性;一次真一次假,
        arguments.callee['fnSort' + arg] = !arguments.callee['fnSort' + arg];
        $scope.dataList = $filter('orderBy')($scope.dataList, arg, arguments.callee['fnSort' + arg]);
        //排序完结果重新赋值
    }
    $scope.fnfilter = function (){
        $scope.dataList = $filter('filter')(oriArr,$scope.filterVal)
    }
}])
<div ng-controller="Aaa">
    <input type="text" name="" id="" ng-model="filterVal"/> <input type="button" value="Search" ng-click="fnfilter()"/>
    <table border="1">
        <tr>
            <th ng-click="fnSort('name')">姓名</th>
            <th ng-click="fnSort('age')">年龄</th>
        </tr>
        <tr ng-repeat="d in dataList">
            <td>{{d.name}}</td>
            <td>{{d.age}}</td>
        </tr>
    </table>
</div>

隔行变色等;

var m1 = angular.module('myApp',[])
m1.controller('Aaa',['$scope',function($scope){
    $scope.dataList = [
        'aaa','bbb','ccc','ddd','eee','ggg'
    ]
}])
<div ng-controller="Aaa">
    <ul>
    <li ng-repeat="d in dataList">{{$index}}</li> <!-- d 循环中的每一项 -->   $index每一项返回index        
        <li class="{{$even ? 'active' : ''}}" ng-repeat="d in dataList">{{$odd}}</li>
        <li class="{{$even ? 'active' : ''}}" ng-repeat="d in dataList">{{d}}</li>
    </ul>
    
    <!--需求,下面的循环,不改变结构-->
    <div ng-repeat-start="d in dataList">{{d}}</div>
    <p>{{d}}</p>
    <div ng-repeat-end>{{d}}</div>
</div>

事件指令

ng-click/dblclick
ng-mousedown/up
ng-mouseenter/leave
ng-mousemove/over/out
ng-keydown/up/press
ng-focus/blur
ng-submit
ng-selected
ng-change
ng-copy
ng-cut
ng-paste
ng-disabled
服务 $interval
ng-readonly
ng-checked
ng-value
ng-bind
ng-cloak
ng-bind-template
ng-bind-html
http://www.bootcdn.cn/angular.js/
ng-non-bindable
var m1  = angular.module('myApp',[]);
m1.controller('Aaa',['$scope',function($scope){
    $scope.name = 'hwoow'
}])
<div ng-controller="Aaa">
    <input type="checkbox" name="" id="" ng-model="aaa"/> <!-- 点击则aaa改为true,所以选中 -->
    <select name="" id="">
        <option value="1">111</option>
        <option value="2" ng-selected="aaa">222</option>

    </select>
    <input type="text" name="" id="" ng-change="bbb='heoo" ng-model="bbb"/>{{bbb}}
    <!--ng-change必须与ng-model相配合才有用-->
    <br/>
    <input type="text" name="" id="" value="sdaflskldfj" ng-copy="ccc='dd'"/>{{ccc}}  <!-- 复制会输出 -->
    <input type="text" name="" id="" value="sdaflskldfj" ng-cut="ccc=true"/>{{ccc}}  <!-- 剪切会输出 -->

    <input type="text" name="" id="" value="sdaflskldfj" ng-paste="ccc=true"/>{{ccc}}

</div>
var m1 = angular.module('myApp', [])
m1.controller('Aaa', ['$scope', '$interval', function ($scope, $interval) {
    var inow = 5;
    $scope.text = inow + 's'
    $scope.isDisabled = true;
    var _t = $interval(function () {
        $scope.text = inow + 's'
        inow--
        if (inow == 0) {
            $interval.cancel(_t)   //清除定时器;
            $scope.text = '可以点击啦'
            $scope.isDisabled = false;
        }
    }, 1000)
}])
<div ng-controller="Aaa">
    <input type="button" value="{{text}}" ng-disabled="isDisabled"/> <!-- 动态修改按钮的状态; -->
    <input type="text" value="{{text}}" ng-readonly="isDisabled"/>
    <input type="checkbox" value="{{text}}" name="" id="" ng-checked="isDisabled"/>     <!-- 选中与不选 中; -->

    <input type="text" ng-value="text"/> <!-- 加上ng后value ,不需要{}  区别不大,推荐所有使用ng-value 提高用户体验 -->
</div>
var m1 = angular.module('myApp',['ngSanitize']) /* 操作html需要下载:angular-sanitize.js */ 
m1.controller('Aaa',['$scope',function($scope){
    alert(123)
    $scope.text = '<h1>hello</h1>'
}])
<div>{{text}},{{text}}</div>
//换个写法;
<div ng-bind-template="{{text}},{{text}}"></div>
<div ng-cloak>{{text}}</div> <!--  相当于未解析完时标签是display:none;,解析完再显示;-->
<div ng-non-bindable="">{{text}}</div>  <!-- 不想被解析时; -->

css操作

* ng-class
* ng-style
* ng-href
* ng-src
* ng-attr-(suffix) //通用写法;
var m1 = angular.module('myApp',[]) /* 操作html */
m1.controller('Aaa',['$scope',function($scope){
    $scope.text = '<h1>hello</h1>';
    $scope.style = "{color:'red',background:'#f3f3f3}'"
    $scope.sClass={red:true,yellow:true}
    $scope.url="http://www.baidu.com"
}])
var m2 = angular.module('myApp2',[])
m2.controller = ('Bbb',['$scope',function($scope){
}])
<div ng-controller="Aaa">
    <div ng-class="{red:true,color:true}">{{text}}</div>
    <div ng-class="{{sClass}}">{{text}}</div><!-- 注意此处需要加{{}} -->
    <div ng-style="{color:'red',background:'#f3f3f3'}">{{text}}</div>
    <div ng-style="{{style}}">{{text}}</div> <!-- 注意此处需要加{{}} -->
    <a ng-href="{{url}}">aaa</a>
    <a ng-attr-href="{{url}}" ng-attr-title="{{text}}">aaa</a>
</div>

dom操作

ng-show
ng-hide :ng-show与ng-hide:对display操作;
ng-if
ng-swtich :有选择性进行切换; 不需要属性 ,了解即可;
on
default
when
ng-open :ng-open; ff不支持;
var m1 = angular.module('myApp',[]) /* 操作html */
m1.controller('Aaa',['$scope',function($scope){
        $scope.btn = true;
}])
<input type="checkbox" name="" id="" ng-model="btn"/> 
<div ng-switch on="btn"><p ng-switch-default>默认是的</p><p ng-switch-when="false">切换隐藏的</p></div>

未完

Less 語言特性

http://less.bootcss.com/features/#mixins-parametric-feature
<h3>變量</h3>

@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;

#header {
  color: @light-blue;
}

/*輸出*/
#header {
  color: #6c94be;
}

注意,由于变量只能定义一次,其本质就是“常量”。



<h3>混合(Mixin)</h3>

相當於“繼承”

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}
#menu a {
  color: #111;
  .bordered;
}

/*輸出*/
#menu a {
  color: #111;
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

class與id同樣適用,當mixin時,()是可選的

.a, #b {
  color: red;
}

.mixin-id {
  #b();
}

/*輸出*/
.mixin-id {
  color: red;
}

<h3>嵌套规则</h3>

header{
  color: #cccccc;
  .nav{
    font-size: 12px;
  }
  .logo{
    width: 300px;
    .img{
      width: 100%;
    }
  }
}

/*輸出*/
header {
  color: #cccccc;
}
header .nav {
  font-size: 12px;
}
header .logo {
  width: 300px;
}
header .logo .img {
  width: 100%;
}

&代表父級

.clearfix {
  display: block;
  zoom: 1;
  &:after {
    content: " ";
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}

/*輸出*/
.clearfix {
  display: block;
  zoom: 1;
}
.clearfix:after {
  content: " ";
  display: block;
  font-size: 0;
  height: 0;
  clear: both;
  visibility: hidden;
}

a {
  color: blue;
  &:hover {
    color: green;
  }
}

/*輸出*/
a {
  color: blue;
}
a:hover {
  color: green;
}

&-生產名

.button{
  &-ok{
    background: #000;
  }
}

/*輸出*/
.button-ok {
  background: #000;
}

&組合

.c{
  &+&{
    color: red;
  }
  &&{
    color:blue;
  }
  & & {
    color:yellow
  }
  &,&con{
      color:pink
  }
}

/*輸出*/
.c + .c {
  color: red;
}
.c.c {
  color: blue;
}
.c .c {
  color: yellow;
}
.c, .ccon {
  color: pink;
}

&同時代表的所有長輩元素,不僅僅是父級,所以多層選擇更簡潔:

.nav{
  .header{
    .logo{
      & input[type=text],& input[type=button]{
        color: green;
      }
    }
  }
}

/*輸出*/
.nav .header .logo input[type=text],
.nav .header .logo input[type=button] {
  color: green;
}

通過&改變選擇器父子關係 :

.h{
  .a{
    width:10px;
    .c{
      height:20px;
    }
  }
}
/*輸出*/
.h .a .c {
  height: 20px;
}

.h{
  .a{
    width:10px;
    .c &{    /*使.c成為父級*/
      height:20px;
    }
  }
}
/*輸出*/
.c .h .a {
  height: 20px;
}

生成可能排列的組合

p,a,ul,li{
  width: 10px;
  & &{
    height:0
  }
}

/*輸出*/
p,
a,
ul,
li {
  width: 10px;
}
p p,
p a,
p ul,
p li,
a p,
a a,
a ul,
a li,
ul p,
ul a,
ul ul,
ul li,
li p,
li a,
li ul,
li li {
  height: 0;
}

<h3>运算</h3>
任何数字、颜色或者变量都可以参与运算。下面是一组案例

@base: 5%;
@filler: @base * 2;
@other: @base + @filler;

div{
  color: #888 / 4;
  width:@base * 10;
  height: 100% / 2 + @filler;
}

/*輸出*/
div {
  color: #222222;
  width: 50%;
  height: 60%;
}

<h3>函数</h3>
http://baike.renwuyi.com/2015-04/9042.html

@base: #f04615;
@width: 0.5;

.class {
  width: percentage(@width); // 0.5轉50%
  color: saturate(@base, 5%); //顏色飽和度+5%
  background-color: spin(lighten(@base, 25%), 8); //顏色亮度+25%,色相+8
}


/*輸出*/
.class {
  width: 50%;
  color: #f6430f;
  background-color: #f8b38d;
}

<h3>命名空間規則</h3>

#logo {
  .img {
    width: 10px;
    height: 10px;
    &:hover {
      background-color: white
    }
  }
}
#nav a {
  color: orange;
  #logo > .img;
}

/*輸出*/
#logo .img {
  width: 10px;
  height: 10px;
}
#logo .img:hover {
  background-color: white;
}
#nav a {
  color: orange;
  width: 10px;
  height: 10px;
}
#nav a:hover {    //注意這一步也帶出
  background-color: white;
}

<h3>變量定義範圍</h3>
先找子範圍,不分前面,找不到再找父;所以下面兩種形式都只會找子範圍內的變量;

@var: red;

#page {
  @var: white;
  #header {
    color: @var; // white
  }
}
#page {
  #header {
    color: @var; // white
  }
  @var: white;
}

<h3>导入(Importe)</h3>
和你预期的工作方式一样。你可以导入一个 .less 文件,此文件中的所有变量就可以全部使用了。如果导入的文件是 .less 扩展名,则可以将扩展名省略掉:

@import "library"; // library.less
@import "typo.css";

<h3>變量替換</h3>

// Variables
@mySelector: banner;

// Usage
.@{mySelector} {
  font-weight: bold;
  line-height: 40px;
  margin: 0 auto;
}
// Variables
@images: "../img";
// 用法
body {
  color: #444;
  background: url("@{images}/white-sand.png");
}

注意:導入css或inport文件,此種變量定義不再適用;

// Variables 無法輸出
@themes: "../../src/themes";
// Usage
@import "@{themes}/tidal-wave.less";

属性

@property: color;

.widget {
  @{property}: #0ee;
  background-@{property}: #999;
}
@fnord:  "I am fnord.";
@var:    "fnord";
p{
  content: @@var;
}

可以後聲明

.lazy-eval {
  width: @var;
}
@var: @a;
@a: 9%;

同名變量遵循後蓋前,從裏到外原則

@var: 0;
.class1 {
  @var: 1;
  .class {
    @var: 2;
    three: @var;
    @var: 3;
  }
  one: @var;
}

/*輸出*/
.class1 {
  one: 1;
}
.class1 .class {
  three: 3;
}


<h3>Extend 擴展</h3>

nav ul {   //原樣式保持不變
  &:extend(.inline);         //與.inline生成擴展
  background: blue;
}
.inline {
  color: red;
}

/*輸出*/
nav ul {
  background: blue;
}
.inline, nav ul {
  color: red;
}

/*另一種寫法:*/

nav ul:extend(.inline){
  background: blue;
}

/*如果定義兩個空置屬性*/
.e:extend(.f) {}
.e:extend(.g) {}
==》
.e:extend(.f,.g){}

多個擴展只擴展對應的本位元素

.big-division,
.big-bag:extend(.bag),
.big-bucket:extend(.bucket) {
  background: #000;
}

/*如果.bag等存在,則輸出*/

.bag,
.big-bag {
  width: 100%;
}
.bucket,
.big-bucket {
  width: 55px;
}
.bucketone{
  tr{
    color:#cd000c;
  }
}
.some-class:extend(.bucketone tr){
}

/*輸出*/
.bucketone tr,.some-class {
  color: #cd000c;
}

如果extend是引用的屬性,則無法匹配

.a.class,.class.a,.class > .a ,*.class{
  color: blue;
}
.test:extend(.class) {} // 上面的.class都是被引用,所以這句無法匹配,(只有純寫.class{..才能匹配.})

順序不同也無法匹配

link:hover:visited {
  color: blue;
}
.selector:extend(link:visited:hover) {}

nth系也無法匹配

:nth-child(1n+3) {
  color: blue;
}
.child:extend(n+3) {}

引用不重要,以下是相同的

[title=identifier] {
  color: blue;
}
[title='identifier'] {
  color: blue;
}
[title="identifier"] {
  color: blue;
}

Extend的 all,以下replacement將會複製一份與.test同樣結構的屬性

.a.b.test, .test.c {
  color: orange;
}
.test {
  &:hover {
    color: green;
  }
}
.replacement:extend(.test all) {}

/*輸出*/
.a.b.test, .test.c, .a.b.replacement, .replacement.c {
  color: orange;
}
.test:hover, .replacement:hover {
  color: green;
}

變量生產出的屬性不能被匹配到extend

@variable: .bucket;
@{variable} { // interpolated selector
  color: blue;
}
.some-class:extend(.bucket) {} // does nothing, no match is found

變量與extend也不能匹配

.bucket {
  color: blue;
}
.some-class:extend(@{variable}) {} // interpolated selector matches nothing
@variable: .bucket;

//當然,這麼寫是無任何問題的
.bucket {
  color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;

//輸出:
.bucket,.selector {
  color: blue;
}

@media


1、比如:print裏的@media只會匹配print裏面的

2、寫在@media內部的extend無法繼承子塊的樣式

@media screen {
  .screenClass:extend(.selector) {} // extend inside media
  @media (min-width: 1023px) {
    .selector {  // ruleset inside nested media - extend ignores it
      color: blue;
    }
  }
}

/*輸出*/
@media screen and (min-width: 1023px) {
  .selector {
    color: blue;
  }
}
很明顯:.screenClass:extend(.selector) {}不會被匹配到;

3、extend寫在@media外部可匹配到內部所有選擇器樣式

@media screen {
  .selector {
    color: blue;
  }
  @media (min-width: 1023px) {
    .selector {
      color: blue;
    }
  }
}
.topLevel:extend(.selector) {}

/*輸出*/
@media screen {
  .selector,
  .topLevel {
    color: blue;
  }
}
@media screen and (min-width: 1023px) {
  .selector,
  .topLevel {
    color: blue;
  }
}



<h3>小例</h3>

/*定义base类*/
@def-bg:#f1f1f1;
@def-col:#464646;

.def-bg{
  background: @def-bg;
  color:@def-col;
}

//子类只改变颜色
.con-bg{
  &:extend(.def-bg);
  background: #cccccc;
}

/*输出*/
.def-bg,
.con-bg {
  background: #f1f1f1;
  color: #464646;
}
.con-bg {
  color: #cccccc;
}
<div class='def-bg con-bg'></div>

使用扩展减少CSS代码

.a(){
  width: 10px;
}
.b{
  .a;
}
.c{
  .a;
}

/*输出*/
.b {
  width: 10px;
}
.c {
  width: 10px;
}

/*使用extend*/
.a{
  width: 10px;
}
.b{
  &:extend(.a);
}
.c{
  &:extend(.a);
}

/*输出*/
.a,
.b,
.c {
  width: 10px;
}
li.list > a {
  width: 10px;
}
button.list-style {
  &:extend(li.list > a); // use the same list styles
}

li.list > a,
button.list-style {
  width: 10px;
}

Webstorm less安裝

npm install less -g

記錄安裝路徑如:C:UsersadminAppDataRoamingnpmnode_moduleslessbinlessc

File-->Settings-->Tools-->External Toools-->Add-->

Name:LESS

Program : C:\Program Files\nodejs\node.exe

Parameters : C:\Users\admin\AppData\Roaming\npm\node_modules\less\bin\lessc $FilePath$ $FileDir$\$FileNameWithoutExtension$.css

Working directory :C:\Program Files\nodejs

OK--->Apply
-->Keymap-->External Tools -->LESS -->設置快捷鍵如:Alt + B

seajs入門

最簡單的示例:

目錄結構:


seajs+
    
    js+
        sea.js
        m.js
        show.js
        hide.js
   
     index.html

注意路徑:
index.html

<script src="js/sea.js"></script>

<script>
    seajs.use('./js/m')
</script>
seajs.use(url,function(ex){
    ex代表js文件里的exports; 
}) 
define(function(require,exports,module){ 
        //require,exports,module 名字不能改,也不能改为var r = require等形式;
        //require 模块之间依赖的接口
        //exports对外提供接口
        // 当引入的是sea下面的模块时,那么require执行完的结果就是exports;
        //一个模块 ,只能省略后面,不能省略前面;
})

m.js

define(function (require,exports,module){
var _box = document.getElementById('box')
    var _on = 1;
    document.onclick = function(){
        if(_on){
            require('./show').hide(_box)
        }
        else{
            require('./hide').show(_box)
        }
        _on = !_on;
    }
})

show.js

define(function (require,exports,module){
    exports.show = function(obj){
        obj.style.display = 'block'
    }
})

hide.js

define(function (require,exports,module){
    exports.hide = function(obj){
        obj.style.display = 'none'
    }
})

模塊代碼:遵循统一的写法

// 所有模块都通过 define 来定义
define(function(require, exports, module) {

  // 通过 require 引入依赖
  var $ = require('jquery');
  var Spinning = require('./spinning');

  // 通过 exports 对外提供接口
  exports.doSomething = ...

  // 或者通过 module.exports 提供整个接口
  module.exports = ...

});


1、关键字define, 以及匿名函数的参数一个都不能少, 注意: require, exports, module 参数名称也不能改.

2、exports: 用于声明该模块的对外接口

3、module: 用于表示当前模块的信息,具有如下属性:

id:         模块的唯一表示, require方法需要用到他<br />

exports: 当前模块开放的接口, Object, main.js中是 sum

dependencies: 当前模块的依赖列表



seajs配合grunt打包压缩;需解决ID与路径问题;[仅适用于seajs1.3.1版本,seajs2.0以后不支持模块依赖,方法见更新]

package.json

{
  "name": "js2",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-cmd-concat":"~0.2.8",
    "grunt-cmd-transport":"~0.3.0",
    "grunt-contrib-uglify":"~0.11.0"
  }
}

切換至項目根目錄運行

npm install

Gruntfile.js

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        transport:{
            js2:{
                files:{
                    '.build' :['1.js','2.js','3.js','4.js']
                }
            }
        },
         concat:{
         js2:{
         files:{
         'dist/m.js' : ['.build/1.js','.build/2.js','.build/3.js','.build/4.js']
         }
         }
         },
         uglify:{
         js:{
         files:{
         'dist/m.min.js': [ 'dist/m.js']
         }
         }
         }

    });
    grunt.loadNpmTasks('grunt-cmd-transport');
    grunt.loadNpmTasks('grunt-cmd-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.registerInitTask('default',['transport','concat','uglify']);
}

運行

grunt

seajs1.3.1



常用API
非官方整理



<h3>Module</h3>
id:模块唯一标识;

uri:模块绝对路径;

dependencies:当前模块依赖;
m.js

define(function (require, exports, module) {
    console.log(module.id); //弹出路径
    console.log(module.uri); //弹出路径
    console.log(module.dependencies);  // 当前模块依赖
})

exports:当前模块对外接口;

m.js

define(function (require, exports, module) {
  console.log(module.exports == exports);  //true                module.exports 对象  //exports一个引用
})

//提供对外接口时:

//这种是无法访问到的;
exports = {
        a:a
    }

//可访问:
exports.a = a;
//可访问:
module.exports = {
    a:a
}

index.html

    seajs.use('m3',function(ex){  
    //ex-->调用的是module.exports这个对象
     console.log(ex.a);
})

require.async:异步加载模块

//默认是同步的
require('m3.js'); 

//可改为异步
require.async('m3.js',func
 console.log('模块加载完成');
})        //此步未加载完成,下面的代码也能运行;

<h3>插件</h3>

安装



<h3>引入多模块</h3>

seajs.use(['m2.js','m3.js'],function(ex2,ex3){
    ex2.drag();
    ex3.pic();  
})
<h3>seajs加ID有利于提取</h3>
index.html

<script src="sea.js" id='seajs'></script>

<h3>如何改造为cmd模块</h3>

//普通
var a = 1;

//seajs下,套个define,再对外提供接口即可

define(function(require,exports,module){
var a = 1;
exports.a = a;
})


<h3>调试接口cache<h3>

零JS筆記 | apply call 轉

call: 调用一个对象的一个方法,以另一个对象替换当前对象。

call([thisObj[, arg1[, arg2[, [,.argN]]]]])

參數:thisObj,


arg1, arg2, , argN :可选项。将被传递方法参数序列。


說明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

说明白一点其实就是更改对象的内部指针,即改变对象的this指向的内容。这在面向对象的js编程过程中有时是很有用的。
    function Obj(){this.value="对象!";}
    var value="global 变量";
    function Fun1(){alert(this.value);}

    window.Fun1();   //global 变量
    Fun1.call(window);  //global 变量
    Fun1.call(document.getElementById('myText'));  //input text
    Fun1.call(new Obj());   //对象!

window.Fun1()默認對象;Fun1.call(window)執行Fun1的對象為window; 以此類推


call函数和apply方法的第一个参数都是要传入给当前对象的对象,及函数内部的this。后面的参数都是传递给当前对象的参数。

    var func=new function(){this.a="func"}
    var myfunc=function(x){
        var a="myfunc";
        alert(this.a);  //func
        alert(x);  //var
    }
    myfunc.call(func,"var");
对于第一个参数意义都一样,但对第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。
func.call(func1,var1,var2,var3)  ==  func.apply(func1,[var1,var2,var3])
同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入 区别在于 call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments




apply :應用某一對象的一個方法,用另一對象替換當前對象;

apply([thisObj[,argArray]]) 

1、如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
2、如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

實例a

function add(a,b){alert(a+b)}function sub(a,b){alert(a-b)}add.call(sub,3,1);

這個例子其實沒什麼用,一定要找理由:不涉及到this,所以call什麼的相當於白寫;alert(4)

實例b

    function Animal(){
        this.name = "Animal";
        this.showName = function(){
            alert(this.name);
        }
    }

    function Cat(){
        this.name = "Cat";
    }

    var animal = new Animal();
    var cat = new Cat();

    //通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。
    //输入结果为"Cat"
    animal.showName.call(cat,",");
    //animal.showName.apply(cat,[]);
animal.showName.call(cat,","); 將原本的this對象指向cat,cat獲得屬性,this.name==cat.name,所以输出是Cat

實例c

 function Animal(name){    
     this.name = name;    
     this.showName = function(){    
         alert(this.name);    
     }    
 }    
   
 function Cat(name){  
     Animal.call(this, name);  
 }    
   
 var cat = new Cat("Black Cat");   
 cat.showName();
Animal.call(this, name); this為cat對象,再執行 Animal(); 裏面的this變為cat對象,所以獲得屬性與方法;最後彈出 'Black Cat'

gruntjs入門

安裝node.js,安裝gruntjs

npm install -g grunt-cli
npm install grunt --save-dev
grunt –version

1、轉到項目根文件夾下,安裝插件;

npm init

生成 package.json

{
  "name": "elmok",
  "version": "0.1.0",
  "devDependencies": {
        "grunt" : "~0.4.2",
           "grunt-contrib-concat" : "~0.3.0",
        "grunt-contrib-uglify" : "~0.3.2"
  }
}

安裝

npm install
或
npm install grunt-contrib-concat --save-dev  //按具體插件名

2、創建任務
創建Gruntfile.js

pkg: grunt.file.readJSON('package.json')引入

elmok:項目

concat:任務名;files:{新生成文件:[被合併各文件]}

concat:任務名;files:{新生成文件:[被壓縮文件]}

src:[ ] 源文件路徑

dest:[ ] 生成目標文件

banner參數,給目標文件頭部加注釋信息

<%= pkg.name %>,pkg是用grunt.file.readJSON('package.json')读取到的JSON,而且已经转换为JS对象。依照前面package.json的演示样例,这段代码会在写入文件时被替换为"my-project-name"。

JS对象和JSON来做辅助的配置 <%= grunt.template.today("yyyy-mm-dd") %> 按指定格式生成任務時間

grunt.loadNpmTasks('grunt-contrib-concat');加載任務所需插件

grunt.registerTask('default', ['concat', 'uglify']);註冊任務,任務名以數組存

module.exports = function (grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        concat: {
            elmok: {
                files: {
                    'dist/m.js': ['1.js', '2.js', '3.js', '4.js']
                }
            }
        },
        uglify: {
            elmok: {
                files: {
                    'dist/main.min.js': ['dist/main.js']
                }
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.registerTask('default', ['concat', 'uglify']);
};

或等等類似

module.exports = function(grunt) {

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        uglify: {
            options: {
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
            },
            build: {
                src: 'main.js',
                dest: 'main.min.js'
            }
        }
    });

    // Load the plugin that provides the "uglify" task.
    grunt.loadNpmTasks('grunt-contrib-uglify');

    // Default task(s).
    grunt.registerTask('default', ['uglify']);

};

最後執行:

grunt

小拓展:可任意選擇配置; 轉

options: {
    mangle: false, //不混淆变量名
    preserveComments: 'all', //不删除注释,还可以为 false(删除全部注释),some(保留@preserve @license @cc_on等注释)
    footer:'\n/*! <%= pkg.name %> 最后修改于: <%= grunt.template.today("yyyy-mm-dd") %> */'//添加footer
    report: "min"//输出压缩率,可选的值有 false(不输出信息),gzip

},
buildall: {//任务三:按原文件结构压缩js文件夹内所有JS文件
    files: [{
        expand:true,
        cwd:'js',//js目录下
        src:'**/*.js',//所有js文件
        dest: 'output/js'//输出到此目录下
    }]
},
release: {//任务四:合并压缩a.js和b.js
    files: {
        'output/js/index.min.js': ['js/a.js', 'js/main/b.js']
    }
}