Javascript File API for Mozilla

1. 文件读取函数
readAsBinaryString() 读取文件内容,读取结果为一个 binary string。文件每一个 byte 会被表示为一个 [0..255] 区间内的整数。函数接受一个 File 对象作为参数。
readAsText() 读取文件内容,读取结果为一串代表文件内容的文本。函数接受一个 File 对象以及文本编码名称作为参数。
readAsDataURL 读取文件内容,读取结果为一个 data: 的 URL。DataURL 由 RFC2397 定义,具体可以参考 http://www.ietf.org/rfc/rfc2397.txt。

2. 文件读取事件
Onloadstart 文件读取开始时触发。
Progress 当读取进行中时定时触发。事件参数中会含有已读取总数据量。
Abort 当读取被中止时触发。
Error 当读取出错时触发。
Load 当读取成功完成时触发。
Loadend 当读取完成时,无论成功或者失败都会触发。

<form name="demoForm" id="demoForm" method="post" enctype="multipart/form-data" 
onsubmit="uploadAndSubmit();return false;"> 
<p>Upload File: <input type="file" name="file" /></p> 
<p><input type="submit" value="Submit" /></p> 
</form> 
<div>Progessing (in Bytes): <span id="bytesRead"> 
</span> / <span id="bytesTotal"></span> 
</div>
  function uploadAndSubmit() {
    var form = document.forms["demoForm"]; 
 
     if (form["file"].files.length > 0) {
     // 寻找表单域中的 <input type="file" ... /> 标签
     var file = form["file"].files[0];
     // try sending
     var reader = new FileReader(); 
 
     C.log(reader);
     reader.onloadstart = function() {
     // 这个事件在读取开始时触发
     C.log("onloadstart");
     document.getElementById("bytesTotal").textContent = file.size;
     }
     reader.onprogress = function(p) {
     // 这个事件在读取进行中定时触发
     C.log("onprogress");
     document.getElementById("bytesRead").textContent = p.loaded;
     } 
 
     reader.onload = function() {
        // 这个事件在读取成功结束后触发
        console.log("load complete");
     } 
 
     reader.onloadend = function() {
        // 这个事件在读取结束后,无论成功或者失败都会触发
     if (reader.error) {
        C.log(reader.error);
     } else {
        document.getElementById("bytesRead").textContent = file.size;
        C.log(reader.readyState);
     }
     } 
 
        reader.readAsBinaryString(file);
     } else {
        C.log("请选择上传文件");
     }
    }
 
    var C = {
    // console wrapper
    debug: true, // global debug on|off
    quietDismiss: false, // may want to just drop, or alert instead
    log: function() {
        if (!C.debug) return false;
 
        if (typeof console == 'object' && typeof console.log != "undefined") {
            console.log.apply(this, arguments);
        }
        else {
            if (!C.quietDismiss) {
                var result = "";
                for (var i = 0, l = arguments.length; i < l; i++)
                    result += arguments[i] + " ("+typeof arguments[i]+") ";
 
                var elem = document.createElement("textarea");
                elem.innerHTML = result;
				document.body.appendChild(elem);
                }
            }
        }
    }; // end console wrapper.

fileAPI Demo:fileAPI.zip

原文链接(136 views)|暂无评论(赶紧抢沙发)

函数的生成

function create(fun,proto){
    var f=function(){};
    //Copy the object since it is going to be changed.
    for (var x in proto){
        f.prototype[x] = proto[x];
    }
    f.prototype.toString = fun;
    return new f;
}
var fun=function(){alert("a");return "Hello world";}
var obj={x:5}
 
var foo=create(fun,obj);
alert(foo); //Hello world
foo.x=8;
alert(foo.x); // 8
delete foo.x;
alert(foo.x); // 5

原文链接(52 views)|评论 (2)

jQuery inViewport

晚上在微博上“拔赤”写了个lazyload插件,发现其中用到一个很有意思的方法”div.inViewportRegion()”,字面意思就是在可视区域内。

在网上找了找,发现这是YUI提供的一个组件,觉得很有意思。
http://gillserver.com/yui/api/dom-region.js.html

如果jQ里面也包含类似的方法,可以做很多事,于是GG了一下,发现国外的同学写过这种选择器,代码表现上更直观。

代码如下:

