分类 JS 下的文章

零JS筆記 | Ajax-留言本

用戶驗證:即時提醒

_username1.onblur = function () {
  ajax('get', 'guestbook/index.php', 'm=index&a=verifyUserName&username=' + this.value, function (data) {
    var d = JSON.parse(data) //數據先轉為objec對像
    verifyUserNameMsg.innerHTML = d.message;
    if (d.code != 0) { //後端定義狀態碼
      verifyUserNameMsg.style.color = 'red'
    } 
    else {
      verifyUserNameMsg.style.color = 'green'
    }
  })
}

用戶註冊:

var password1 = document.getElementById('password1')
var btnReg = document.getElementById('btnReg')
btnReg.onclick = function () {
  ajax('post', 'guestbook/index.php', 'm=index&a=reg&username=' + encodeURI(_username1.value) + '&password=' + password1.value, function (data) {
    var d = JSON.parse(data)
    alert(d.message)
  })
}

更新狀態:

function udpateUserStatus() {
  var uid = getCookie('uid')
  var username = getCookie('username')
  if (uid) {
    _user.style.display = 'block'
    _userinfo.innerHTML = username
    _red.style.display = 'none'
    _login.style.display = 'none'
  } else {
    _user.style.display = 'none'
    _userinfo.innerHTML = username
    _red.style.display = 'block'
    _login.style.display = 'block'
  }
}

//getCookie封裝
function getCookie(key) {
  var arr1 = document.cookie.split('; ')
  for (var i = 0; i < arr1.length; i++) {
    var arr2 = arr1[i].split('=')
    if (arr2[0] == key) {
      return arr2[1]
    }
  }
}

退出:

_logout.onclick = function () {
  ajax('post', 'guestbook/index.php', 'm=index&a=logout', function (data) {
    var d = JSON.parse(data)
    alert(d.message)
    if (!d.code) {
      udpateUserStatus()
    }
  })
  return false
}

發送留言:

btnPost.onclick = function () {
  ajax('post', 'guestbook/index.php', 'm=index&a=send&content=' + encodeURI(content.value), function (data) {
    var d = JSON.parse(data)
    console.log(d);
    if (!d.code) {
      createList(d.data, true)
      udpateUserStatus()
    }
  })
}

顯示留言 :

function showlist() {
  ajax('post', 'guestbook/index.php', 'm=index&a=getList&n=10&page=' + ipage, function (data) {
    var d = JSON.parse(data)
    console.log(d);
    var data = d.data //注意此處判斷;
    if (data) {
      for (var i = 0; i < data.list.length; i++) {
        createList(data.list[i])
      }
    } else {
      if (ipage == 1) {
        _list.innerHTML = '现在还没有留言,快来抢沙发!'
      }
      showMore.style.display = 'none'
    }
  })
}

創建元素添加到頁面:

function createList(data, insert) {
  var dl = document.createElement('dl')
  var dt = document.createElement('dt')
  var strong = document.createElement('strong')
  strong.innerHTML = data.username;
  dt.appendChild(strong)
  var dd1 = document.createElement('dd')
  dd1.innerHTML = data.content
  var dd2 = document.createElement('dd')
  dd2.className = 't'
  var a1 = document.createElement('a')
  a1.href = 'javascript:;'
  a1.innerHTML = '顶(<span>' + data.support + '</span>)'
  var a2 = document.createElement('a')
  a2.href = 'javascript:;'
  a2.innerHTML = '踩(<span>' + data.oppose + '</span>)'
  dd2.appendChild(a2)
  dd2.appendChild(a1)
  dl.appendChild(dt)
  dl.appendChild(dd1)
  dl.appendChild(dd2)
  if (insert && _list.children[0]) {     //如果有第一條,則插入,否則添加;最新總是顯示第一位
    _list.insertBefore(dl, _list.children[0])
  } else {
    _list.appendChild(dl)
  }
}

顯示更多

var showMore = document.getElementById('showMore')
showMore.onclick = function () {
  ipage++
  showlist()
}

comment_ajax.rar

零JS筆記 | Ajax-固定瀑布流布局实例

1、首先,分四列,固定好,每次把div都加进li里,每次加都选最短列li加;

<ul id="ul1">
    <li></li>  <!-- 一定要有这四个初始li -->
    <li></li>
    <li></li>
    <li></li>
</ul>

2、写好后端php接收,得到格式如:

