Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Jul 8, 2009

javascript基本类型和对象类型

基本类型

对象类型 object

对象类型 Array

对象类型 DOM

Apr 18, 2009

Javascript跨域传递JSON

Javascript无法跨域访问,这是Javascript的安全机制,跨域访问的定义可以这么说,www.google.com域下的脚本不能访问www.amazon.com域,www.google.com当然也不能访问子域名site.google.com域。JS如果要跨域访问数据,AJAX的http请求跨域数据会报错。如果需要用JS请求跨域的数据,JSON是很好的选择。跨域获取JSON并不是异步请求,而是应用script标签的src属性获取到服务器生成的JSON格式化文本,例:

<script type="text/javascript">
function jsonCallback(resp) { //jsonCallback是下面script标签回调的,resp将返回的JSON作为参数传递
  var entris =  resp.feed.entry
}
</script>
<script type="text/javascript" src="http://fanlog.blogspot.com/feeds/posts/default/?max-results=10&start-index=1&alt=json-in-script&callback=jsonCallback"></script>

script标签src的地址,是blogger API返回的JSON格式化数据,数据格式如下:

jsonCallback({"feed":["content",{"$t":"第一个标题"}],["content",{"$t":"第二个标题"}], .....

JSON数据格式可以像访问JS对象一样去访问,例如jsonCallback.feed[0].content.$t返回的值就是"第一个标题","[]"符号表示数组对象,访问第二个"[]"即为jsonCallback.feed[1]。

jQuery有一个getJSON()的方法可以直接访问JSON数据。prototype貌似米有。

Feb 26, 2009

可持续访问的AJAX

《ppk on Javascript》书中谈到Javascript的目的,Javascript其实是为web增加特别的一层可用性,我的理解Javascript的在web中的角色是增加web的易用性,让用户更好的体验web产品,开发者在设计产品时,就应该考虑到不同用户的复杂情况,例如禁用脚本的用户、盲人、手持设备用户等等。

创建可持续访问性的web,也可以如上理解,具体在开发中的细节如下:

  • a链接一定有href地址,页面分离事件注册器,决绝行内时间注册(例如<a href="#" onclick="func();">)
  • 有选择性的使用Javascript和CSS隐藏页面内容1
  • 不用Javascript做页面跳转,否则用户使用浏览器的后腿按钮将无限制跳转,最终只能强迫用户推出页面,这样的体验真的很糟糕,我想至少我收够了这样的方式;
  • 务必考虑脚本兼容主流的浏览器,招商银行的网银和之前淘宝的支付宝不支持Firefox就是例子,用户抱怨很囧

另外,记录一下以前开发中的小技巧:

当我们希望点击一个a链接,然后用一个DIV的popup容器来呈现内容而不刷新页面时,使用AJAX如果做到持续的可访问性呢?首先,来思考一下无脚本的情况下,这个a链接的地址一定是能够访问的,访问的页面应该是完整的页面(有head和foot),而不是HTML片段。然后,再思考一下有脚本情况下,我们给a链接注册一个事件func,事件func完成一个AJAX请求,把a链接的href地址通过异步获取到当前页面,并且创建一个DIV作为popup容器,那么这个popup容器内被请求的HTML不应该显示head和foot部分(HTML片段)。那么,现在的问题是,如果判断当a链接分别在有脚本、无脚本的的情况下,显示或者不显示页面的head、foot部分呢?如下:

当脚本可用时,我们在func里给a链接加上一个参数"popup":

<a href="http://www.site.com/site.php">Click</a>//页面静态地址
<a href="http://www.site.com/site.php?popup=1">Click</a>//JS给a href添加“&popup=1”

那么现在当为AJAX请求页面时,a href带有一个popup=1的参数,当无脚本时,a href无popup=1的参数,这个参数有什么用呢?popup=1这个参数可以交给服务器脚本,服务器脚本判断当页面上有popup这个值时,就不编译head和foot的HTML,没有这个popup这个值,服务器脚本就编译head和foot的值。

以上这种方法,美味书签用到很多,有兴趣的可以登录体验一下美味书签的一些操作(删除、编辑),操作方法就是禁用脚本,或者对美味书签的删除、编辑按钮用新窗口打开。

有选择性的选择JS或者CSS隐藏内容,分情况例如:JS驱动的下拉菜单,禁用脚本用户是无法浏览到被隐藏的菜单,那么菜单的隐藏内容应该用JS隐藏,当无脚本的情况下,JS隐藏菜单的功能自然也无法工作,那么禁用脚本的用户自然也可以浏览到本该隐藏的菜单列表

Feb 22, 2009

获取鼠标位置

获取鼠标位置,就是获取event对象的坐标属性,先看看如何获取event对象。在W3C的模型中,把参数传递的第一个参数当作当前的event对象,在MSIE的模型中,总是window.event。

function myfunc(e) {
  var e = e || window.event;//如果e不存在,则获取window.event
}

event对象的坐标属性pageX, pageY分别是当前鼠标相对body的X, Y的坐标值,但是在IE中没有pageX和pageY,不过可以通过clientX, clientY加上scrollTop, scrollLeft的值来确定当前鼠标的位置。clientX, clientY是当前鼠标相对window的坐标值。代码:

function mouseCoords(e){
 if(e.pageX || e.pageY){//标准浏览器返回当前鼠标坐标值
  return {x:e.pageX, y:e.pageY};
 }
 else if(e.clientX || e.clientY) {//仅IE返回回当前鼠标坐标值
  return {
   x:(e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft),
   y:(e.clientY + document.documentElement.scrollTop  + document.body.scrollTop)
  }
 }
}
function mouseMove(e){
 e = e || window.event;
 var mousePos = mouseCoords(e);//这里mousePos.x, mousePos.y分别为鼠标的X, Y坐标值
}

以上代码中发现一个兼容性问题,如果文档声明为XHTML,document.body.scrollTop的值始终为0,所以在XHTML文档声明的时候,只能用document.documentElement.scrollTop。

Jan 8, 2009

[转]scrollLeft,scrollWidth,clientWidth等详解

  • scrollHeight: 获取对象的滚动高度。
  • scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
  • scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
  • scrollWidth:获取对象的滚动宽度
  • offsetHeight:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度
  • offsetLeft:获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
  • offsetTop:获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置
  • event.clientX 相对文档的水平座标
  • event.clientY 相对文档的垂直座标
  • event.offsetX 相对容器的水平坐标
  • event.offsetY 相对容器的垂直坐标
  • document.documentElement.scrollTop 垂直方向滚动的值
  • event.clientX+document.documentElement.scrollTop相对文档的水平座标+垂直方向滚动的量

以上主要指IE之中,FireFox差异如下:

IE6.0、FF1.06+:

  • clientWidth = width + padding
  • clientHeight = height + padding
  • offsetWidth = width + padding + border
  • offsetHeight = height + padding + border

IE5.0/5.5:

  • clientWidth = width - border
  • clientHeight = height - border
  • offsetWidth = width
  • offsetHeight = height

(需要提一下:CSS中的margin属性,与clientWidth、offsetWidth、clientHeight、offsetHeight均无关)

用隐藏的iframe提交表单

AJAX无法上传文件是很头疼的事情,不过我们可以用隐藏在页面上的iframe提交,这里讨论的是用iframe提交表单之后,如果获取返回数据。

HTML代码片断:

form method="post" action="upload_file" target="hiddenFrame">

form的target指向iframe,通过iframe提交表单

Javascript代码:

function uploadFile() {
  $('hiddenFrame').onreadystatechange = $('hiddenFrame').onload = function() {
      if(this.readyState && this.readyState!= 'complete') {return;} //readyState判断iframe内容是否改变

      //获取iframe dom
      var frameBody = top.frames[0];
      if(!frameBody) return;
      frameBody = frameBody.document;
      if(!frameBody) return;        
      frameBody = frameBody.getElementsByTagName('body');
      if(!frameBody) return;
      frameBody = frameBody[0];
      if (!frameBody) return;
  }
}

以上代码是通过DOM获取iframe的body下返回的数据,数据可以是文本,也可以是JSON格式,如果是JSON格式,就需要evel()来解释。这种方法是在页面上写静态的iframe,复杂一点可以在页面上用JS创建iframe,不过考虑到可用性,建议还是在页面上写静态的iframe。

封装鼠标跟随tips

刚学习prototype.js的时候写的一个鼠标跟随提示的代码,后来在项目中发现一个很严重的问题,暂时没有修正。代码基于prototype.js v1.6。

代码打包下载

Javascript代码:

function handleTips(idElement) {
    this.handleBtn = (typeof idElement == 'string')? $(idElement) : idElement;
    this.popuptips = (typeof idElement == 'string')? $(idElement + "-tips") : idElement.id + "tips";
   
    this.handleBtn.onmouseover = this.showTips.bind(this);
    this.handleBtn.onmouseout = this.hiddenTips.bind(this);
    this.handleBtn.onmousemove = this.cursorPosition.bind(this);
}

handleTips.prototype.showTips = function() {
 //debugger;
 Element.show(this.popuptips);
 this.cursorPosition(arguments[0]);
}

handleTips.prototype.hiddenTips = function() {
        Element.hide(this.popuptips);
}

handleTips.prototype.cursorPosition = function(){
 
    var event = arguments[0] || window.event;
    this.arrPageSize = getPageSize();
    this.pageWidth = this.arrPageSize.PageWidth;
    this.pageHeight = this.arrPageSize.PageHeight;

   
    this.leftSpace = Event.pointerX(event) + 20;
    this.topSpace = Event.pointerY(event) + 20;

    this.rightSpace = this.pageWidth - this.leftSpace;
    this.bottomSpace = this.pageHeight - this.topSpace;
   
    this.tipsWidth = this.popuptips.getWidth();
    this.tipsHeight = this.popuptips.getHeight();

   
    if (this.tipsWidth < this.rightSpace && this.tipsHeight < this.bottomSpace) {
        this.popuptips.setStyle({
            left: Event.pointerX(event) + 20 + "px",
            top: Event.pointerY(event) + 20 + "px"
        });
    } else if(this.tipsWidth > this.rightSpace && this.tipsHeight < this.bottomSpace) {
        this.popuptips.setStyle({
            left: Event.pointerX(event) - this.tipsWidth - 20 + "px",
            top: Event.pointerY(event) + 20 + "px"
        });
    } else if(this.tipsWidth < this.rightSpace && this.tipsHeight > this.bottomSpace) {
        this.popuptips.setStyle({
            left: Event.pointerX(event) + 20 + "px",
            top: Event.pointerY(event) - this.tipsHeight - 20 + "px"
        });
    } else if(this.tipsWidth > this.rightSpace && this.tipsHeight > this.bottomSpace) {
        this.popuptips.setStyle({
            left: Event.pointerX(event) - this.tipsWidth - 20 + "px",
            top: Event.pointerY(event) - this.tipsHeight - 20 + "px"
        });
    }
}


function getPageSize() {
    var scrW, scrH;
    if(window.innerHeight && window.scrollMaxY) {
        // Mozilla
        scrW = window.innerWidth + window.scrollMaxX;
        scrH = window.innerHeight + window.scrollMaxY;
    } else if(document.body.scrollHeight > document.body.offsetHeight){
        // all but IE Mac
        scrW = document.body.scrollWidth;
        scrH = document.body.scrollHeight;
    } else if(document.body) {
        // IE Mac
        scrW = document.body.offsetWidth;
        scrH = document.body.offsetHeight;
    }
   
    var winW, winH;
    if(window.innerHeight) {
        // all except IE
        winW = window.innerWidth;
        winH = window.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) {
        // IE 6 Strict Mode
        winW = document.documentElement.clientWidth;
        winH = document.documentElement.clientHeight;
    } else if (document.body) { // other
        winW = document.body.clientWidth;
        winH = document.body.clientHeight;
    }
   
    // for small pages with total size less then the viewport
    var pageW = (scrW < winW) ? winW : scrW;
    var pageH = (scrH < winH) ? winH : scrH;
   
    return {PageWidth:pageW, PageHeight:pageH, WinWidth:winW, WinHeight:winH};
}

Event.observe(window, 'load', function() {new handleTips('note')});

CSS代码:

.tips {
    position: absolute;
    z-index: 9999;
    padding: 5px;
    background-color: #FFFFFF;
    border: 1px solid #FF6600;
}

#note {
 margin: 100px 0 0 300px;
}

#note-tips {
 width: 120px;
}