网上这方面的要点一大堆,总结了几点,稍懂的看下要点就知道大概,不细说,只为记录下:
- 总是从ID选择器开始继承
- 在class前使用tag
- 将jquery对象缓存起来,如果页面多出引用,可以适当的把变量存成全局变量
- 掌握强大的链式操作
- 使用子查询
- 对直接的DOM操作进行限制
- 冒泡
- 消除无效查询
- 推迟到 $(window).load
- 压缩js,在线压缩地址:http://dean.edwards.name/packer/
- 全面掌握jquery库
- 使用最新版本(这个看情况把,新版一般性能好,但同时体积也大)
- 用for替代each
- 给选择器指定前后文
- 避免使用concat(),利用join()处理长字串
第7点需要说明下:
7. 冒泡
除非在特殊情况下, 否则每一个js事件(例如:click, mouseover, 等.)都会冒泡到父级节点. 当我们需要给多个元素调用同个函数时这点会很有用.
代替这种效率很差的多元素事件监听的方法就是, 你只需向它们的父节点绑定一次, 并且可以计算出哪个节点触发了事件.
例如, 我们要为一个拥有很多输入框的表单绑定这样的行为: 当输入框被选中时为它添加一个class
像这样绑定事件是低效的:
- $("#entryform input").bind("focus", function(){
- $(this).addClass("selected");
- }).bind("blur", function(){
- $(this).removeClass("selected");
- });
我们需要在父级监听获取焦点和失去焦点的事件:
- $("#entryform").bind("focus", function(e){
- // e.target grabs the node that triggered the event.
- var cell = $(e.target);
- cell.addClass("selected");
- }).bind("blur", function(e){
- var cell = $(e.target);
- cell.removeClass("selected");
- });
父级元素扮演了一个调度员的角色, 它可以基于目标元素绑定事件. 如果你发现你给很多元素绑定了同一个事件监听, 那么你肯定哪里做错了.
Tags: jquery, 性能
chive是一个类似phpmyadmin的管理mysql数据库的系统(当然基于B/S),开源并采用Yii框架编写(官网地址:http://www.chive-project.com/),所以建议学习Yii框架的TX可以下下来学习下。
chive的安装其实比phpmyadmin简单咯,直接放在web服务器的指定目录下访问即可,当然你得满足一些安装条件:比如php的PDO扩展、json扩展还有在chive目录下开启rewrite等,官方都有说明,详见:http://www.chive-project.com/Wiki/Installation
但是笔者安装后,用mysql的账户登录发现请求好久最终页面空白无任何响应,分析程序代码(当前版本为0.5.1)才知道,在SiteController.php中的actionIndex()方法中有访问网上的一个xml文件,即如下这行:
$xml = @simplexml_load_file('http://feeds.launchpad.net/chive/announcements.atom');
所以如果无网络情况下或者公司网络访问受限的情况下无法使用系统,解决就很简单咯,直接在有网络条件的情况下下载这个文件并放在指定目录下,如系统的根目录,那么将这行代码替换成下面即可:
$xml = @simplexml_load_file('announcements.atom');
Tags: chive, yii, 安装
关于缓冲的引言(摘自:http://hi.baidu.com/wd_828/blog/item/6e3e71dcfe9a6bf676c638d6.html):
buffer是一个内存地址空间,Linux系统默认大小一般为4096(1kb),即一个内存页。主要用于存储速度不同步的设备或者优先级不同的 设备之间传办理数据的区域。通过buffer,可以使进程这间的相互等待变少。这里说一个通俗一点的例子,你打开文本编辑器编辑一个文件的时候,你每输入 一个字符,操作系统并不会立即把这个字符直接写入到磁盘,而是先写入到buffer,当写满了一个buffer的时候,才会把buffer中的数据写入磁 盘,当然当调用内核函数flush()的时候,强制要求把buffer中的脏数据写回磁盘。
同样的道理,当执行echo,print的时候,输出并没有立即通过tcp传给客户端浏览器显示, 而是将数据写入php buffer。php output_buffering机制,意味在tcp buffer之前,建立了一新的队列,数据必须经过该队列。当一个php buffer写满的时候,脚本进程会将php buffer中的输出数据交给系统内核交由tcp传给浏览器显示。所以,数据会依次写到这几个地方echo/pring -> php buffer -> tcp buffer -> browser
比如我们用的apache作为web服务器,那么此处的tcp buffer就是我们的apache的buffer了,关于ob_flush和flush的区别, Laruence的博文(http://www.laruence.com/2010/04/15/1414.html)讲的比较详细:
ob_flush/flush在手册中的描述, 都是刷新输出缓冲区, 并且还需要配套使用, 所以会导致很多人迷惑…
其实, 他们俩的操作对象不同, 有些情况下, flush根本不做什么事情..
ob_*系列函数, 是操作PHP本身的输出缓冲区.
所以, ob_flush是刷新PHP自身的缓冲区.
而flush, 严格来讲, 这个只有在PHP做为apache的Module(handler或者filter)安装的时候, 才有实际作用. 它是刷新WebServer(可以认为特指apache)的缓冲区.
在apache module的sapi下, flush会通过调用sapi_module的flush成员函数指针, 间接的调用apache的api: ap_rflush刷新apache的输出缓冲区, 当然手册中也说了, 有一些apache的其他模块, 可能会改变这个动作的结果..
有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,
这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。
甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape
浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在
接受到 标记之前,不会显示出整个表格。
一些版本的 Microsoft Internet Explorer 只有当接受到的256个
字节以后才开始显示该页面,所以必须发送一些额外的空格来让这
些浏览器显示页面内容。
所以, 正确使用俩者的顺序是. 先ob_flush, 然后flush,
当然, 在其他sapi下, 不调用flush也可以, 只不过为了保证你代码的可移植性, 建议配套使用.
Tags: flush, ob_flush, 区别
先来看下基本需求:将excel中单元格中的内容包括图片导入到数据库中的指定字段的值,那么假如单元格中既有内容“123”,又贴了某个图片,那我们需要读出该单元格内容和把图片上传并构造成<img/>加入到字段值中,例如存入的字段值为:”123<img src=’images/test.jpg’ />”
首先说明下,经过我测试发现:在excel中贴图片,那么这个图片属于图片左上角开始坐标所在的单元格,即图片占有的其他单元格并不拥有该图片。
来看下基本的代码:
- require_once '../Classes/PHPExcel/IOFactory.php';
-
- $objReader = PHPExcel_IOFactory::createReader('Excel5');
- // 设置载入含有贴图的 sheet
- $objReader->setLoadSheetsOnly(array('sheet1'));
- $objPHPExcel = $objReader->load('test.xls');
-
- $drawing = new PHPExcel_Writer_Excel2007_Drawing();
-
- $drawingHashTable = new PHPExcel_HashTable();
- $drawingHashTable->addFromSource($drawing->allDrawings($objPHPExcel));
-
- for ($i = 0; $i < $drawingHashTable->count(); ++$i)
- {
- $memoryDrawing = $drawingHashTable->getByIndex($i);
- if ($memoryDrawing instanceof PHPExcel_Worksheet_MemoryDrawing)
- {
- $filename = 'images/' . $memoryDrawing->getCoordinates() . '_' . $memoryDrawing->getHashCode() . '.jpg';
- // 将图片存到指定的目录
- imagejpeg($memoryDrawing->getImageResource(), $filename);
- // 获得该图片所在的单元格
- $cell = $memoryDrawing->getWorksheet()->getCell($memoryDrawing->getCoordinates());
- // 将该单元格的值设置为单元格的文本加上图片的 img 标签
- $cell->setValue($cell->getValue() . '<img src="' . $filename . '" />');
- }
- }
- // 再处理将这些单元格的值存入数据库
- // ... ...
上面的代码主要参考Writer类中的save()方法的一些原理,如果想把读出的图片继续存入到excel,那可以参考他的代码
Tags: excel, phpexcel, 图片
PHPExcel是php操作excel的一个类库,详细可以去官网了解下:http://phpexcel.codeplex.com/
当你需要读excel时,你可以直接用工厂类PHPExcel_IOFactory的load方法载入,他会根据文件类型使用对应的的Reader对象读取并装载成一个PHPExcel对象,如下:
- // 载入 excel03
- $objPHPExcel = PHPExcel_IOFactory::load("test.xls");
- // 载入 excel07
- $objPHPExcel = PHPExcel_IOFactory::load("test.xlsx");
当然也可以显式的用PHPExcel_IOFactory的createReader后,在用Reader对象的load方法装载,这样的优点是可以更多的定义载入的选项,比如我们为了性能只载入excel的指定sheet,如下:
- // 创建 Reader 对象,参数为类型,Excel5 适用于 excel97-03, 如果 excel07 则为 Excel2007
- $objReader = PHPExcel_IOFactory::createReader("Excel5");
- // 注意参数是 sheet 的名字数组而不是 sheet 的索引
- $objReader->setLoadSheetsOnly(array('sheet1', 'sheet2'));
- // 这里的文件类型要符合上面创建的类型
- $objPHPExcel = $objReader->load("test.xls");
其他的具体用法参考他给的文档和示例吧,在此就不详述了。
下面回到标题说到的重点,我们通常读取单元格的值的时候使用下面方式获得
- $objPHPExcel->getSheet(1)->getCell('A1')->getValue();
但是对于存在的值为空单元格,excel07下上面返回的是空字符串,而excel03下则返回null,而对于不存在的单元格03和07统一返回null,所以你不能通过”$cellvalue===null”这种方式判断某单元格是否存在,本人就犯了这个错误调了好久才找到是这个原因,悲催。。。
通过看他的代码,才找到正确的判断单元格是否存在的方法,就是调用PHPExcel_Worksheet对象的cellExists方法判断,如下:
- $objPHPExcel->getSheet(1)->cellExists('A1');
另外,对于合并单元格,通常只有合并中的第一个单元格才有对应的值,其他的值都为空,但是通常我们的需求是对于合并的每个单元格都想是对应的值,这种需求实现起来也比较简单,我们可以遍历该sheet的所有单元格,看我们要读取的单元格是否属于其中,如果属于则取这个合并单元格的第一个格子的值就可以了,封装成函数大致的代码如下:
- $cell = $objPHPExcel->getSheet(1)->getCell('A5');
- $cellValue = $cell->getValue();
- if (!$cellValue)
- {
- foreach ($objPHPExcel->getSheet(1)->getMergeCells() as $mergeCell)
- {
- if ($cell->isInRange($mergeCell))
- {
- list($startCell,$endCell) = explode(':', $mergeCell);
- return $objPHPExcel->getSheet(1)->getCell($startCell)->getValue();
- }
- }
- }
- return $cellValue;
Tags: excel, phpexcel, 区别
作者: 蓝色夏威夷
原文地址: http://www.coderbolg.com/content/140.html
最近在做代码规范方面的工作,以前使用Eclipse时有插件支持将SVN版本号自动更新到代码页头注释中去。现在用Zend Studio 7来开发PHP项目,得找一个替代方案来做这个。后来在SVN手册中找到了一个非常简单的解决方案:
1、打开C:/Users/[username]/AppData/Roaming/Subversion文件夹
2、找到 config文件,并打开
3、找到 nable-auto-props = yes 行,去掉行首的注释;
在[auto-props]节上添加以下字段:
*.css = svn:keywords=Id
*.php = svn:keywords=Id
*.html = svn:keywords=Id
*.tpl = svn:keywords=Id
*.txt = svn:keywords=Id
*.js = svn:keywords=Id
保存后创建一个文件,并在文件注释处添加 $Id$ ,然后添加并提交到版本库。提交成功再回过头看看这个文件,当$Id$被替换成类似这样:
$Id: UsersController.php 19629 2011-05-09 10:18:16Z zhuwanchun $
说明已经可以自动将SVN版本号更新到注释啊。注意,这种替换只对新创建的文件有效;当在已经提交到版本库中的文件添加$Id$发现并不会被替换成当前的版本号。
Tags: svn, 注释, 版本
后台已经基本具备所需功能,虽然还有待完善,但是我们的注意力先转移到前台显示上,后台以后再完善!
1、前台显示博客的需求
前台的博客详细内容我们设计了两种方式的url访问,具体如下:
第一种:根据blog主键id来访问,如/blog/3.html,其中3为指定博客的id,id为整数
第二种:根据blog的别名字段alias来访问,如/blog/django_13-framework,其中django13-framework为指定博客的别名,别名应由字母、数字、下划线、短横线组成(设置别名的作用是可以在url中添加与文章相关的关键字,有利于seo)
2、初步实现方案
首先我们先配置url,由于我们要为每个app单独管理自己的url配置,所以我们可以在根目录下的urls.py中添加下面代码:
(全文 …)
Tags: django, djcms, python