[
    {
        "id": "539529",
        "title": "",
        "referer": "https://www.tumblr.com/dashboard",
        "url": "http://www.wookmark.com/image/539529",
        ......
    },
    {
        "id": "539543",
        "title": "Épinglé par Scot Woodman sur Bionic Digitism | Pinterest",
......
]

3、操作需转换为Object对象 var data = JSON.parse(data),再调用ajax函数

ajax('get', 'getPics.php', 'cpage=' + ipage, function (data) {
  var data = JSON.parse(data)
  //后续无数据
  if (!data.length) {
    return;
  }
  for (var i = 0; i < data.length; i++) {
    //获取每次最短li的下标,可能的值为:0,1,2,3
    var _index = getShort()
    var _div = document.createElement('div')
    var _img = document.createElement('img')
    _img.src = data[i].preview;
    //修正scroll时图片未加载li总高度计算问题
    _img.style.height = data[i].height * (200 / data[i].width) + 'px'
    //比例、
    var _h3 = document.createElement('h3')
    _div.appendChild(_img)
    _div.appendChild(_h3)
    _h3.innerHTML = data[i].title;
    _li[_index].appendChild(_div) //每次都往最短的li里扔东西
  }
  b = true; //加载完开门
  //获取高度最短的li
})

所以计算每次最短li方法:

function getShort() {
  //找最短列li
  var index = 0;
  var ih = _li[index].offsetHeight;
  for (var i = 1; i < ilen; i++) {
    if (_li[i].offsetHeight < ih) { //每次小于第index个,
      index = i;  //则给index赋值
      ih = _li[i].offsetHeight; //重新赋值
    }
  }
  return index; //最后return回去
}

//思路:如数组[5,6,1,4,3]
目的:找出最小值的位置;
位置:0,1,2,3,4
i = 0;iv = 5; index = 0
i = 1;iv = 6;[6>5]  index = 0[不变]
i = 2;iv = 1;[1<5]  index = 2
i = 3;iv = 4;[4>1]  index = 2[不变]
i = 4;iv = 3;[3>1]  index = 2[不变]
所以返回index = 2;

当滚动条拉到最后一个li时,触发onscroll事件;条件是:li的top值+本身高度 < 当前视窗 + 滚动条距离;

技巧:先设开关b,打开状态时b,当获取时b = false关,什么时候开,请求结束时再开,所以每次ajax加载完时b = true再打开
window.onscroll = function () {
  var _index = getShort()
  var oli = _li[_index]
  var scrolltop = document.body.scrollTop || document.documentElement.scrollTop;
  if (getTop(oli) + oli.offsetHeight < document.documentElement.clientHeight + scrolltop) {
    if (b) {
      ipage++
      getList()
      b = false; //关门
    }
  }
}

当前元素的到顶部的距离 :

function getTop(obj) {
  var itop = 0;
  while (obj) {
    itop += obj.offsetTop;
    obj = obj.offsetParent
  }
  return itop;
}

運行

零JS筆記 | Ajax-基础

核心:

btn.onclick = function () {
  var xhr = new XMLHttpRequest()
  xhr.open('get', 'hellw.txt', true)
  xhr.send();
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        alert(xhr.responseText)
      } 
      else {
        alert('出错了,' + xhr.status)
      }
    }
  }
}

流程:
打开浏览器--》输入地址--》按Enter--》等待服务器响应;


1)打开浏览器,创建一个ajax对象 之后利用属性send()和方法responseText()去获取内容

IE6下: 以下用的是ActiveXObject('Microsoft.XMLHTTP')

標準下:var xhr = new XMLHttpRequest()

为兼容IE6,首先定义一个null;,然后分别判断处理



2)var xhr = null;

try {
  var xhr = new XMLHttpRequest()
} 
catch (e) {
  var xhr = ActiveXObject('Microsoft.XMLHTTP')
}

2)輸入地址:open('打开方式',url,3是否异步)

异步:非阻塞,前面未完成,後面可開始執行,大部分情況下都用异步

同步:阻塞,当前面未完成時,会阻止后面的比如加载jq,须先加完再执行($)(fun).....

xhr.open( 'get','hellw.txt',true)

3)按Enter,執行操作;相當於Form的submit

4)等服务器响应,即返回的数据 ,返回后存放在属性里,responseText【属性】或responseXML【XML属性】:ajax请求返回的内容,被存放到这个属性下

readyState:ajax工作狀態:0,1,2,3,4

0 (初始化)还没有调用open()方法 1 (载入)已调用send()方法,正在发送请求 2 (载入完成)send()方法完成,已收到全部响应内容 3 (解析)正在解析响应内容 4 (完成)响应内容解析完成,可以在客户端调用了

status状态码;需要做容错处理:

if (xhr.status == 200) {
  alert(xhr.responseText)
} 
else {
  alert('出错了,' + xhr.status)
}




表单的作用:数据提交

action:地址;默认当前页面<br />
method:数据提交方式 get post enctype:提交数据格式: 默认get方式<br />

"Content-Type","application/x-www-form-urlencoded”

get:把数据名称和数据对应的数据值用等号连接起来,如果有多个会&连接,通过url?后面传入指定页面<br />

PHP接收方式要对应:get $_GET ; post $_POST 当然 $_REQUEST

JSON.stringify() 对象转成字符串
JSON.parse()字符串解析成对象



生成新闻例子一:

整个流程走一遍,数据data转换成对像再处理:var data = JSON.parse(xhr.responseText)

之后即拿数据处理append到ul里

var btn = document.getElementById('btn')
btn.onclick = function () {
  var xhr = null
  try {
    var xhr = new XMLHttpRequest()
  } 
  catch (e) {
    var xhr = ActiveXObject('Microsoft.XMLHTTP')
  }
  xhr.open('get', 'getnews.php', true)
  xhr.send();
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        //   console.log(xhr.responseText);
        var data = JSON.parse(xhr.responseText) //转换成对像
        var html = ''
        var _ul = document.getElementById('ul1')
        for (var i = 0; i < data.length; i++) {
          html += '<li><a href="">' + data[i].title + '</a></li>[<span>' + data[i].data + '</span>]'
        }
        _ul.innerHTML = html;
      } 
      else {
        alert('出错了,' + xhr.status)
      }
    }
  }
}

