纯代码编写拖动加载

iscroll 功能强大,也只能在手机下面用。pc只能模仿个差不多的东西。

不过iscroll的东西,只能在单独的页面好用,如果添加太多东西,得到的效果和付出的代价划不来,只能手动编写一个。支持手机pc,因为是纯jq,没有兼容问题

<div class='indexList'>
	<!-- 数据集合 -->
</div>
<!-- 用于放置底部,当滚动条超过这个时,触发相关动作,实现拖动加载,手机本身有滚动特效,同样以滚动条滚动做为媒介 -->
<div id="gd_iscroll_bottom"
	style="height: 25px; font-size: 16px; visibility: hidden; overflow: hidden; width: 100%; text-align: center;">
	下拉加载更多</div>

 

	//仿php时间函数
	function time() {
		return Math.floor(new Date().getTime() / 1000);
	}
	//分页的索引页面
	var shop_page_index = 1;
	//滚动的记录时间,用来识别滚动时间,当停止滚动时触发对应函数
	var is_on_scroll_time = 0;
	//加载数据已经结束
	//当数据加载结束,不进行二次加载
	var is_load_end = 0;
	//用于触摸设备,判断是否触摸和离开,离开状态下才进行数据加载
	var is_mobile_touch = false;
	setInterval(function() {
                //时间阀值,当滚动触发时,超过3秒,则表示用户停止滚动,触发对应的加载事件
		if (!is_mobile_touch && is_on_scroll_time
				&& is_on_scroll_time - time() <= 3) {
			console.log('is stop');
			is_on_scroll_time = 0;
			$('#gd_iscroll_bottom').html('加载中...');
			//停止动画链表执行
			$('body').stop(true);
			//调用目标地址加载数据
			$.post('xxxxxx', {
				page : shop_page_index
			}, function(result) {
				var htmlstr = '';
				for (i = 0; i < result.length; i++) {
					model = result[i];
					//拼接数据
					$('.indexList').append('xxx');
				}
				//当返回为空时,不进行数据触发和加载
				if (result.length == 0) {
					$('#gd_iscroll_bottom').html('暂无更多数据...');
					$('body')
							.animate(
									{
										scrollTop : $('#gd_iscroll_bottom')
												.offset().top
												- $(window).height()
									}, 1200);
				} else {
					shop_page_index++;
				}
				//$('.indexList').append($('.indexList').html());
				//$('body').animate({scrollTop:$('#gd_iscroll_bottom').offset().top-$(window).height()}, 1200);
			}, 'json');
		}
	}, 1000);
	$(document)
			.ready(
					function() {
						$(window)
								.scroll(
										function() {
											//滚动条超过底部加载条时,记录
											if ($(window).height()
													+ $(window).scrollTop() >= $(
													'#gd_iscroll_bottom')
													.offset().top
													+ $('#gd_iscroll_bottom')
															.height()) {
												//记录当前滚动时间,用于判断用户是否停止鼠标滚动
												is_on_scroll_time = time();
												console
														.log('gd event on bottom');
												$('body').stop(true);
												//$('body').animate({scrollTop:$('#gd_iscroll_bottom').offset().top-$(window).height()}, 800)
											} else if ($(window).height()
													+ $(window).scrollTop() < $(
													'#gd_iscroll_bottom')
													.offset().top) {
												//当用户滚动到底部,又直接往上拖动时,停止相关触发,否则当上拉时,动画会自动往下拖动
												is_on_scroll_time = 0;
												//停止页面滚动特效
												$('body').stop(true);
											}
										});
					});
	//手机触摸相关触发
	function load() {
		document.addEventListener('touchstart', touch, false);
		document.addEventListener('touchmove', touch, false);
		document.addEventListener('touchend', touch, false);
		function touch(event) {
			var event = event || window.event;
			switch (event.type) {
			case "touchstart"://用户触摸中
				is_mobile_touch = true;
				break;
			case "touchend":
				//用户释放
				is_mobile_touch = false;
				break;
			case "touchmove":
				//event.preventDefault();
				break;
			}

		}
	}
	try {
		window.addEventListener('load', load, false);
	} catch (e) {
		//不是手机
	}

 

重写WeixinApi.js 兼容原代码

官方文档

http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

为了兼容原来的代码,重写WeixinApi的js,只处理分享的部分….

