`
java_lyvee
  • 浏览: 89674 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

仿QQ空间无限下拉翻页——自定义+时间轴翻页

    博客分类:
  • J2EE
阅读更多

    项目里面要实现这么一个效果,类似腾讯QQ空间那种利用滚动条来翻页,但是还要有数字分页再带一个类似时间轴的东西显示在右边。于是 Google it!网上有很多代码,但我发觉没一个可以用,包括JQUERY官方提供的的插件都那么不尽人意,于是自己动手写一个。

 

    1、首先要实现的第一个效果就是滚动翻页,和数字翻页如图(数据都是通过ajax往后台请求)

   

    

 

 

2、实现一个时间轴,主要为了良好的用户体验(其实用处不大,主要在时间轴上加上锚点),如图

       

   

 

 

 

3、数字分页和滚动翻页的结合:比如用户一进到页面,没有滚动那么自然只有第一页(1-10条记录)的数据。每次将滚动条、滚动到下面的时候就去后台请求下一页的数据,这个JS操作网上一大把,但是都不行。原因是发多次请求,加载出来重复的数据。这个问题解决方法就是每次需要往后台加载数据的时候先window的scroll的监听事件取消,然后执行ajax请求,执行完ajax后根据返回出来的信息判断时候还需要添加window的scroll监听事件,比如当数据已经全部加载完了则不需要为window再次添加scroll,否则再一次为window添加scroll。代码如下:

 

     

    根据ajax返回来的信息判断是否要为window再次加上scroll的监听事件

 

 

     

 

     至此滚动翻页的功能就完成了,基本和腾讯QQ空间的那个无线下拉翻页没什么区别。但是我们项目里面还要加上一个数字分页,这个功能本身没什么难点,难的是要和滚动翻页结合,比方用户首先进来不滚动翻页,直接点击一个数字翻页假设他点击的是3,那么我首先得判断第三页(20-30条记录)的数据是否被加载出来了,是否显示在页面上了,如果已经加载出来显示在页面上了那么就利用HTML的锚点跳转功能,使浏览器定位到第(20条记录),如果没有加载出来,在发送ajax请求往后台请求数据加载并显示。

 

 

 用户第一次进到页面:

        

 

 

 

 

当用户直接点击数字翻页钟的3

 

     

 

 

 

 

 

 

 

如果这个时候用户在此点击数字翻页钟的2的时候数据情况:

 

 

 

 

数据展示:

 

 

 

     如果用户这个时候又去滚动 滚动条,那么就会往后台请求数据(由于第三页和第2页的数据已经被加载请出来了),所以直接往后台加载第4页的数据————这个功能也是最难实现的,也是最能体现用户体验的地方

    直接上图: 使用滚动条滚动的时候

   

 

     

 

  

 

 

 

 

 

 服务器端的java代码:

@Override
	@RequestMapping(value="designer.xhtml")
	 /*
	  * <p>Title: forward</p>
	  * <p>Description:查询设计师 </p>
	  * @param model
	  * @param request
	  * @param response
	  * @return
	  * @see com.kecg.web.base.BaseController#forward(org.springframework.ui.ModelMap, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	  */
	public String forward(ModelMap model, HttpServletRequest request, HttpServletResponse response) {
		try {
			MemberEntity mentity = (MemberEntity) this.conditionParam(request, null, MemberEntity.class);
			mentity.setRecommendFlag(1);
			PageResult pr = memberService.query4List(request, mentity, 1);
			request.setAttribute("list",pr.getList());
			request.setAttribute("page",pr.getPageUtil());
			request.setAttribute("total",pr.getTotal());
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return "model/modelDesigner";
	}
	@RequestMapping(value="ajaxLoadDesigner.xhtml")
	public @ResponseBody Map<String,Object> ajaxLoadDesigner(HttpServletRequest request, HttpServletResponse response){
		Map<String,Object> map = new HashMap<String,Object>();
		try {
			MemberEntity mentity = (MemberEntity) this.conditionParam(request, null, MemberEntity.class);
			mentity.setRecommendFlag(1);
			PageResult pr = memberService.query4List(request, mentity, 1);
			map.put("list",pr.getList());
			map.put("page",pr.getPageUtil());
			map.put("total",pr.getTotal());
			return map;
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return map;
	}

 

       JS代码:

var currentPage =2;
var tatalPage = "";
var scrollFlag="1";

var hght=0;//初始化滚动条总长
var top=0;//初始化滚动条的当前位置
$(function() {
	/*  点击更多  加载更多 */
	$("#sea_more").click(
		function(){
			var brand = document.getElementById("sea_padding1");
			brand.style.display=="block"?brand.style.display="none":brand.style.display="block";
		});
		$(".addClass").qtip({
		position : {
			my : 'bottom right',
			at : 'top center'
		},
		style : {
			classes : 'ui-tooltip-dark ui-tooltip-shadow ui-tooltip-rounded'
		}
	});
		

//滚动翻页
 $(window).bind("scroll",scrollFun);
 
	var top = $('#timeline').offset().top - parseFloat($('#timeline').css('marginTop').replace(/auto/, 0));
	var topage = $('#designerPage').offset().top - parseFloat($('#designerPage').css('marginTop').replace(/auto/, 0));
	
    var footTop = $('#dis_footer').offset().top - parseFloat($('#dis_footer').css('marginTop').replace(/auto/, 0));

    var maxY = footTop - $('#timeline').outerHeight();
    var maxYP = footTop - $('#designerPage').outerHeight();

    $(window).scroll(function(evt) {
        var y = $(this).scrollTop();
        if (y > top) {
            if (y < maxY) {
                $('#timeline').addClass('fixed').removeAttr('style');
            } else {
                $('#timeline').removeClass('fixed').css({
                    position: 'absolute',
                    top: (maxY - top) + 'px'
                });
            }
        } else {
            $('#timeline').removeClass('fixed');
        }
        
        if(y>topage){
        	if (y < maxYP) {
                $('#designerPage').addClass('fixed').removeAttr('style');
            } else {
                $('#designerPage').removeClass('fixed').css({
                    position: 'absolute',
                    top: (maxYP - top) + 'px'
                });
            }
        }else{
         	$('#designerPage').removeClass('fixed');
        }
    });
 
});

function hrefCurrentPage(obj){
	$('html,body').animate({scrollTop:$('#'+obj).offset().top}, 800);
}

function pageFun(obj,obj1){
	var info = $('#'+obj).attr('class');
	if(info){
		$('html,body').animate({scrollTop:$('#'+obj).offset().top}, 800);
	}else{
		$(window).unbind();
		currentPage = obj1;
		ajaxLoadData()
		setTimeout('hrefCurrentPage(\"'+obj+'\")',1000);
		return;
		
		
	}
}

function scrollFun(){
	 $(window).scrollTop();//这个方法是当前滚动条滚动的距离
        $(window).height();//获取当前窗体的高度
        $(document).height();//获取当前文档的高度
        var bot = 10; //bot是底部距离的高度
        if ((bot + $(window).scrollTop()) >= ($(document).height() - $(window).height())) {
           //当底部基本距离+滚动的高度〉=文档的高度-窗体的高度时;
            //我们需要去异步加载数据,每次执行ajax之前先取消window的scroll事件监听(防止多次请求数据)
            	$(window).unbind();
            	existLoad(currentPage);//判断当前页码的数据是否已经被加载,如果没有则往后台请求加载数据
            	return;
        }
};
function existLoad(obj){
	var clazz = $('#'+obj+'0box').attr('class');
	console.log(clazz);
	if(clazz){//当前这个页码的数据已经存在
		currentPage++;
		existLoad(currentPage);
	}else{
		setTimeout('ajaxLoadData()',1000);
		return;
	}
	return false;
}
function ajaxLoadData(){
		$.ajax({type: 'POST',
			  url: 'ajaxLoadDesigner.xhtml',
			  data: {"currentPage":currentPage},
			  success: function(data){
				  if(currentPage>=data.page.totalPage){//如果当前页大于等于总页则表示数据全部加载完毕
				  		currentPage = data.page.totalPage;
				  		$(window).unbind();//取消window的scroll事件监听(再怎么滚动都不会去后台加载数据了)
				  		$(".desigenerLoadingMore").html("已经全部加载完毕");
				  	}else{//如果数据还没有全部加载完毕,设置当前页为服务器端返回的当前页
				  		currentPage=data.page.currentPage;
				  		//并且再次为window加上scroll的监听事件
				  		//(由于之前在ajax请求之前已经取消了对scroll的监听,故而这里需要手动再一次加上)
				  		$(window).bind("scroll",scrollFun);
				  	}
			  	ajaxLoadDesignerCall(data);
			  },
			  dataType: 'json'
		 });
}

function checkedDesigner(obj){
	var html= '<div class="seleceedLabel"><p class="selectedLeft"></p>'+
		'<p class="selectedText">'+obj+'</p><p class="selectedRight">'+
		'<img onClick="removeChecked($(this));" class="cancelChecked" src="../static/images/cancel.png" /></p></div>';
	var checkedLabelArray = $(".selectedText");
	if(checkedLabelArray<=0){
		$("#allSelected").append(html);
	}else{
		for(var i=0;i<checkedLabelArray.length;i++){//如果已经被选择
			if($(checkedLabelArray[i]).text()==obj){
				return false;
			}
		}
	}
	$("#allSelected").append(html);
}

function removeChecked(obj){
	$(obj).parent().parent().remove();
}

function ajaxLoadDesignerCall(data,obj){
	var list = data.list;
	currentPage++;
	console.log(currentPage);
	var html ="";
	if(list.length>0){
		for(var i=0;i<list.length;i++){
			var gender = "女";
			if(list[i].memberGender==1){
				gender ="男";
			}
			html+='<li class="designer_list_details" id='+(currentPage-1)+''+i+'box>'+
				'<div class="user-info-banner">'+
				'<div class="grid-730 left author-info">'+
				'<div class="author-portrait left">'+
				'<a href="#" title="" class="author-portrait-container">'+
				'<div class="portrait-cover"></div>'+
				'<img src="../static/images/'+list[i].memberPic+'" style="float:left" width="115px" height="115px" alt="" style="border:0px;"> </a> </div></div>'+
				'<div class="designer_list_details_info">'+
				'<p>'+list[i].memberName+'<img title="添加关注" class="addClass" src="../static/images/add.png" /></p>'+
				'<p>'+gender+'</p>'+
				'<p>粉丝/'+list[i].fans+' &nbsp;作品:80</p></div>'+
				'<div class="opus_images_list">'+
				'<a href="javascipt:void(0);">'+
				'<img src="../static/attachment/1.jpg" width="100" height="75"/></a>'+
				'<a href="javascipt:void(0);">'+
				'<img src="../static/attachment/1.jpg" width="100" height="75"/></a>'+
				'<a href="javascipt:void(0);">'+
				'<img src="../static/attachment/1.jpg" width="100" height="75"/></a>'+
				'<a href="javascipt:void(0);">'+
				'<img src="../static/attachment/1.jpg" width="100" height="75"/></a></div></div></li>';
		}
		$("#layout_designer_list").append(html);
		var timeHtml  = '<li><div class="time">'+Number(((currentPage-2)*10)+1)+'-'+Number(((currentPage-1)*10)+1)+'</div><div class="version">第'+(currentPage-1)+'页</div><div class="number" onclick="hrefCurrentPage(\''+currentPage+'0box\');" info='+(currentPage-1)+'0box></div></li>';
		$("#timeline").append(timeHtml);
	}else{
			$(".desigenerLoadingMore").html("已经全部加载完毕");
			$(window).unbind();
		}
}

 JSP主要代码:

 <div class="designerList" id="10box"><!-- start designerList -->
		        	<ul class="layout_designer_list" id="layout_designer_list">
		        		<c:forEach var="mentity" items="${list}">
			        		<li class="designer_list_details"><!-- start designer_list_details-->
	        					<div class="user-info-banner"><!-- start user-info-banner-->
									<div class="grid-730 left author-info"><!-- start author-info-->
										<div class="author-portrait left"> <!-- start author-portrait-->
											<a href="#" title="" class="author-portrait-container">
												<div class="portrait-cover"></div>
												<img src="${ctx}/static/images/${mentity.memberPic}" style="float:left" width="115px" height="115px" alt="" style="border:0px;"> 
											</a> 
										</div><!-- end author-portrait-->
									</div><!-- end author-info-->
									<div class="designer_list_details_info"><!-- start designer_list_details_info -->
										<p>${mentity.memberName} <img title="添加关注" class="addClass" src="${ctx}/static/images/add.png" /></p>
										<p>
											<c:if test="${mentity.memberGender==1}">男</c:if>
											<c:if test="${mentity.memberGender==2}">女</c:if>/${mentity.city}/销售
										</p>
										<p>粉丝/${mentity.fans} &nbsp;作品:80</p>
									</div><!-- end designer_list_details_info -->
									
									<div class="opus_images_list">
										<a href="javascipt:void(0);">
											<img src="${ctx}/static/attachment/1.jpg" width="100" height="75"/>
										</a>
										<a href="javascipt:void(0);">
											<img src="${ctx}/static/attachment/2.jpg" width="100" height="75"/>
										</a>
										<a href="javascipt:void(0);">
											<img src="${ctx}/static/attachment/3.jpg" width="100" height="75"/>
										</a>
										<a href="javascipt:void(0);">
											<img src="${ctx}/static/attachment/4.jpg" width="100" height="75"/>
										</a>
									</div>
								</div><!-- end user-info-banner-->
			        		</li><!-- end designer_list_details-->
			        	</c:forEach>
		        	</ul>
		        </div><!--end designerList -->

 

  • 大小: 777.3 KB
  • 大小: 21 KB
  • 大小: 226.9 KB
  • 大小: 103.8 KB
  • 大小: 206.5 KB
  • 大小: 862.5 KB
  • 大小: 708 KB
  • 大小: 1.1 MB
  • 大小: 85.2 KB
  • 大小: 1.1 MB
  • 大小: 860.1 KB
  • 大小: 682.1 KB
  • 大小: 687.7 KB
分享到:
评论

相关推荐

    自定义ListView仿QQ空间下拉图片放大效果(雷惊风)

    本示例“自定义ListView仿QQ空间下拉图片放大效果”由雷惊风实现,旨在模仿QQ空间顶部图片在用户下拉时的放大动画,当用户松手时,图片会有一个反弹的效果。这一功能的实现涉及到多个Android开发的关键知识点,包括...

    Android仿qq空间实现下拉刷新上拉加载

    在Android应用开发中,"仿qq空间实现下拉刷新上拉加载"是一个常见的功能需求,主要涉及到了Android UI设计、滚动事件处理、网络请求以及数据加载等多个知识点。下面将详细阐述这些技术点。 1. **SwipeRefreshLayout...

    博客《PullScrollView详解(一)——自定义控件属性》对应源码

    博客《PullScrollView详解(一)——自定义控件属性》深入探讨了如何自定义这个控件,以满足特定的交互需求。通过阅读博客并分析提供的源码,我们可以学习到以下几个重要的知识点: 1. **自定义控件**:在Android中...

    IOS应用源码——自定义风格UIPickerView.rar

    在iOS开发中,UIPickerView是一个非常常用的组件,它用于展示一系列可滚动的选项,比如日期选择、时间选择或者是下拉列表。这个压缩包“IOS应用源码——自定义风格UIPickerView.rar”显然包含了一个关于如何自定义...

    安卓Android源码——自定义表格自动刷新数据.zip

    本压缩包文件"安卓Android源码——自定义表格自动刷新数据.zip"提供了相关的源码示例,帮助开发者深入理解这一功能的实现。以下是关于这个主题的详细知识讲解。 1. **自定义表格组件**: 安卓系统默认的表格控件`...

    下拉菜单(自定义控件+popuwindow)

    本教程将详细讲解如何利用自定义控件和PopupWindow实现一个仿58同城样式的下拉菜单。 首先,我们要了解什么是自定义控件。在Android系统中,虽然内置了大量的视图组件,如TextView、Button等,但这些组件可能无法...

    vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0

    vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0

    移动端下拉翻页效果

    在移动端开发中,下拉翻页效果是一种常见的用户体验设计,它允许用户通过在屏幕上向下滚动来加载更多内容,通常用于无限滚动列表或者分页浏览。这种效果在新闻、社交媒体、电商应用等场景中广泛使用,因为可以有效地...

    jQuery自定义报警时间轴代码.zip

    本项目“jQuery自定义报警时间轴代码”是为开发者提供的一种功能强大的工具,它允许用户模拟移动报警器的时间轴,并且可以自定义设置报警区间。 这个时间轴代码的核心功能包括: 1. **报警类型选择**:用户可以...

    仿美团下拉筛选菜单——PopupDownMenu

    在Android应用开发中,创建一个类似美团或淘宝的下拉筛选菜单是一项常见的需求。这个功能可以为用户提供方便快捷的筛选选项,提升用户体验。本篇将详细介绍如何使用PopupWindow结合ListView来实现这样的`...

    仿QQ下拉刷新

    【仿QQ下拉刷新】是一种常见的移动应用交互设计,它让用户在顶部下拉时触发页面内容的刷新。这种设计在QQ等社交应用中被广泛采用,后来成为了许多Android和iOS应用的标准特性。实现这一功能主要涉及到滚动视图、动画...

    Android-下拉刷新——卡打印机效果

    总的来说,"Android-下拉刷新——卡打印机效果"是一个融合了Android视图动画、事件监听和自定义View技术的实例,它展示了Android开发中如何通过创新的交互设计提升用户体验。通过研究和实践这个案例,开发者不仅可以...

    android 自定义下拉菜单模式——Spinner与setDropDownViewResource

    在Android开发中,Spinner是一种常用的UI组件,它用于实现下拉选择菜单的功能,类似于iOS中的PickerView。在很多场合,开发者需要对Spinner进行自定义,以满足特定的设计需求。本篇将详细介绍如何利用Spinner和`...

    Android城市级联下拉框(自定义Spinner)

    Spinner是Android中的一个下拉选择控件,它提供了用户友好的交互方式,允许用户在一组预设选项中进行选择。 **1. Spinner的基本使用** Spinner的使用主要包括两步:创建Spinner对象和设置数据源。创建Spinner通常在...

    ios上提下拉翻页插件

    除了EGORefreshTableHeaderView,还有其他类似的库,如MJRefresh,它提供了更多自定义选项和更简单的API,可以实现上拉加载更多和下拉刷新的功能。这些插件都大大简化了开发者实现滚动刷新功能的过程,使得应用更加...

    自定义ScrollView,实现QQ空间阻尼下拉刷新和渐变菜单栏效果

    Android UI设计之&lt;十三&gt;自定义ScrollView,实现QQ空间阻尼下拉刷新和渐变菜单栏效果,详http://blog.csdn.net/llew2011/article/details/52626148

    安卓Android源码——自定义单选、多选对话框及popwindow窗口实例源码.zip

    在安卓(Android)开发中,创建自定义的用户界面是提升应用用户体验的关键步骤之一。本实例源码主要涉及了自定义单选对话框、多选对话框以及popwindow窗口的实现,这些都是Android应用中常见的交互元素。下面我们将...

    jquery树型下拉时间轴特效代码

    本项目涉及的是使用jQuery实现的一种特殊效果——树型下拉时间轴,这种效果通常用于展示一系列按时间顺序排列的事件,用户可以以折叠或展开的方式查看这些事件,类似于QQ空间的时间轴设计。 时间轴是一种直观的数据...

    ios-仿QQ安全中心下拉菜单.zip

    在iOS开发中,创建自定义下拉菜单是一项常见的任务,特别是在设计类似QQ安全中心这样的应用时,为了提供用户友好的交互体验,这类菜单通常用于展示多种功能选项。本项目名为"ios-仿QQ安全中心下拉菜单.zip",显然...

    select 分组下拉菜单自定义样式

    本话题将深入探讨如何自定义`select`分组下拉菜单的样式,以实现更美观且功能丰富的交互效果。 首先,我们需要了解`&lt;select&gt;`的基本结构。一个带有分组的`select`通常会包含`&lt;optgroup&gt;`元素来创建选项组,以及`...

Global site tag (gtag.js) - Google Analytics