运行



get方式,1、缓存问题;可使用时间戳解决,&不能丢;2、乱码,使用encodeURI解决,post无此问题

xhr.open('get', '1.get.php?username=' + encodeURI('小时') + '&age=32&' + new Date().getTime(), true)

1.get.php:

<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);
$username = $_POST['username'];
$age = $_POST['age'];
echo "欢迎 你的名字:{$username},年龄:{$age}";

所以,post方式应该时,send()方法里传参,并且要设置请求头:

var btn = document.getElementById('btn')
btn.onclick = function () {
  var xhr = null
  try {
    var xhr = new XMLHttpRequest()
  } 
  catch (e) {
    var xhr = ActiveXObject('Microsoft.XMLHTTP')
  }
  //post时参数传这里
  xhr.open('post', '1.get.php', true)
  //告诉后端发送数据的类型  
  xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
  xhr.send('username=小时&age=30');
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        alert(xhr.responseText)
      } 
      else {
        alert('出错了,' + xhr.status)
      }
    }
  }
}

所以粗略的ajax封装为:

function ajax(method, url, data, success) {
  var xhr = null
  try {
    var xhr = new XMLHttpRequest()
  } 
  catch (e) {
    var xhr = ActiveXObject('Microsoft.XMLHTTP')
  }
  if (method == 'get' && data) {
    url += '?' + data
  } //如果有数据存在并且方法get()

  xhr.open(method, url, true)
  if (method == 'get') {
    xhr.send();
  } 
  else {
    xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
    xhr.send(data);
  }
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        success && success(xhr.responseText) //如果存在执行
      } 
      else {
        alert('出错了,' + xhr.status)
      }
    }
  }
}

零HTML5筆記 | canvas

绘制环境

getContext('2d')


绘制方块

fillRect(L,T,W,H)默认颜色是黑色


strokeRect(L,T,W,H)带边框的方块


设置绘图

fillStyle填充颜色(绘制canvas是有顺序的)


lineWidth线宽度,是一个数值


strokeStyle边线颜色


边界绘制

lineJoin边界连接点样式(即四個角):miter(默认)、round(圆角)、bevel(斜角)


lineCap 端点样式:butt(默认)、round(圆角)、square(高度多出为宽一半的值)


绘制路径

beginPath 开始绘制路径


closePath 结束绘制路径


moveTo 移动到绘制的新目标点


lineTo 新的目标点


stroke 划线,默认黑色


fill 填充,默认黑色


rect 矩形区域


clearRect 删除一个画布的矩形区域


save 保存路径


restore 恢复路径


beginPath 开始绘制路径

零JS筆記 | 定時器 | 抖動

setInterval(函數,毫秒);
clearInteval( setInterval(函數,毫秒); )
注意理解: num %= arr.length;

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


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

圖片切換實例更改
<a href='http://www.elmok.com/js/%E6%9C%80%E7%B0%A1%E5%96%AE%E7%9A%84%E5%9C%96%E7%89%87%E5%88%87%E6%8F%9B%E4%BA%8C.html
' target='_blank'>最簡單的圖片自動切換

function aplay(){
var timer = setInterval(function(){
    num++;
    num %= arrimg.length;//num = 0 1 2 3 4  === if(num = lis.length){num = 0}
    tab()
},1000)
}
//去掉鼠標移入移出
box.onmouseover = function(){
    clearInterval(timer)
};
box.onmouseout = aplay  //不能加括號

//打開時隔2s後再執行;體驗 
setTimeout(aplay,2000)

應用:打開網頁自動彈出;
setTimerout(函數,毫秒);
clearTimeout( setTimerout(函數,毫秒); )

var imgbox = document.getElementById('img')
setTimeout(function(){
    imgbox.style.display = 'inline-block';    //圖片為 inline-block;
        setTimeout(function(){                //3秒後關閉; 
            imgbox.style.display = 'none'
        },3000)
},2000)

圖片鼠標按下自動滾動,抬起停止
onmousedown
onmouseup

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


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

抖動函數
原理:原位置以遞減方式向兩邊相加,越加越小直到0;
抖完後執行回調~

//方法封裝
function shake(obj, attr, pos, endfn) {
  // var pos = parseInt(getStyle(obj,attr)); //去掉ps //隱患,多次觸發時每次的初始位置不同;
  var arr = []; //20 -20 18 -18
  var shake = null;
  var num = 0;
  for (var i = 20; i > 0; i -= 2) {
    arr.push(i, - i);
  }
  arr.push(0);
  clearTimeout(obj.shake)
  shake = setInterval(function () {
    obj.style[attr] = pos + arr[num] + 'px'
    num++
    if (num == arr.length) {
      clearInterval(obj.shake)
      endfn && endfn()
    }
  }, 50)
}
var img = document.getElementsByTagName('img')
var on = true;
for (var i = 0; i < img.length; i++) {
  img[i].style.left = 100 + i * 110 + 'px'
  var pos = parseInt(getStyle(img[i], 'top'));
  img[i].onmousemove = function () {
    shake(this, 'top', pos)
  }
}
<img src="c1.jpg" alt="" width="150"/>
<img src="c2.jpg" alt="" width="150"/>
<img src="c3.jpg" alt="" width="150"/>
<img src="c4.jpg" alt="" width="150"/>
<img src="c5.jpg" alt="" width="150"/>