/**
 * ! 微信内置浏览器的Javascript API,功能包括:
 * 
 * 1、分享到微信朋友圈 2、分享给微信好友 3、分享到腾讯微博 4、隐藏/显示右上角的菜单入口 5、隐藏/显示底部浏览器工具栏 6、获取当前的网络状态
 * 7、调起微信客户端的图片播放组件 8、关闭公众平台Web页面
 * 
 * @author zhaoxianlie(http://www.baidufe.com)
 * 
 * @author caihaibin 1.只重写分享部分,兼容原代码
 */
var WeixinApi = (function() {

	"use strict";
	/**
	 * 分享到微信朋友圈
	 * 
	 * @param {Object}
	 *            data 待分享的信息
	 * @p-config {String} appId 公众平台的appId(服务号可用)
	 * @p-config {String} imageUrl 图片地址
	 * @p-config {String} link 链接地址
	 * @p-config {String} desc 描述
	 * @p-config {String} title 分享的标题
	 * 
	 * @param {Object}
	 *            callbacks 相关回调方法
	 * @p-config {Boolean} async ready方法是否需要异步执行,默认false
	 * @p-config {Function} ready(argv) 就绪状态
	 * @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空
	 * @p-config {Function} cancel(res) 取消
	 * @p-config {Function} fail(res) 失败
	 * @p-config {Function} confirm(res) 成功
	 * @p-config {Function} all(res) 无论成功失败都会执行的回调
	 */
	function weixinShareTimeline(data, callbacks) {
		callbacks = callbacks || {};
		var theData = data;
		wx.onMenuShareTimeline({
			title : theData.title,
			desc : theData.desc,
			link : theData.link,
			imgUrl : theData.imgUrl,
			trigger : function(res) {
				callbacks.ready && callbacks.ready(res);
			},
			success : function(res) {
				callbacks.confirm && callbacks.confirm(res);
			},
			cancel : function(res) {
				callbacks.cancel && callbacks.cancel(res);
			},
			fail : function(res) {
				callbacks.fail && callbacks.fail(res);
			}
		});
	}

	/**
	 * 发送给微信上的好友
	 * 
	 * @param {Object}
	 *            data 待分享的信息
	 * @p-config {String} appId 公众平台的appId(服务号可用)
	 * @p-config {String} imageUrl 图片地址
	 * @p-config {String} link 链接地址
	 * @p-config {String} desc 描述
	 * @p-config {String} title 分享的标题
	 * 
	 * @param {Object}
	 *            callbacks 相关回调方法
	 * @p-config {Boolean} async ready方法是否需要异步执行,默认false
	 * @p-config {Function} ready(argv) 就绪状态
	 * @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空
	 * @p-config {Function} cancel(res) 取消
	 * @p-config {Function} fail(res) 失败
	 * @p-config {Function} confirm(res) 成功
	 * @p-config {Function} all(res) 无论成功失败都会执行的回调
	 */
	function weixinSendAppMessage(data, callbacks) {
		callbacks = callbacks || {};
		var theData = data;
		wx.onMenuShareAppMessage({
			title : theData.title,
			desc : theData.desc,
			link : theData.link,
			imgUrl : theData.imgUrl,
			trigger : function(res) {
				callbacks.ready && callbacks.ready(res);
			},
			success : function(res) {
				callbacks.confirm && callbacks.confirm(res);
			},
			cancel : function(res) {
				callbacks.cancel && callbacks.cancel(res);
			},
			fail : function(res) {
				callbacks.fail && callbacks.fail(res);
			}
		});
	}

	/**
	 * 分享到腾讯微博
	 * 
	 * @param {Object}
	 *            data 待分享的信息
	 * @p-config {String} imageUrl 图片地址
	 * @p-config {String} link 链接地址
	 * @p-config {String} desc 描述
	 * @p-config {String} title 分享的标题
	 * 
	 * @param {Object}
	 *            callbacks 相关回调方法
	 * @p-config {Boolean} async ready方法是否需要异步执行,默认false
	 * @p-config {Function} ready(argv) 就绪状态
	 * @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空
	 * @p-config {Function} cancel(res) 取消
	 * @p-config {Function} fail(res) 失败
	 * @p-config {Function} confirm(res) 成功
	 * @p-config {Function} all(res) 无论成功失败都会执行的回调
	 */
	function weixinShareWeibo(data, callbacks) {
		callbacks = callbacks || {};
		var theData = data;
		wx.onMenuShareWeibo({
			title : theData.title,
			desc : theData.desc,
			link : theData.link,
			imgUrl : theData.imgUrl,
			trigger : function(res) {
				callbacks.ready && callbacks.ready(res);
			},
			success : function(res) {
				callbacks.confirm && callbacks.confirm(res);
			},
			cancel : function(res) {
				callbacks.cancel && callbacks.cancel(res);
			},
			fail : function(res) {
				callbacks.fail && callbacks.fail(res);
			}
		});
	}

	/**
	 * 分享到腾讯微博
	 * 
	 * @param {Object}
	 *            data 待分享的信息
	 * @p-config {String} imageUrl 图片地址
	 * @p-config {String} link 链接地址
	 * @p-config {String} desc 描述
	 * @p-config {String} title 分享的标题
	 * 
	 * @param {Object}
	 *            callbacks 相关回调方法
	 * @p-config {Boolean} async ready方法是否需要异步执行,默认false
	 * @p-config {Function} ready(argv) 就绪状态
	 * @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空
	 * @p-config {Function} cancel(res) 取消
	 * @p-config {Function} fail(res) 失败
	 * @p-config {Function} confirm(res) 成功
	 * @p-config {Function} all(res) 无论成功失败都会执行的回调
	 */
	function onMenuShareQQ(data, callbacks) {
		callbacks = callbacks || {};
		var theData = data;
		wx.onMenuShareQQ({
			title : theData.title,
			desc : theData.desc,
			link : theData.link,
			imgUrl : theData.imgUrl,
			trigger : function(res) {
				callbacks.ready && callbacks.ready(res);
			},
			success : function(res) {
				callbacks.confirm && callbacks.confirm(res);
			},
			cancel : function(res) {
				callbacks.cancel && callbacks.cancel(res);
			},
			fail : function(res) {
				callbacks.fail && callbacks.fail(res);
			}
		});
	}

	/**
	 * 调起微信Native的图片播放组件。 这里必须对参数进行强检测,如果参数不合法,直接会导致微信客户端crash
	 * 
	 * @param {String}
	 *            curSrc 当前播放的图片地址
	 * @param {Array}
	 *            srcList 图片地址列表
	 */
	function imagePreview(curSrc, srcList) {
		if (!curSrc || !srcList || srcList.length == 0) {
			return;
		}
		WeixinJSBridge.invoke('imagePreview', {
			'current' : curSrc,
			'urls' : srcList
		});
	}

	/**
	 * 显示网页右上角的按钮
	 */
	function showOptionMenu() {
		WeixinJSBridge.call('showOptionMenu');
	}

	/**
	 * 隐藏网页右上角的按钮
	 */
	function hideOptionMenu() {
		WeixinJSBridge.call('hideOptionMenu');
	}

	/**
	 * 显示底部工具栏
	 */
	function showToolbar() {
		WeixinJSBridge.call('showToolbar');
	}

	/**
	 * 隐藏底部工具栏
	 */
	function hideToolbar() {
		WeixinJSBridge.call('hideToolbar');
	}

	/**
	 * 返回如下几种类型:
	 * 
	 * network_type:wifi wifi网络 network_type:edge 非wifi,包含3G/2G
	 * network_type:fail 网络断开连接 network_type:wwan 2g或者3g
	 * 
	 * 使用方法: WeixinApi.getNetworkType(function(networkType){
	 * 
	 * });
	 * 
	 * @param callback
	 */
	function getNetworkType(callback) {
		if (callback && typeof callback == 'function') {
			WeixinJSBridge.invoke('getNetworkType', {}, function(e) {
				// 在这里拿到e.err_msg,这里面就包含了所有的网络类型
				callback(e.err_msg);
			});
		}
	}

	/**
	 * 关闭当前微信公众平台页面
	 */
	function closeWindow() {
		WeixinJSBridge.call("closeWindow");
	}

	/**
	 * 当页面加载完毕后执行,使用方法: WeixinApi.ready(function(Api){ // 从这里只用Api即是WeixinApi
	 * });
	 * 
	 * @param readyCallback
	 */
	function wxJsBridgeReady(readyCallback) {
		if (readyCallback && typeof readyCallback == 'function') {
			var Api = this;
			// 当在微信中时,才进行签名处理.
			if (Api.inWeixin) {
				/**
				 * 需要引用jquery weixinjs_url 获取当前url的签名参数
				 */
				$.post('http://xxxxxxxx/weixinjs/index', {
					weixinjs_url : location.href
				}, function(result) {
					wx.config(result.obj);
				}, 'json');
			}
			var wxReadyFunc = function() {
				readyCallback(Api);
			};
			wx.ready(wxReadyFunc);
			return;
		}
	}
	return {
		version : "1.6",
		ready : wxJsBridgeReady,
		shareToTimeline : weixinShareTimeline,
		shareToWeibo : weixinShareWeibo,
		shareToFriend : weixinSendAppMessage,
		shareToQq : onMenuShareQQ,
		showOptionMenu : showOptionMenu,
		hideOptionMenu : hideOptionMenu,
		showToolbar : showToolbar,
		hideToolbar : hideToolbar,
		getNetworkType : getNetworkType,
		imagePreview : imagePreview,
		closeWindow : closeWindow,
		// 在微信内才进行签名判断.
		inWeixin : navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == "micromessenger"
	};
})();

 

