开放的编程资料库

当前位置:我爱分享网 > PHP教程 > 正文

使用 MooTools ScrollSpy 通过 JSON/AJAX 加载更多项目

去年七月我写了一个史诗 支配 unbelievable fantastic outstanding awesome NetTuts名为使用 CSS、HTML、JSON 和 jQuery 或 MooTools 创建类似 Twitter 的“加载更多”小部件的帖子,其中我使用 MooTools/AJAX/JSON 系统在用户单击“加载更多”链接时加载其他项目。功能很不错,但我认为还有改进的余地。如果用户向下滚动到容器的末尾,为什么不自动为他们加载更多项目?配备一流的 MooTools 滚动插件 ScrollSpy,我们可以做到这一点。

HTML




如您所见,该页面以非常少的 HTML 开头。显然,这不是在没有启用 JavaScript 的情况下也能工作的解决方案。让这个系统在没有 JavaScript 的情况下工作不会太困难……但我们将在本教程中跳过它。

CSS

#posts	{ height:300px; overflow:scroll; }

我原来的 NetTuts 中的 CSS 保持不变——我们只是添加了#posts 选择器属性。

MooTools JavaScript

原始教程中添加了相当多的内容,因此我将分别指出每个更改:

/* via @appden, Scott Kyle, http://appden.com/javascript/fun-with-custom-events-on-elements-in-mootools/ */
Native.implement([Element, Window, Document, Events], {
	oneEvent: function(type, fn) {
		return this.addEvent(type, function() {
			this.removeEvent(type, arguments.callee);
			return fn.apply(this, arguments);
		});
	}
});

上面的代码表示一个函数,每个元素只运行一次。我们稍后会用到它。

//NEW!
var spy;
var spyContainer = $('posts');
var spyAct = function() {
	var min = spyContainer.getScrollSize().y - spyContainer.getSize().y - 150 /* tolerance */;
	spy = new ScrollSpy({
		container: spyContainer,
		min: min,
		onEnter: function() {
			loadMore.fireEvent('click');
		}
	});
};
//wait for first load...
window.oneEvent('load',function() {
	spyAct();
});

我们创建 ScrollSpy 侦听器来跟踪滚动。如果用户在距离底部 150 像素的范围内滚动,我们会触发对“加载更多”链接的虚拟点击。

//Request.JSON above....
onSuccess: function(responseJSON) {
	//reset the message
	loadMore.set('text','Load More');
	//increment the current status
	start += desiredPosts;
	//add in the new posts
	postHandler(responseJSON);
	//spy calc!
	spyAct();
},
//more below....

最后,我们在 JSON 请求的成功事件上调用辅助函数。这是完整的 MooTools JavaScript 片段:

/* via @appden, Scott Kyle, http://appden.com/javascript/fun-with-custom-events-on-elements-in-mootools/ */
Native.implement([Element, Window, Document, Events], {
	oneEvent: function(type, fn) {
		return this.addEvent(type, function() {
			this.removeEvent(type, arguments.callee);
			return fn.apply(this, arguments);
		});
	}
});


//safety closure
(function($) {
	//domready event
	window.addEvent('domready',function() {
		//settings on top
		var domain = 'https://davidwalsh.name/';
		var initialPosts = ;
		var start = ;
		var desiredPosts = ;
		var loadMore = $('load-more');
		//NEW!
		var spy;
		var spyContainer = $('posts');
		var spyAct = function() {
			var min = spyContainer.getScrollSize().y - spyContainer.getSize().y - 150 /* tolerance */;
			spy = new ScrollSpy({
				container: spyContainer,
				min: min,
				onEnter: function() {
					loadMore.fireEvent('click');
				}
			});
		};
		//wait for first load...
		window.oneEvent('load',function() {
			spyAct();
		});
		//function that creates the posts
		var postHandler = function(postsJSON) {
			postsJSON.each(function(post,i) {
				//post url
				var postURL = '' + domain + post.post_name;
				//create the HTML
				var postDiv = new Element('div',{
					'class': 'post',
					events: {
						click: function() {
							window.location = postURL;
						}
					},
					id: 'post-' + post.ID,
					html: '' + post.post_title + '

' + post.post_content + '
Read more...

' }); //inject into the container postDiv.inject($('posts')); }); }; //place the initial posts in the page postHandler(initialPosts); //ajax! var request = new Request.JSON({ url: 'load-more.php', //ajax script -- same page method: 'get', link: 'cancel', noCache: true, onRequest: function() { //add the activate class and change the message loadMore.addClass('activate').set('text','Loading...'); }, onSuccess: function(responseJSON) { //reset the message loadMore.set('text','Load More'); //increment the current status start += desiredPosts; //add in the new posts postHandler(responseJSON); //spy calc! spyAct(); }, onFailure: function() { //reset the message loadMore.set('text','Oops! Try Again.'); }, onComplete: function() { //remove the spinner loadMore.removeClass('activate'); } }); //add the "Load More" click event loadMore.addEvent('click',function(){ //begin the ajax attempt request.send({ data: { 'start': start, 'desiredPosts': desiredPosts } }); }); }); })(document.id);

PHP

以下 PHP 加载更多项目。我的示例使用 WordPress 帖子:

/* settings */
session_start();
$number_of_posts = 5; //5 at a time
$_SESSION['posts_start'] = $_SESSION['posts_start'] ? $_SESSION['posts_start'] : $number_of_posts;

/* loading of stuff */
if(isset($_GET['start'])) {
	/* spit out the posts within the desired range */
	echo get_posts($_GET['start'],$_GET['desiredPosts']);
	/* save the user's "spot", so to speak */
	//$_SESSION['posts_start']+= $_GET['desiredPosts'];
	/* kill the page */
	die();
}

/* grab stuff */
function get_posts($start = 0, $number_of_posts = 5) {
	/* connect to the db */
	$connection = mysql_connect('localhost','username','password');
	mysql_select_db('blogname',$connection);
	$posts = array();
	/* get the posts */
	$query = "SELECT post_title, post_content, post_name, ID FROM wp_posts WHERE post_status = 'publish' ORDER BY post_date DESC LIMIT $start,$number_of_posts";
	$result = mysql_query($query);
	while($row = mysql_fetch_assoc($result)) {
		preg_match("/

(.*)<\/p>/",$row['post_content'],$matches); $row['post_content'] = strip_tags($matches[1]); $posts[] = $row; } /* return the posts in the JSON format */ return json_encode($posts); }

几点思考

  • 这种类型的系统只有在您记得上次加载了多少项目时才能正常工作。让用户从默认号码开始是非常烦人的。
  • 我发现浏览器监听滚动是很糟糕的——有时浏览器根本没有正确触发滚动事件,这使得“加载更多”链接显得尤为重要。

如果您想深入了解该系统,请阅读 NetTuts 上的原始帖子。

虽然功能很酷,是吧?

未经允许不得转载:我爱分享网 » 使用 MooTools ScrollSpy 通过 JSON/AJAX 加载更多项目

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