修復版:

    function shake(obj, attr, endfn) {
        if (obj.door) {
            return
        }
        obj.door = 1;
        var pos = parseInt(css(obj,attr)); 
        var arr = []; //20 -20 18 -18
        var num = 0;
        for (var i = 20; i > 0; i -= 2) {
            arr.push(i, - i);
        }
        arr.push(0);
        clearTimeout(obj.shake)
        obj.shake = setInterval(function () {
            obj.style[attr] = pos + arr[num] + 'px'
            num++
            if (num == arr.length) {
                clearInterval(obj.shake)
                endfn && endfn()
                obj.door = 0;
            }
        }, 50)
    }

零JS筆記 | 運算符 | 流程控制 | return | getStyle

0%3 = 0
1%3 = 1
2%3 = 2
3%3 = 0

a%b
a未遇到自己前,=a
a遇到自己, =0
a超過自己,=除以整數倍a後,又開始未遇到自己的情況

var i = 0;
i++;
if (i === 5) {
  i = 0
} //可寫成下面

i % 5 //i = 0 1 2 3 4
for(var i=0;i<a;i++){
    i%b
}
if( a<=b ){ 0.1.2.3...a-1 }
if( a>b  ){ 0.1.2.3...b-1...[0.1.2....a-b-1 ]}

var s  =6500 //秒
alert(Math.floor(s/60)+'分'+s%60+'秒')

給所有li加間隔顏色,及移入移出

var ul = document.getElementById('ul')
var li = ul.getElementsByTagName('li')
var arr = ['red','yellow','blue'];

//第一種寫法
for (var i = 0; i < li.length; i++) {
  li[i].index = i;
  li[i].style.background = arr[i % arr.length]; //0 1 2 0 1 2 0 1 2 .....
  li[i].onmousemove = function () {
    this.style.background = 'gray'
  }
  li[i].onmouseout = function () { //for 裏包fn,不能用i,所以給所有li建索引值
    this.style.background = arr[this.index % arr.length] // 0 1 2 0 1 2
  }
}

//第二種寫法
var str = '' //存鼠標移過去時原來的顏色
for (var i = 0; i < li.length; i++) {
  li[i].style.background = arr[i % arr.length];
  li[i].onmouseover = function () {
    str = this.style.background; // 先存颜色
    this.style.background = 'gray';
  };
  li[i].onmouseout = function () {
    this.style.background = str;
  };
}

重點思路:

1、同一li切換:使用開關on;
2、多個li切換:點擊時,先for清空所有li[i],再當前添加li[this.index]添加事件;

如:

var on = true;
for (var i = 0; i < li.length; i++) {
  li[i].index = i;
  li[i].style.background = arr[i % arr.length];
  li[i].onmouseover = function () {
    str = this.style.background; // 先存颜色
    this.style.background = 'gray';
  };
  li[i].onmouseout = function () {
    this.style.background = str;
  };
  li[i].onclick = function () {  //1、每次點擊時當前變黑色,先還原所有顏色,再當前添加黑色
    for (var i = 0; i < li.length; i++) {
      li[i].style.background = arr[i % arr.length];
    }
    this.style.background = '#000'
    for (var i = 0; i < li.length; i++) { //2、每次點擊時當前over/out事件去除,所以是先for還原所有事件,再當前去除事件 li[this.index]
      li[i].onmouseover = function () {
        str = this.style.background; // 先存颜色
        this.style.background = 'gray';
      };
      li[i].onmouseout = function () {
        this.style.background = str;
      };
    }
    li[this.index].onmouseover = li[this.index].onmouseout = null;
  }
}

&&與 、||或、!或
10 < 80 && 23 < 100 ,左邊必須成立才會看右邊

var a = 100>30 && 40
alert(a) //40
var a = 100<30 && 40
alert(a) //false

10 < 80 || 23 < 100 ,左邊成立,則不會看右邊;都不成立返回false

var a = 100>30 || 40
alert(a) // true
var a = 100<30 || 40
alert(a) // 40
var str = ''
alert(!!str) //false,//雙否表示:第一個先轉數據為boolean值,再取反;

反選小例子

var inp = document.getElementsByTagName('input')
inp[0].onclick = function () {
  for (var i = 1; i < inp.length; i++) {
    inp[i].checked = !inp[i].checked
  }
}

流程控制:
判斷:if switch (case break default) ?:
循環: while for
跳出:break continue

var str = 'js'
switch( str ){
    case 'js': alert('js');break;
    case 'html': alert('html');break;
    default: alert(str);
}
//break不加,則執行完後會繼續執行,直到遇見break或執行完所有
if(a<10){alert(a)}else{{alert(b)}}

a<b ? alert(a) : alert(b);
var i = 0;
while(i<3){
alert(i);
i++;
}

for(var i=0;i<6;i++){
    if(i==4){
        break; //跳出for,停止執行
    }
    alert(i)   // 0 1 2 3 
}   
//最後循環外的i = 4

