2013年10月

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