(function($) {
 
    $.belowthefold = function(element, settings) {
        var fold = $(window).height() + $(window).scrollTop();
        return fold < = $(element).offset().top - settings.threshold;
    };
 
    $.abovethetop = function(element, settings) {
        var top = $(window).scrollTop();
        return top >= $(element).offset().top + $(element).height() - settings.threshold;
    };
 
    $.rightofscreen = function(element, settings) {
        var fold = $(window).width() + $(window).scrollLeft();
        return fold < = $(element).offset().left - settings.threshold;
    };
 
    $.leftofscreen = function(element, settings) {
        var left = $(window).scrollLeft();
        return left >= $(element).offset().left + $(element).width() - settings.threshold;
    };
 
    $.inviewport = function(element, settings) {
        return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
    };
 
    $.extend($.expr[':'], {
        "below-the-fold": function(a, i, m) {
            return $.belowthefold(a, {threshold : 0});
        },
        "above-the-top": function(a, i, m) {
            return $.abovethetop(a, {threshold : 0});
        },
        "left-of-screen": function(a, i, m) {
            return $.leftofscreen(a, {threshold : 0});
        },
        "right-of-screen": function(a, i, m) {
            return $.rightofscreen(a, {threshold : 0});
        },
        "in-viewport": function(a, i, m) {
            return $.inviewport(a, {threshold : 0});
        }
    });
 
})(jQuery);

来源:http://www.appelsiini.net/projects/viewport

简单测了下,不错,呵呵~

Demo:http://www.zhangjingwei.com/inviewport.zip

原文链接(86 views)|暂无评论(赶紧抢沙发)

js ip地址转真实地址

新浪,有道,ip138提供了将ip地址转换为真实地址的接口,这个控件的作用就是将这些接口封装起来,实现js将ip地址转换为真实地址。

使用方法很简单,如有html

<div class="query_ip">202.103.22.1</div>

调用如下js

$(".query_ip").getaddress({
    type:"youdao" // 支持youdao|sina|ip138 (有道速度快且准确,新浪快,ip138较慢)
});

则将HTML修改为

<div class="query_ip">202.103.22.1 湖北省十堰市 东风电信</div>

具体JS源码如下

(function(){
    /*
     * 默认配置
     */
    var domainAddressConf = {
        source : {
            "sina":"http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=",
            "youdao":"http://youliao.sinaapp.com/app/getip.php?callback=?&type=youdao&ip=",
            "ip138":"http://youliao.sinaapp.com/app/getip.php?callback=?&ip="
        },
        type : null,
        charset : "gb2312"
    }
 
    function getAddress( self,conf ){
        var type = conf.type || "youdao",
            ipadress = conf.source[type] + self.text(),
            api = new getAddressApi( type,ipadress );
 
        api.ready(function( data ){
            self.append( data );
        })
 
        return self;
    }
 
    function getAddressApi( type,conf ){
        var root = this;
 
        this.changeData = function( data ){
            this.data = data;
            return this;
        }
 
        return new getAddressApi[type]( root,conf );
    }
 
    /*
     * 获取新浪ip数据
     */
    getAddressApi.sina = function( root,dataUri ){
 
        this.root = root;
 
        $.getScript(dataUri,function(){
            root.changeData(remote_ip_info);
        });
    }
    getAddressApi.sina.prototype = {
        ready: function( fn ){
            var self = this,
                data = self.root.data;
 
            setTimeout(function(){
                if( data ){
                    fn.call(document,"&nbsp;"+data.province+"省"+data.city+"市&nbsp;"+data.desc);
                }else{
                    self.ready(fn);
                }
            },13);
        }
    }
 
    /*
     * 获取搜狐ip数据
     */
    getAddressApi.youdao = function( root,dataUri ){
 
        this.root = root;
 
        $.getJSON( dataUri, function( data ){
            root.changeData(data);
        });
    }
    getAddressApi.youdao.prototype = {
        ready: function( fn ){
            var self = this,
                data = self.root.data;
 
            setTimeout(function(){
                if( data ){
                    fn.call(document,"&nbsp;"+data[0]);
                }else{
                    self.ready(fn);
                }
            },13);
        }
    }
 
    /*
     * 获取ip138数据
     */
    getAddressApi.ip138 = function( root,dataUri ){
        this.root = root;
 
        $.getJSON( dataUri, function( data ){
            root.changeData(data[0].replace("查询结果:",""));
        });
    }
    getAddressApi.ip138.prototype = {
        ready: function( fn ){
            var self = this,
                data = self.root.data;
 
            setTimeout(function(){
                if( data ){
                    fn.call(document,"&nbsp;"+data);
                }else{
                    self.ready(fn);
                }
            },13);
        }
    }
 
    $.fn.getaddress = function(conf) {
 
        // 判断是否已实例化
        if (this.data("domainaddress")) { return this; }
 
        // 配置
        conf = $.extend(true, {}, domainAddressConf, conf);
 
        this.each(function() {
            var el = new getAddress( $(this), conf );
            $(this).data("domainaddress", el);
        });
 
        return conf.api ? el : this;
    }; 
 
})(jQuery);