for(var i=0;i<6;i++){
    if(i==4){
        continue ; //跳過這一次循環for
    }
    alert(i)  //0 1 2 3 5 
}
//最後循環外的i = 6


真假:數據類型-數字(NaN)、字符串、布爾、函數、對象{elem、[]、{}、null}、undefined

真:非0數字(正負數、小數)、非空字符串、true、函數、能找到的元素、[]、{}、
假:0、NaN、空字符串('')、false、不能找到的元素、null、undefined


return返回值

函數名() = return後面的內容

//return 函數
fn2()
function fn2(){
    return function(){
    alert(1)
}
}
fn2()() //彈出1

//return 對象
fn3().onload = function(){document.body.innerHTML = 123};function fn3(){return window}

//例如
function $(id) {
  return document.getElementById(id)
}

//簡單模擬$
function $(v) {
  if (typeof v === 'function') {
    window.onload = v;
  } 
  else if (typeof v === 'string') {
    return document.getElementById(v)
  } 
  else if (typeof v === 'object') {
    return v;
  }
}
$(function(){
    $('btn').onclick = ....
        $(this)....
})

alert(fn());
function fn(){
    return; //默認返回值為undefined;
}

function fn(){
    return 123;
        alert('無法彈出')
}
/*
1、函數名() = return 後面的值;
2、所有函數默認返回值:未定義;
3、return後任何代碼都不執行;
*/

函數內部: function fn(){ this return arguments event ...}
實參: fn(1,2,3)
形參: arguments ----- [實參的集合],無數組的方法
當函數參數個數無法確定時,使用arguments

fn(1,2,3)
function fn(){
    alert(arguments)  //object arguments
    alert(arguments.length)  //3
    alert(arguments[0]) //1
}
//小應用:當函數參數個數無法確定時,使用arguments
sum(1,2,3....'+')
function sum() {
  var n = 0;
  for (var i = 0; i < arguments.length - 1; i++) {
    if (arguments[arguments.length - 1] == '+') {
      n += arguments[i]
      alert(1)
    } 
    else if (arguments[arguments.length - 1] == '-') {
      n -= arguments[i]
    }
  }
  return n
}
//arguments 能讀也能寫,實參的集合
var a = 1;
function fn2(a){
    arguments[0] = 3 //arguments[0] = a
    alert(a);  //3
    var a =2
    alert(arguments[0])
}
fn2(a); //2
alert(a)  //1


獲取瀏覽器最終計算後樣式 :
1、getComputedStyle(obj).width IE9+
2、obj.currentStyle.width IE8-
注意:適用範圍 width height opacity backgroundColor zIndex marginRight ...只要有空格,全部undefined
另:不要去獲取未設置後的樣式 ;
FF4.0以前 getComputedStyle($('div'),4.0以前可以跟任何參數才有反應).width);


function getStyle(obj, attr) {
  return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj) [attr]
}

零JS筆記 | 作用域

瀏覽器:
JS解析器,在域內,一定會有兩步
1)找東西: var function 參數
2)逐行解讀代碼 [碰到script,及fn,會解析執行]

什麼是域: script 全局變量、全局函數

alert(a);
var a = 1;
function fn(){ alert(a) }

//1)找東西 找var function 參數
    a = undefined  //如果var去掉,則js解析器為空,所以a is not defined
    fn = function fn(){ alert(a) } (在倉庫內存放)
//2)逐行解讀代碼
    alert(a); 倉庫內為未定義
    var a = 1 ; (看見表達式:= + - * / % ++ -- 參數;)(把倉庫內的a = undefined 改為 a = 1) 
alert(a); //function a() { alert(4) 
var a = 1;
alert(a); //1
function a() { alert(2) ;}
alert(a); //1
var a = 3; //
alert(a); //3
function a() { alert(4) } 
alert(a); //3


//1)找東西 找var function 參數
  //a = undefined
    a = function a() { alert(2) } //又找到a,是函數,變量與函數重命,則只留函數
  //a = undefined                 //重命,只留下函數
    a = function a() { alert(4) } //遇到函數,前面被覆蓋;(存到倉庫裏只有這一行)
//2)逐行解讀代碼
    alert(a); //倉庫裏有 a = function a() { alert(4) } 
    var a = 1; //出現表達式,a被修改為 a = 1;
    function a() { alert(2) ;}  //函數聲明,不是表達式,所以不改東西 a = 1
    alert(a);  //所以1
    var a = 3     //出現表達式,a被修改為 a = 3;
    alert(a);  //所以是a = 3
    function a() { alert(4) }  ////函數聲明,不是表達式,所以不改東西 a= 3
    alert(a) //a = 3 //倉庫裏無函數了,所以若:
    a() //相當於 3(),報錯!
//域是分開執行的 先後順序,自上而下
<script> alert(a) </script>      // a is not defined 
<script> var a = 1 </script>
var a = 1;
function fn(){
    alert(a);
    var a = 2;
}
fn();
alert(a);

//1)找東西 找var function 參數
    a = undefined
    fn = function fn() { alert(a);var a = 2; }                 
//2)逐行解讀代碼
    a = 1;
    fn(); //1
           //1)找東西 找var function 參數  
               var a = 2  //a = undefined; // a为局部變量 ,與外面的a無關係 所以只在局部倉庫裏;
           //2)逐行解讀代碼
                a = 2;    //局部垃圾回收機制回收
    alert(a) //1 全局倉庫裏