jssdk.php

替换

JSSDK::getSignPackage()
	public function getSignPackage() {
		$jsapiTicket = $this->getJsApiTicket ();
		$url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
		// 通过外部参数进行目标的url的签名
		if ($_REQUEST ['weixinjs_url']) {
			$url = $_REQUEST ['weixinjs_url'];
		}
		$timestamp = time ();
		$nonceStr = $this->createNonceStr ();

		// 这里参数的顺序要按照 key 值 ASCII 码升序排序
		$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";

		$signature = sha1 ( $string );

		$signPackage = array (
				"appId" => $this->appId,
				"nonceStr" => $nonceStr,
				"timestamp" => $timestamp,
				"url" => $url,
				"signature" => $signature,
				"rawString" => $string 
		);
		return $signPackage;
	}

服务器端签名

	public function actionIndex() {
		if ($_SERVER ['HTTP_ORIGIN'])
			header ( "Access-Control-Allow-Origin: " . $_SERVER ['HTTP_ORIGIN'] );
		header ( "Access-Control-Allow-Credentials: true" );
		$title = '微信签名相关';
		lib ( "weixin/js/jssdk.php" );
		$jssdk = new JSSDK ( "xxxxxxxx", "xxxxxxx" );
		$signPackage = $jssdk->GetSignPackage ();
		$result = array (
				'appId' => $signPackage ["appId"],
				'timestamp' => $signPackage ["timestamp"],
				'nonceStr' => $signPackage ["nonceStr"],
				'signature' => $signPackage ["signature"],
				'jsApiList' => array (
						'onMenuShareAppMessage',
						'onMenuShareTimeline',
						'onMenuShareQQ',
						'onMenuShareWeibo' 
				) 
		);
		sjson ( true, $title, '', $result );
	}