因为有道和ip138使用的是xml,为解决跨域,增加了一个php做中转,源码如下

	@header("Content-Type: text/html; charset=utf-8");
	$type = $_GET['type'];
	if( $type == "youdao" ){
		$xml_file_content = fopen_url("http://www.youdao.com/smartresult-xml/search.s?type=ip&q=".$_GET['ip']);
 
		$xml = simplexml_load_string( $xml_file_content );
 
		echo $_GET['callback'].'('.json_encode($xml->product->location).')';
 
	}else{
		$xml_file_content = fopen_url("http://wap.ip138.com/ip.asp?ip=".$_GET['ip']);
 
		preg_match_all( "/\<p \>((.|\n)*)\< \/p\>/s",$xml_file_content,$content );
 
		foreach( $content[1] as $result )
		{
			preg_match_all( "/\<b \>((.|\n)*)\< \/b\>/",$result, $location ); 
 
			echo $_GET['callback'].'('.json_encode($location[1]).')';
		}
 
	}
 
	//Curl 获取网址内容
	function fopen_url($url) 
	{ 
		if (function_exists('file_get_contents')) { 
			$file_content = @file_get_contents($url); 
		} elseif (ini_get('allow_url_fopen') && ($file = @fopen($url, 'rb'))){ 
			$i = 0; 
			while (!feof($file) && $i++ < 1000) { 
				$file_content .= strtolower(fread($file, 4096)); 
			} 
			fclose($file); 
		} elseif (function_exists('curl_init')) { 
			$curl_handle = curl_init(); 
			curl_setopt($curl_handle, CURLOPT_URL, $url); 
			curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT,2); 
			curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER,1); 
			curl_setopt($curl_handle, CURLOPT_FAILONERROR,1); 
			curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Trackback Spam Check'); 
			$file_content = curl_exec($curl_handle); 
			curl_close($curl_handle); 
		} else { 
			$file_content = ''; 
		} 
		return $file_content; 
	}

DEMO:http://www.zhangjingwei.com/getIp_0204_addip138_last.zip

原文链接(587 views)|评论 (2)

无限级菜单

随手写了一个,实现不复杂,只支持动态树。

如果要用的话,获取数据哪里做下简单的修改就可以了,这只是一个Demo。

  (function($){
 
	var jtree = {
		treeid : "jquery_tree_resource",
		treeclass : "tree",
		idname : "id",
		classname : "name",
		optionname : "options",
		openclass: "switch_roots_open",
		closeclass: "switch_roots_close",
		treeurl: ""
	}
 
	// constructor
	function tree(root, conf) {
		var self = root,
		cache = "",    // HTML缓存区
		current = null,    // 当前节点对象
		counter = 0;    // 层级计数器
 
		$.extend(self,{
			/*
			 * 初始化Html
			 * 设置固定的格式以及Id、Class
			 */
			init: function(){
				var el = root.append("< \ul>");
				el.attr({
					"id": conf.treeid,
					"class": conf.treeclass
				});
 
				if( !current ){
					current = root.find("ul");
				}
 
				return self;
			},
 
			getTreeHtml: function(){
				var html = "";
 
				/*
				 * 构建菜单
				 */
				$.each(window.now,function( n,o ){
					html += '<li class="tree-node" id="tree_resource_'+o.id+'"><a id="tree_resource_'+o.id+'_a"><span id="tree_resource_'+o.id+'_span">'+o.name+'</span></a><ul id="tree_resource_'+o.id+'_ul" style="display: none;"></ul></li>';
				});
				cache = html;
 
				return self;
 
			},
 
			/*
			 * 插入HTML代码
			 */
			innerTree: function(){
				current.html( cache ).show("fast");
 
				return self;
			},
 
			/*
			 * 显示菜单
			 */
			showTree: function(){
				current.show("fast");
 
				return self;
			},
 
			/*
			 * 关闭菜单
			 */
			hideTree: function(){
				current.hide("normal");
 
				return self;
			},
 
			/*
			 * 绑定点击事件
			 */
			bindTreeEvent: function(){
				var treeNodes = current.find("a");
 
				/*
				 * 实现菜单
				 */
				$.each(treeNodes,function(n,i){
					$(i).bind("click",function(){
						var s = $(this),
						type = s.data("menuType")
						current = s.nextAll("ul");
						if( !type ){
							if( type === undefined ){
								// ---模拟
								window.now = json_02;
								// 加入新节点
								counter++;
								self.getTreeHtml().innerTree().bindTreeEvent();
							}else{
								self.showTree();
							}
							s.data("menuType",true);
						}else{
							s.data("menuType",false);
							self.hideTree();
						}
					});
				})
				return self;
			}
		});
 
		return self;
	}
 
	$.fn.jtree = function(conf) { 
 
		var el = this.data("jtree");
		if (el) {
			return el;
		}
 
		conf = $.extend({}, jtree, conf); 
 
		this.each(function() {
			el = new tree($(this), conf);
			el.init().getTreeHtml().innerTree().bindTreeEvent();
			$(this).data("jtree", el);
		});
 
		return conf.api ? el: this; 
 
	};
 
  })(jQuery);

数据

  var json_01 = [{"id":"1","name":"111"},{"id":"2","name":"222"}];
 
  var json_02 = [{"id":"3","name":"aaaa"},{"id":"4","name":"bbb"}];

原文链接(58 views)|暂无评论(赶紧抢沙发)