热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

不见光就死的ContentPane:原因及解决之道

dijit.layout.TabContainer是非常好用的一款tab组件,而创建每个tab的内容,最常用的就是dijit.layout.ContentPane。ContentPane可以设

dijit.layout.TabContainer是非常好用的一款tab组件,而创建每个tab的内容,最常用的就是dijit.layout.ContentPane。ContentPane 可以设置href,载入一块独立的html内容。每次在一个TabContainer中创建多个tab时,总是有一个tab的内容是当前可见的,而其他tab的内容看不见。这儿就出来一个需求:当每个tab包含的内容都很多时(比如显示一张大数据表格),我们并不希望一口气将所有tab的内容在第一时间都下载下来,而是每次只加载当前要显示的内容。也就是通常所说的“延迟加载”。

“延迟加载”的功能可以很好地改善用户体验,让网页浏览变得更高效,因此是一个可取的优化方法。但采用上面所说的实现,在某些场景中,却存在一个问题:有些ContentPane不见光就死了。

 

下面就来说说这个现象,分析原因并提供了一个解决方案。

 

首先构建一个TabContainer,包含了两个ContentPane。


11111

其中Test[1]是一个自定义的ContentPane,功能不变,只是为每个标准生命周期函数加了控制台打印语句,从而便于我们观察它们的加载顺序。Test被设置为延迟加载,从而在不点击第二个tab之前,它的内容不会被加载。可以看到,当刷新整个页面时,firebug的控制台的输出结果,从而证明Test的内容并未被加载:

preamble
constructor
postMixInProperties
buildRendering
cancel
postCreate
startup

当点击按钮“Replace current tabs”时,TabContainer原有的tab会被清除掉,代之以新的tab。

function rep(){
	var con = dijit.byId("container");
	con.destroyDescendants();
				
	var list = ["dijit.layout.ContentPane", "dijit.layout.ContentPane"];
	for(var i = 0; i  
 
这个时候错误就出现了:

Error: xhr cancelled

从表面意思上来看,这个错误说的是一个xhr请求被取消了。那到底哪里来的xhr请求呢?

其实这要归因于TabContainer的destroyDescendants工作原理。destroyDescendants在运行时,会先销毁当前可见的tab。因此对于一个隐藏tab而言,在被销毁之前,它的显示功能会先被调用。而由于这个tab设置了href,根据延迟加载的原理,这个时候它的内容会通过发出一个xhr请求加载进来。但很不幸地,它的销毁功能紧接着显示功能被调用了,而且由于本地代码运行速度大于xhr请求速度,这个刚发出还没来得及完成的xhr请求就被销毁功能取消了。

 

知道了错误产生的原理,解决方法可以有很多种。为了保持延迟加载,有一种较好的解决方法[2],就是在销毁各个tab时,阻止其显示功能被触发。重写点击“Replace current tabs”按钮的功能如下:

function rep(){
	var con = dijit.byId("container");
	dojo.forEach(con.getChildren(), function(child){
		if(!child.selected){
			con.removeChild(child); //con.closeChild(child);
		}
	});
	con.destroyDescendants(); // destroy the final visible tab
				
	var list = ["dijit.layout.ContentPane", "dijit.layout.ContentPane"];
	for(var i = 0; i  
 

参考文献:

[1] dijit.layout.ContentPane 中的标准方法/事件在不同情况下的调用, http://blog.csdn.net/eengel/article/details/6595473

[2] dojo toolkit mailing list, http://dojo-toolkit.33424.n3.nabble.com/Set-preload-false-not-working-when-programmatically-creating-a-content-pane-as-a-hidden-child-of-a-tr-td3196970.html

 



推荐阅读
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • FineReport平台数据分析图表显示部分系列接口的应用场景和实现思路
    本文介绍了FineReport平台数据分析图表显示部分系列接口的应用场景和实现思路。当图表系列较多时,用户希望可以自己设置哪些系列显示,哪些系列不显示。通过调用FR.Chart.WebUtils.getChart("chartID").getChartWithIndex(chartIndex).setSeriesVisible()接口,可以获取需要显示的系列图表对象,并在表单中显示这些系列。本文以决策报表为例,详细介绍了实现方法,并给出了示例。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
author-avatar
D大龙
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有