调用方式

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<!-- 重写后的 js-->
<script src="http://xxxxxx/js/WeixinApi.js"></script>
<!-- 
原来代码不用进行调整,方便修复.如果代码有问题,也可以对WeixinApi.js进行统一修改
 -->

 

【转】谢孟媛教英语

http://i.youku.com/u/UNTg0ODUxMzk2?from=113-2-1-2

对于完全零基础的人,强烈建议从这些学起,体系不全很多时候摸不到头脑,很打击信心。

补充下有一定基础后,学习的方式

http://www.cnblogs.com/jesse2013/p/how-to-learn-english.html

看完发音篇,对发音才有一定的认识,不过这老师特别厉害。赚到了哈哈。

【转】英语语法大全:名词性从句知识点总结

http://www.yingyu.com/e/20140708/53bbb752ecd09.shtml

快半年了。。前阵子终于搞完了,拖到今天才来记录。

学到很多,更多的是了解的自己的缺点。

跳了那么多年,工作后才来认真开始学,知识体系是个硬伤。

不过做选择一直对6成也挺可以了。。。。

继续继续

cas 登录各种虐

原理:

http://steven-wiki.readthedocs.org/en/latest/security/sso/

麻烦一:

出现一个比较奇葩的逻辑。是有一套系统已经成形了。cas 登录是后补充的.

需要由原页面登录页面进行提交。

麻烦二:

cas是其它合作公司处理,竞争公司,你懂的。。

 

解决方式:

1.直接post 提交

1.1 各种逻辑处理问题相对麻烦,特别是对于已经成形的

1.2页面各种跳转不好看

2.ajax 进行提交(前提目标公司要合作。。。。要合作。。。)

2.1目标服务器需要有权限,设置头

参考:http://haibin.info/?p=532

2.2需要考虑兼容问题(ie8+,chrome 这些ok,ie7以下的请无视看3)

参考:http://haibin.info/?p=973

2.3页面不用跳转,可在原逻辑的支持下实现,修改少。

3.隐藏post 表单 js 提交到 隐藏的iframe (通过target 指定对应的提交地址)

3.1 修改相对较少,没有兼容性问题。因为post提交,只要是浏览器都支持.

3.2不过本身就是通过跳来跳去实现的,只是包装到iframe中,再通过外部函数调用。如果原页面逻辑复杂,推荐这种处理方式