var a = 1;
function fn(){
    alert(a);
    a = 2;  //去掉var,相當於改全局倉庫裏的值;
}
fn(); //1
alert(a); //2
var a = 1;
function fn(a){  //加參數
    alert(a); //往上找到參數a,到達不了 var a = 1; 所以預解析a = undefined
    a = 2;   //局域的a被改為a = 2,執行完後銷毀
}
fn(); //局部a = undefined
alert(a); //全局a = 1
var a = 1;
function fn(a){ 
    alert(a); 
    a = 2; 
}
fn(a);//執行時傳參進來 所以1
alert(a); //1
//獲取fn內的值方法一:

var str = ''         //1、定義
function fn(){
    var a = 'pig'
    str = a         //2、str 拿到
}
fn(); /////////////////////////////////////////     3、一定要執行;
alert(str)         //4、可找到pig
//获取fn内的值方法二:

function fn2(){
    var a = 'MM';
    fn3(a);
}
fn2()
function fn3(e){ //调用参数接收
    alert(e);  //e = a = 'MM'
}

写代码注意事项:
1、if条件判断非作用域;如下代码,但ff不能对下面的函数进行预解析;兼容性问题,所以若需定义全局变量或全局函数,不要在if或for循环里定义!

//不要這麼寫:
alert(a);  //undefined正常
alert(fn)  //if非作用域,理论上应该弹出整个fn内容chrome,但在ff上:fn is not defined
if(true){
  var a = 1
  function fn(){
    alert(123)
  }
}

//需這麼寫,變量與函數定義在if或for 外面
alert(a);  //undefined正常
alert(fn)  // function fn(){alert(123)}
  var a = 1
  function fn(){
    alert(123)
  }
if(true){
}
var btn = document.getElementsByTagName('input')
for (var i = 0; i < btn.length; i++) { //一個循環
  btn[i].onclick = function () {
    for (var i = 0; i < btn.length; i++) { //點擊每一個時,循環三次,正常
      btn[i].style.background = 'red'
    }
  }
}
for (var i = 0; i < btn.length; i++) { //一個循環3
  btn[i].onclick = function () {
    alert(i) //i = 3,執行完for後才點擊,i向上找,所以是3;
  }
}
for (var i = 0; i < btn.length; i++) { //一個循環3
  btn[i].onclick = function () { //這一塊是作用域,下面有var = 0,所以最開始 彈 i = undefined
    alert(i) // undefined
    for (var i = 0; i < btn.length; i++) { //如去掉var,則上面的i 必須往上找
      btn[i].style.background = 'red'
    }
  }
}

零JS筆記 | 數據類型

JS中的數據類型:number(NaN) string boolean function object(fn,[],{},null) undefined

var str = 'abc';
str.charAt(3) //下標

var obj = window; //object

var arr = [1] //
console.log(typeof arr); //object

function fn() {
  alert(this)
}
console.log(typeof fn); //function

obj.fn1 = function () {
  alert(1)
}
console.log(typeof obj.fn1); //object

var json = {
  name: 'elmok'
}
console.log(typeof json); //object

var u;
alert(u) //undefined 表示一種狀態
alert(typeof u) //undefined

顯式類型轉換:Number(),parseInt(),parseFloat()

//字符串轉數字 Number()
//可轉換的類型
var a = '100'
alert(a + 100) // '100100'

alert(Number(a) + 100) // 200

var b = '000100';
alert(Number(b)) //100

var c = '+100'
alert(Number(c)) //100

var d = ''; //d = '   '
alert(Number(d)); //0

var e = true
alert(Number(e)) //1

var arr = [] //['']-->0   [1,2,3]-->NaN  ['123']-->123
alert(Number(arr)) //0

var f = null
alert(Number(f)) // 0

//可轉換類型:parseInt(),parseFloat()
var i = '100px'
alert(parseInt(i)) //100,從左到右查看,若有非數字,則截斷;

var j = '+100'
alert(parseInt(j)) //從左到右,如遇到 + - 空格,則例外

var l = '100px'
alert(parseInt(l, 8)) // parseInt(l,進制)

var k = '10.1231231231元'
alert(parseFloat(k)) // 10.1231231231
//判斷是否有帶小數點  parseInt(n) == parseFloat(n)

無法轉換的數據類型:

1、NaN: not a number //不是數字 的 數字類型;
2、出現NaN表示進行了非法的操作;
3、NaN ==> false;
4、自已不等於自己;
5、isNaN 不是數字 返回true, 數字返回false
6、isNaN內部依靠Number()轉換

var fn = function () {
}
alert(Number(fn)) //NaN

var json = {
} //json無法轉

alert(Number(json)) //NaN

var g; //undefined
alert(Number(g)) //NaN

var h = '100px'
alert(Number(h)) //NaN

var o = Number('abc')
alert(o) //NaN

alert(typeof NaN) // number

//isNaN 不是數字 返回true,  是數字返回false ,即Number()能轉換的
alert(isNaN(123)) //false
alert(isNaN('abc')) //true
alert(isNaN(function () {
  alert(1)
})) //true
alert(isNaN('250')) //false ,使用Number('250')轉成250數字後返回false
alert(isNaN(true)) // false
alert(isNaN([])) //false
alert(isNaN(NaN)) //true

