xhEditor上传文件功能

xhEditor是一款不错的js超文本编辑器,感觉还是不错的,默认是不提供文件上传功能的,需要设定参数,才会开启。

默认初始化:$(‘#content’).xheditor();

如果想开启图片上传,那么要这样:

$(‘#content’).xheditor({upImgUrl:”upload.php?immediate=1″,upImgExt:”jpg,jpeg,gif,png”});

上传url地址里的immediate参数是给xhEditor的,表示立即上传,php端可直接忽略。

图片处理upload.php接收图片文件数据要注意了,默认是html5上传,不是普通的表单上传,所以是没有_FILES数组的,要通过file_get_contents(‘php://input’)获取文件内容。

最后要注意的是返回的数据,采用json格式,具体格式如下:

$arr = array("err" => "","msg" => "http://pic.jpg");
echo json_encode($arr);

 

jsonp和应用实例-2000万开房查询接口

jsonp,我个人的理解就是一个可以跨域的js接口,这个接口直接返回一个本地的function调用,其参数一般是json格式,数据来源于接口。好像比较费解。实例说明:

前段时间爆出2000万开房数据的漏洞,这里就是一个获取数据的jsonp接口:http://www.2dianying.net/kaifang.php?fun=callback&id=310104198405232812

提供了两个参数fun和id,其中id是身份证号码,接口会按照指定id返回json格式的开房数据,fun参数是关键,可以看到这个url直接返回的是一个js函数调用,而这个函数名又是调用方指定的,当然也需要在调用方的页面上实现具体的功能。

下面是一个简单的调用方接口实现代码:

function callback(json){
		for(var i=0; i < json.length; i++){
			document.write(json[i]["name"]+json[i]["address"]+json[i]["phone"]+json[i]["time"]);
		}
	}

看起来好像很简单啊,问题是怎样查询不同的id,并且实时返回数据呢?如果只是用script标签用src指定一个固定的接口地址,那只能获取一个固定的id的开房情况。

这个时候就要用到动态生成script标签的功能了,主流浏览器都支持的:

var otherid = "xxxxx";
var script = document.body.appendChild(document.createElement("script"));
script.src = "http://www.2dianying.net/kaifang.php?fun=callback&id="+otherid;

至此一个完整的jsonp应用实例就完成了。

基于jquery的无刷新多文件上传

有几个关键点:

1、无刷新

2、多文件上传

无刷新,就是不显示提交表单,file控件有改变就触发文件上传,且页面不刷新,很高级的感觉。

多文件上传,点击file控件,弹出的选择文件系统对话框,可以选择多个文件并上传。

这些都基于jquery,这是好东西,这个上传的js如下:

(function($) {
	var context = new Array();
	var gUploadId = 0;
	var settings = null;
	var index = 0;

	var onProgress = function(ev) {
		console.debug("progress");
		if (ev.lengthComputable) {
			var id = ev.target.upfile_id;
			var uploadId = ev.target.upload_id;
			settings = context[uploadId]['settings'];			
			var percent = Math.round(ev.loaded * 100 / ev.total);
			console.debug("percent=" + percent);
			console.debug("progress");
			if (settings.progress != null)
				settings.progress(id, percent);
		}
	}

	var onLoad = function(ev) {
		var id = ev.target.upload.upfile_id;
		var uploadId = ev.target.upload.upload_id;
		settings = context[uploadId]['settings'];
		console.debug(ev.target.responseText);
		json = eval("(" + ev.target.responseText + ")");
		console.debug("success");
		if (settings.success != null)
			settings.success(id, json);
	}

	var fetch = function(uploadId, upfile) {
		settings = context[uploadId]['settings'];
		console.debug("fetch.settings=" + settings.url);
		console.debug("fetch");
		console.debug("add(" + index + ")");
		if (settings.add != null)
			settings.add(index);
		var fd = new FormData();
		fd.append(settings.fieldName, upfile);
		var xhr = new XMLHttpRequest();
		xhr.addEventListener("load", onLoad, false);
		xhr.upload.addEventListener("progress", onProgress, false);
		xhr.upload.upfile_id = index;
		xhr.upload.upload_id = uploadId;
		xhr.open("POST", settings.url, true);
		xhr.send(fd);
		index++;
	}

	$.fn.upload = function(options) {

		settings = jQuery.extend({
			url: null,
			add: null,
			success: null,
			fieldName: 'upload_file',
			progress: null,
		}, options);
		context[gUploadId] = new Array();
		context[gUploadId]['settings'] = settings;
		$(this).attr('g-upload-id', gUploadId);
		gUploadId++;
		this.each(function() {
			var $el = $(this);
			$(this).bind('change', function() {
				var fileList = $el.get(0).files;
				for (var i = 0; i < fileList.length; i++) {
					var uploadId = $(this).attr('g-upload-id');
					fetch(uploadId, fileList[i]);
				}
			});

		});

		return this;
	}

})(jQuery);

用法:

$('input[type=file]').upload({
	url: 'http://upload.chengxufan.com/upload',
	add: function(id) {
		$('#box').append('<li id="'+id+'"><img src="/default.png" /></li>')
	},
	success: function(id, json) {
		$('#box').find("li[id='+id+']").html('<img src="'+json.data+'" />');
	},
	progress: function(id, percent) {
		$('#box').find("li[id='+id+']").html('progress is %' + percent);
	}
 });

如果有多个file控件,那么就要定义多个upload绑定

verlet一个基于html5的js物理引擎

标题好像很拗口,就是在canvas上做符合物理规律的动画,重力、弹性、碰撞等等。

git clone https://github.com/subprotocol/verlet-js.git

里面有4个examples。

那个蜘蛛是非常牛B的,看了js源码,困啊,没想到html5+js能做出如此牛B的效果。

没有git,也可以下载zip包:https://github.com/subprotocol/verlet-js/archive/master.zip

效果是牛,只不过js也不好写啊,门槛还是有的。

IOS之WebViewJavascriptBridge补充

上篇讲到ios中页面使用WebViewJavascriptBridge交互数据,只提供一个页面上一个按钮,如果是个列表页有多个按钮都要交互数据呢?写法要改一下:

首先要初始化

var bridge;
document.addEventListener(‘WebViewJavascriptBridgeReady’, onBridgeReady, false)
function onBridgeReady(event) {
bridge = event.bridge

bridge.init(function(message, responseCallback) {
var data = { ‘Javascript Responds’:’Wee!’ }
responseCallback(data)
})

bridge.registerHandler(‘testJavascriptHandler’, function(data, responseCallback) {
var responseData = { ‘Javascript Says’:’Right back atcha!’ }
responseCallback(responseData)
})

}

然后在每个按钮后绑定事件

<a id=”a_1″>touch1</a>
var obj = document.getElementById(‘a_1’);
obj.ontouchstart = function(e) {
e.preventDefault()
bridge.send(‘data’, function(responseData) {

})
}
<a id=”a_2″>touch2</a>
var obj = document.getElementById(‘a_2’);
obj.ontouchstart = function(e) {
e.preventDefault()
bridge.send(‘data’, function(responseData) {

})
}

多文件上传方案

多文件上传,最简单的方案当然是一个表单里放多个file控件,这种方案最大的缺点,你我都知道,就是文件都很大,一次提交多个很大的文件,后果大家都知道,所以就有各种将多个文件上传拆分为单个文件上传的方案。

1、file上使用onchange事件提交,一旦选择了文件就触发表单提交,一般是提交到一个隐藏的iframe里,这样又做到了单个上传,又做到了无刷新提交,缺点是如果用户选错文件,改都来不及。

2、一个表单一个file,通过一个提交按钮,遍历表单,逐个提交,第一种方案的缺点当然是解决了,不过还是有问题,如果提交按钮连续提交的话,服务器端压力还是不小的。改进方案是先提交一个,等待iframe返回结果,再触发下一个表单提交,顺序提交。

范例代码 继续阅读“多文件上传方案”