4.jsonp登录,类似ajax(前提目标公司要合作。。。。要合作。。。)

4.1参考http://www.cnblogs.com/jifeng/p/3511219.html(页面图大。。。谨慎 ~.~ )

http://www.cnblogs.com/jifeng/p/3511219.html

5. cas/service 手动写入cookie.(需要有服务器的操作权限或配置)

5.1 最简单的实现方式,影响最小,通过模拟登录获取最终CASTCG ,通过客户端GET 直接设置到cookie

6. 模拟登录,登录成功之后 iframe 进行隐藏post提交,即是登录两次。相对修改较少

7.这边的最终解决方案,搞一个同域名下的服务器.让目标公司配合cookie 设置成顶级域名下

setcookie ( 'name', 'value' ,null,'/','.xxxxxx.com');

 

注意事项:

登录检查

1.http://casservice/cas/login?servce=跳转的目标地址

1.1访问以上地址,会返回对应的ticket ,ticket 只能抓取一次数据

1.2 这种跳转是直接控制top.location ,无法进行iframe 检查

2.http://casservice/cas/remoteLogin?service=跳转的目标地址&loginUrl=跳转的目标地址

2.1登录地址也可以用来进行登录检查判断

2.2只跳转当前location ,可以当前iframe进行跳转

ticket获取用户信息

1 ticket 只能抓取一次数据

2 http://caservice/cas/serviceValidate?service=获取ticket的地址&ticket=返回的ticket

3.补充xml转array代码

		// 过滤标签头
		$result = preg_replace ( '/<cas:/i', '<', $xml );
		// 过滤结束标签头
		$result = preg_replace ( '/</cas:/i', '</', $result );
		$res = @simplexml_load_string ( $result, NULL, LIBXML_NOCDATA );
		if (! $res) {
			return false;
		}
		$res = json_decode ( json_encode ( $res ), true );
		if (isset ( $res ['authenticationSuccess'] )) {
			/**
			 * Array
			 * (
			 * _[authenticationSuccess] => Array
			 * _(
			 * __[user] => xxxxx
			 * __[attributes] => Array
			 * __(
			 * ____[login_flag] => xxx
			 * ____[employeeId] => xxx
			 * ____[asHelp] => xxxx
			 * __)
			 * _)
			 * )
			 */
			//$res ['authenticationSuccess'];
			return true;
		}

 

ajax 跨域cookie问题 (CORS support in a browser)

介绍

http://software.dzhuvinov.com/cors-filter-tips.html

封装好的js

https://github.com/dkastner/jquery.iecors

请求头部分的设置参考

HTML5 跨域提交和上传实现 及 nginx $_SERVER[‘HTTP_X_FILENAME’]解决

请求头时不可以直接设置:

Access-Control-Allow-Headers: *

不然会冲突下面配置

$.ajax({
	url : 'http://xxxxxx',
	xhrFields : {
		withCredentials : true
	},
	crossDomain : true,
	success : function(result) {
		alert('ajax调用成功' + result)
	}
});

withCredentials 开启时,跨与登录的cookie才会记录到域名中.

如a 域名调用 b域名。b域名中才会记录对应的cookie,否则即使在chrome中看到成功返回cookie,直接访问b时,会不存在。

且withCredentials 只支持html5特性的浏览器 ie8需要参考上面的处理

 

 

 

修复Yii ar 在win环境下 oci_pconnect 访问慢问题

同样的代码,在linux 环境下的 apache访问速度就正常,一样是链接外部数据库。

在开发环境中win(php5.2)链接测试机linux数据库访问里,速度会慢。还是用oci_pconnect的情况下.

折腾过php的不同版本 5.4 ts nts 这些版本。速度依旧烂。

测试机内部apache访问时,速度不慢。觉得是出在win上。

这块无解。尝试分析各sql访问上的速度问题.

log 补充 trace 打印出sql访问日志,单条进行数据分析

				'log' => array (
						'class' => 'CLogRouter',
						'routes' => array (
								array (
										'class' => 'CFileLogRoute',
										'levels' => 'trace, error, warning'
								)
						) 
				),

 

发现ar 在获取结构时,一次要花费约1s左右。

其它访问速度正常。

ar开启缓存。第一次访问时较慢,后续访问均明显变快,和原来mysql环境下差不多。

'db' => array (
              'class'=>'ext.oci8Pdo.OciDbConnection',
				'connectionString' => 'oci:dbname=//xxx/xx;charset=UTF8;',
				// 开启表结构缓存(schema caching)提高性能
				'schemaCachingDuration'=>3600,
		),