inp[1].onclick = function () {
  if (isNaN(inp[0].value)) { //有缺陷,如輸入 空格、true false
    alert('不是數字')
  } 
  else {
    alert('是數字')
  }
}

if (NaN) {
  alert('真')
} 
else {
  alert('假')
}

隱式類型轉換: - * / % 可讓字符串變成數字 + 可讓數字變成字符串 ++ -- 變成數字 > < 數字比較,字符串比較 !轉成布爾值 ==

alert(100 - '1') //99
alert('100' + 1) // 101
var n = '10'
alert(n++) //11
alert('10' > 5) // true '10'被轉成數字10
alert('10' < '5') // true 編碼位置比較
alert(!true) //false
alert(!'ok') //false
alert('2' == 2) //true

小技巧:

找字符:判斷typeof == 'string';
找數字:判斷typeof=='number' && 排除屬性NaN的數字類型:!isNaN(obj)
找可以轉成數字的:parseFloat(arr[i])==parseInt(arr[i])
找NaN:判斷typeof==='number' && 並且屬性不是數字:isNaN(obj)
var arr = [ '100px', 'abc'-6, [], -98765, 34, -2, 0, '300', , function(){alert(1);}, null, document, [], true, '200px'-30,'23.45元', 5, Number('abc'), function(){ alert(3); }, 'xyz'-90 ]

//找到數字,排除布爾值
for (var i = 0; i < arr.length; i++) { 
  if ((typeof arr[i]) == 'number' && !isNaN(arr[i])) {
    console.log(arr[i])
  }
}
//parseFloat会干掉0  所以要加上
var arrN = []
for (var i = 0; i < arr.length; i++) {
  if (parseFloat(arr[i]) == parseInt(arr[i])) {
    console.log(arr[i]);
    arrN.push(arr[i])
  }
}
console.log(Max(arrN));
function Max(arr) {
  var max = arr[0];
  for (var i = 0; i < arr.length; i++) {
    if (max < arr[i]) {
      max = arr[i]
    }
  }
  return max
}
//找字符串
for (var i = 0; i < arr.length; i++) {
  if (typeof arr[i] === 'string') {
    console.log(arr[i])
  }
}
//找到數字類型,並且是NaN
for (var i = 0; i < arr.length; i++) {
  if (typeof (arr[i]) == 'number' && isNaN(arr[i])) {
    console.log(i + ':' + arr[i]);
  }
}

零JS筆記 | 最簡單的圖片切換 | index

最簡單的圖片切換一

window.onload = function () {
  var _prev = document.getElementById('prev'),
  _next = document.getElementById('next'),
  _txt = document.getElementById('txt'),
  _count = document.getElementById('count'),
  _img = document.getElementById('img'),
  num = 0,
  imgDate = {
    txt: ['校園美女一','校園美女二','校園美女三',
      '校園美女四','校園美女五','校園美女六'],
    img: ['../img/jc1.png','../img/jc2.png','../img/jc3.png',
        '../img/jc4.png','../img/jc5.png','../img/jc6.png']
  }
  //初始化

  tabImg()
  var len = imgDate.txt.length;
  _next.onclick = function () {
    num++;
    if (num == len) {
      num = 0;
    }
    tabImg()
  }
  _prev.onclick = function () {
    num--;
    if (num == - 1) {
      num = len - 1
    }
    tabImg()
  }
  function tabImg() {
    _txt.innerHTML = imgDate.txt[num];
    _count.innerHTML = (num + 1) + '/' + len;
    _img.src = imgDate.img[num];
  }
}

運行



最簡單的圖片切換二

注意:this指向;

步驟:初始化,寫循環每一個,合並函數[num = this.index;tab()],注意this指向;

on切換:1、全清空,當前添加;2、創建上一個狀態變量:prevLi = null; 清空上一個

for (var i = 0; i < lis.length; i++) {
  lis[i].className = '' //全清空
}
this.className = 'on'//當前添加

var prevLi = null; 
prevLi = li[num]; //先存上一個狀態;
prevLi.className = '' //點擊時把上一個狀態清除
prevLi = this; //再把當前付給上一個,形成循環
this.className = 'on' //當前添加

運行



菜單收縮

1、關鍵在於找元素;配合index,找到每一個h2,對應自已的ul;

2、每一個ul下,對應自己的li,即需要for套for;

3、for套for中,有fn的,不需要改i,無fn的,需要改變j;

4、判斷的方法,this.className = '';

5、找到li,因事件一致,可先存在數組裏,以數組來操作;

<ul id='list'>
    <li>
        <h2>aaaaaa</h2>
        <ul>
            <li> a-a-a-a-a-a</li>
            <li> a-a-a-a-a-a</li>
            <li> a-a-a-a-a-a</li>
        </ul>
    </li>
    .....
</ul>
var list = document.getElementById('list')
var h2 = document.getElementsByTagName('h2')
var _ul = list.getElementsByTagName('ul')
var _li = null;
var arrLi = [
];
var on = true;
for (var i = 0; i < h2.length; i++) {
  h2[i].index = i; //索引值對應 每個 h2 -> ul
  h2[i].onclick = function () {
    if (this.className == '') {
      //1、當前展開,其他收縮
      for (var i = 0; i < _ul.length; i++) {
        _ul[i].style.display = 'none'
        h2[i].className = ''
      }
      _ul[this.index].style.display = 'block'
      this.className = 'on'
    } 
    else {
      _ul[this.index].style.display = 'none'
      this.className = ''
    }
  }
}
for (var i = 0; i < _ul.length; i++) { //找到所有h2下 ul
  _li = _ul[i].getElementsByTagName('li') //找到所有li
  for (var j = 0; j < _li.length; j++) {
    arrLi.push(_li[j]); //所有li存放在arrLi裏
  }
}

//for 套for ,內部的fn,可不改i,無fn,必須改i
for (var i = 0; i < arrLi.length; i++) { //操作數組,即相當於操作li
  arrLi[i].onclick = function () {
    //2、當前點擊取消
    if (this.className == '') {
      for (var i = 0; i < arrLi.length; i++) {
        arrLi[i].className = ''
      }
      this.className = 'hover'
    } 
    else {
      this.className = ''
    }
  }
}

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


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

簡單系統時間

var nowTime = new Date();//typeof object
下面出來的都數字類型:number
nowTime.getFullYear() //年
nowTime.getMonth() + 1 //月 從0開始算,所以需加1
nowTime.getDate() //日
nowTime.getDay() //星期
nowTime.getHours() //時
nowTime.getMinutes() //分
nowTime.getSeconds() //秒

Time()
setInterval(Time, 1000)
function Time() {
  var nowTime = new Date(); //typeof object
  var _year = nowTime.getFullYear();
  var _month = nowTime.getMonth() + 1;
  var _date = nowTime.getDate();
  var _week = nowTime.getDay();
  var _hours = nowTime.getHours()
  var _minutes = nowTime.getMinutes();
  var _seconds = nowTime.getSeconds();
    switch (_week){
        case 0:_week='星期日';break;
        case 1:_week='星期一';break;
        case 2:_week='星期二';break;
        case 3:_week='星期三';break;
        case 4:_week='星期四';break;
        case 5:_week='星期五';break;
        case 6:_week='星期六';
    }
  document.body.innerHTML = _year + '年' + _month + '月' + _date + '日  ' + _week + ' ' + toTwo(_hours) + ':' + toTwo(_minutes) + ':' + toTwo(_seconds);
}
function toTwo(n) {  //單數轉雙數
  return n = n < 10 ? '0' + n : '' + n;
}

圖片日期要點:日期共6位,使用str.charAt(i)獲取每一位數字,與圖片名字相對應

str = toTwo(_hours)+toTwo(_minutes)+toTwo(_seconds);
for(var i=0;i<str.length;i++){
    img[i].src = '../img/timePic/'+ str.charAt(i)+'.JPG'
}

運行

倒計時:
設置時間形式:
數字形式:new Date(2013,6,22,01,19,54)
字符串形式:new Date('June 10,2013 12:01:20')
思想:(未來時間 - 當前時間)/1000 = t //秒

套用

天:Math.floor(t/86400)
時:Math.floor(t%86400/3600)
分:Math.floor(t%86400%3600/60)
秒:t%60
Math.floor(t/86400)+'天'+ Math.floor(t%86400/3600)+'時'+ Math.floor(t%86400%3600/60)+'分'+t%60+'秒'

一月:January 简写Jan.
二月:February 简写Feb.
三月:March 简写Mar.
四月:April 简写Apr.
五月:May 简写May.
六月:June 简写Jun.
七月:July 简写Jul.
八月:August 简写Aug.
九月:September 简写Sep. / Sept.
十月:October 简写Oct.
十一月:November 简写Nov.
十二月:December 简写Dec.
開始時間:<input type="text" value="August 29,2015 1:39:59"/>
剩余時間:<input type="text"/>
<input type="button" value="Start"/>
var nowTime = new Date();
//var newTime = new Date(2013, 5, 22, 1, 39, 59);
var newTimeE = new Date('August 29,2014 1:39:59')
var t = Math.floor((newTimeE - nowTime) / 1000); //newTime - nowTime 毫秒單位 t為秒
var str = Math.floor(t / 86400) + '天' + Math.floor(t % 86400 / 3600) + '時' + Math.floor(t % 86400 % 3600 / 60) + '分' + t % 60 + '秒'
var inp = document.getElementsByTagName('input')
var inow = null;
var inew = null;
var timer = null;
inp[2].onclick = function () {
  clearInterval(timer)
  inew = new Date(inp[0].value)
  timer = setInterval(function () {
    inow = new Date();
    var tt = Math.floor((inew - inow) / 1000);
    if (tt >= 0) {
      var str = Math.floor(tt / 86400) + '天' + Math.floor(tt % 86400 / 3600) + '時' + Math.floor(tt % 86400 % 3600 / 60) + '分' + tt % 60 + '秒'
      inp[1].value = str;
    } 
    else { //倒計時完成後動作
      clearInterval(timer)
    }
  }, 1000)
}

new Date().getTime() //時間戳:1970年1月1日0點0分0秒0毫秒 距離現在多長時間,毫秒為單位