jquery动画课程(4)--queue和dequeue

官方文档:

队列的本质是一个数组,对队列的理解先从数组的push和shift开始。

push是从数组尾端插入新的元素,shift是从数组首端删除元素;分别对应队列中得queue和dequeue。我们知道jquery所有动画基于animate方法,而animate的动画默认保存在名为fx的动画队列中。

queue就是将动画放进队列中,dequeue就是将动画从队列中删除并执行它。

$.fn.queue传参形式有:

  1. queue([queue_name]) 查看队列,传入队列名2. queue([queue_name], new_queue) 添加new_queue到队列中,对列名默认为fx,new_queue类型为数组3. queue([queue_name], callback) 添加callback回调函数到队列中,对列名默认为fx,callback类型为函数,当该函数被调用时,会从弹出队列中的下一个元素。

一、队列的存在和执行

我们在页面中常使用这样的语句:

  $('#foo').slideUp().fadeIn();

它的执行顺序是元素先slideUp后再fadeIn,slideUp和fadeIn有先后顺序。jquery会默认地将它们放进名为fx的队列中,我们可以这样认为:

var fx = [slideUp, fadeIn];

    //相当于
    $('#foo').queue('fx', fx);

    //第一步:出列第一个元素slideUp并执行它
    $('#foo').dequeue('fx');    //fx = ['inprogress', fadeIn]

    //第二步:出列第二个元素fadeIn并执行它
    $('#foo').dequeue('fx');    //fx = ['inprogress']

    //第三步,队列fx为空,动画执行完毕
    fx = [];

通过不断的dequeue,fx每个元素逐个依次出列执行,直至队列没有元素。

所以我们很容易发现,当我们书写下面这个语句的时候,执行顺序并不是按照书写顺序来执行了:

  $('#foo').slideUp().fadeIn().css({'width':'200px'});

它的执行顺序是元素宽度马上变成200px的同时,slideUp也在执行,slideUp执行完后再执行fadeIn。

二、队列的回调

官网中的例子:

$(document.body).click(function () {
        $("div")
                .show("slow")
                .animate({left : "+=200"}, 2000)
                .queue(function () {
                    $(this).addClass("newcolor").dequeue();
                })
                .animate({left : "-=200"}, 500)
                .queue(function () {
                    $(this).removeClass("newcolor").dequeue();
                })
                .slideUp();
    });

在click之后,div元素会先出现,再往右运动两秒,接着添加newcolor的类名,再往左回到起点,去除newcolor类名后收起来消失。

.queue(function () {
        $(this).addClass("newcolor").dequeue();
    })

这个匿名函数是queue的回调函数,$(this).dequeue()在这里的作用是弹出队列中的下一个元素。

如果我们将这句话中的dequeue去除会怎样呢?

$(document.body).click(function () {
        $("div")
                .show("slow")
                .animate({left : "+=200"}, 2000)
                .queue(function () {
                    $(this).addClass("newcolor");//.dequeue();
                })
                .animate({left : "-=200"}, 500)
                .queue(function () {
                    $(this).removeClass("newcolor").dequeue();
                })
                .slideUp();
    });

运行后可以知道脚本在执行完addClass(’newcolor’)后停止了。虽然队列中还有元素在排队,但是去除dequeue后没有将下个元素抛出,所以停止了执行。这就是dequeue的作用,弹出下一个元素,让队列执行下去。

如果将上面的脚本再修改下:

$(document.body).click(function () {
        $("div")
                .show("slow")
                .animate({left : "+=200"}, 2000)
                .queue(function () {
                    $(this).addClass("newcolor").dequeue();
                    $(this).slideDown("slow");//添加slideDown
                })
                .animate({left : "-=200"}, 500).queue(function () {
                    $(this).removeClass("newcolor").dequeue();
                })
                .slideUp();
    });

div中的fx队列最后会增加一个排队元素slideDown,所以最后slideUp收起收,又再缓缓地slideDown下来。

三、队列的自定义

我们可以通过这样的方式来创建自己的队列:

var queue = [
        function () {
            console.log('NO.1');
        },
        function () {
            console.log('NO.2');
        }
    ];
    $('div').queue('a1', queue);

这样我们创建了一个名为a1的队列,队列里有两个元素在排队。

打印队列长度:

$('div').queue('a1').length;//输出2

通过dequeue来让队列的第一个元素出列:

$('div’).dequeue('a1’);//输出NO.1

打印下队列现在的长度:

$('div’).queue(‘a1').length;//输出1

 

接着再dequeue一次,queue队列就会清空,全部队列出列执行完毕。

按照这个思路,我们可以运用之前学习的回调函数方法,将出列的方法放在回调函数中,在完成一个动画后调用出列,就可以将队列依次执行。

思路:

var queue = [
        function () {
            $('item-1').fadeIn(function(){
                $('div').dequeue('a1');
            });
        },
        function () {
            $('item-2').fadeIn(function(){
                $('div').dequeue('a1');
            });
        },
        function () {
            $('item-3').fadeIn(function(){
                $('div').dequeue('a1');
            });
        }
    ];
    $('div').queue('a1', queue);

    //触发动画
    $('div').dequeue('a1');

成型:

var queue = [
        function () {
            $('item-1').fadeIn(dequeue);
        },
        function () {
            $('item-2').fadeIn(dequeue);
        },
        function () {
            $('item-3').fadeIn(dequeue);
        }
    ];

    var dequeue = function(){
        $('div').dequeue('a1');
    };
    $('div').queue('a1', queue);

    //触发动画
    dequeue();

 

item-1,item-2,item-3会依次的出现。

四、队列的运用场景

在动画效果中需要按序来执行的时候都可以用到队列,特别是在动画绑定在不同的dom元素上和某些效果没有用到animate方法的时候。

案例:

  1. 京东双12头部文案出现顺序:http://sale.jd.com/act/J067lGoWuw.html

五、作业

 

地址:http://1.javier.sinaapp.com/case/jquery/20141202.html

40 signs you really are a lousy PHP programmer

Disclaimer: This collection was published a few years ago on my blog, it was met with heavy criticism about featuring micro-optimiziations which have little to no effect at all compared to other things you can do which was then and is still today very true :)

As this was copied & published on a few hundred blogs in the aftermath here again the original list exactly as I published it many years ago.

I will follow up shortly with an article on more effective methods. Until then …

This is something I prefer to call my “programming list of shame”. Although having a formal university education with courses on software engineering, enterprise software architecture & database design I have been guilty of every single one of those things at one time or another. This is completely subjective & Eclipse oriented.

You are a lousy PHP programmer if you

  1. don’t comment your code properly with something like phpDoc2. don’t see the need and/or benefits of a good programming IDE like Zend Studio or Eclipse PDT3. have never used some form of version control like Subclipse4. don’t adopt some coding & naming standards and general conventions and stick to to them at least throughout the project5. don’t use a consistent methodology6. don’t escape and/or validate properly input or sql queries7. don’t plan your application thoroughly before starting to code8. don’t use test-driven development9. don’t program & test with error reporting on10. don’t see the benefits of a debugger11. don’t refactor your code12. don’t keep the different layers seperated using something like MVC13. don’t know what these stand for: KISS, DRY, MVC, OOP, REST14. don’t return content but echo or print it from your functions or classes15. have never seen the advantage of unit tests or testing in general16. return HTML, not data, strings, or objects.17. hard code messages and configuration parameters18. don’t optimize your sql queries19. don’t use __autoload20. don’t allow intelligent error handling21. use $_GET instead of $_POST for any destructive actions22. don’t know how to use regular expressions23. you’ve never heard of sql injection or cross-site scripting24. don’t allow simple configuration, can be parameters passed to a class’s constructor, set/get methods called later, or constants defined at a runtime.25. don’t understand the benefits and limitations of Object Oriented Programming26. misuse OOP / everything you write , no matter how small is OOP27. you think reusable software equals/requires your code to be OOP28. don’t choose intelligent defaults29. don’t have one single configuration file30. don’t want the file contents to be seen, but give it a .inc extension instead of .php31. don’t use a database abstraction layer32. don’t keep it DRY, Don’t repeat yourself. If you have to copy and paste or duplicate something your design may be off.33. don’t make a function/class/method do just one thing and don’t make them interact.34. don’t try to take advantage of OOP specific features like abstract/interface classes, inheritage polymorphism & access modifiers.35. don’t optimize your application design with established design patterns36. don’t allow your user to define a base directory if you have multiple files and/or directories37. pollute the global namespace, one option is to prefix the functions in your library with a common string38. don’t allow a table prefix when using database tables39. use a separate template engine40. don’t take a look at established php frameworks for inspiration, most of them have advanced web dev concepts and good code.

Post From:

http://reinholdweber.com/2012/04/13/40-signs-you-really-are-a-lousy-php-programmer/
test

.htaccess详解

.htaccess是什么

.htaccess文件(或者"分布式配置文件")提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。

概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:AccessFileName .config 。

笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。

工作原理

      .htaccess文件(或者"分布式配置文件")提供了针对每个目录改变配置的方法,即在一个特定的目录中放置一个包含指令的文件,其中的指令作用于此目录及其所有子目录。
说明:
如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:
AccessFileName .config
通常,.htaccess文件使用的配置语法和主配置文件一样。AllowOverride指令按类别决定了.htaccess文件中哪些指令才是有效的。如果一个指令允许在.htaccess中使用,那么在本手册的说明中,此指令会有一个覆盖项段,其中说明了为使此指令生效而必须在AllowOverride指令中设置的值。

(不)使用.htaccess文件的场合

      一般情况下,不应该使用.htaccess文件,除非你对主配置文件没有访问权限。有一种很常见的误解,认为用户认证只能通过.htaccess文件实现,其实并不是这样,把用户认证写在主配置文件中是完全可行的,而且是一种很好的方法。
      .htaccess文件应该被用在内容提供者需要针对特定目录改变服务器的配置而又没有root权限的情况下。如果服务器管理员不愿意频繁修改配置,则可以允许用户通过.htaccess文件自己修改配置,尤其是ISP在同一个机器上运行了多个用户站点,而又希望用户可以自己改变配置的情况下。
虽然如此,一般都应该尽可能地避免使用.htaccess文件。任何希望放在.htaccess文件中的配置,都可以放在主配置文件的<Directory>段中,而且更高效。
避免使用.htaccess文件有两个主要原因。
       首先是性能。如果AllowOverride启用了.htaccess文件,则Apache需要在每个目录中查找.htaccess文件,因此,无论是否真正用到,启用.htaccess都会导致性能的下降。另外,对每一个请求,都需要读取一次.htaccess文件。
       还有,Apache必须在所有上级的目录中查找.htaccess文件,以使所有有效的指令都起作用(参见指令的生效),所以,如果请求/www/htdocs/example中的页面,Apache必须查找以下文件:
/.htaccess /www/.htaccess /www/htdocs/.htaccess /www/htdocs/example/.htaccess
总共要访问4个额外的文件,即使这些文件都不存在。(注意,这可能仅仅由于允许根目录"/"使用.htaccess ,虽然这种情况并不多。)

       其次是安全。这样会允许用户自己修改服务器的配置,这可能会导致某些意想不到的修改,所以请认真考虑是否应当给予用户这样的特权。但是,如果给予用户较少的特权而不能满足其需要,则会带来额外的技术支持请求,所以,必须明确地告诉用户已经给予他们的权限,说明AllowOverride设置的值,并引导他们参阅相应的说明,以免日后生出许多麻烦。
注意,在/www/htdocs/example目录下的.htaccess文件中放置指令,与在主配置文件中<Directory /www/htdocs/example>段中放置相同指令,是完全等效的。

      /www/htdocs/example目录下的.htaccess文件的内容:
AddType text/example .exm
httpd.conf文件中摘录的内容:
<Directory /www/htdocs/example>
AddType text/example .exm
</Directory>
但是,把配置放在主配置文件中更加高效,因为只需要在Apache启动时读取一次,而不是在每次文件被请求时都读取。
将AllowOverride设置为none可以完全禁止使用.htaccess文件:
AllowOverride None

指令的作用范围

.htaccess文件中的配置指令作用于.htaccess文件所在的目录及其所有子目录,但是很重要的、需要注意的是,其上级目录也可能会有.htaccess文件,而指令是按查找顺序依次生效的,所以一个特定目录下的.htaccess文件中的指令可能会覆盖其上级目录中的.htaccess文件中的指令,即子目录中的指令会覆盖父目录或者主配置文件中的指令。

疑难解答

      如果在.htaccess文件中的某些指令不起作用,可能有多种原因。
最常见的原因是AllowOverride指令没有被正确设置,必须确保没有对此文件区域设置 AllowOverride None 。有一个很好的测试方法,就是在.htaccess文件随便增加点无意义的垃圾内容,如果服务器没有返回了一个错误消息,那么几乎可以断定设置了 AllowOverride None 。
在访问文档时,如果收到服务器的出错消息,应该检查Apache的错误日志,可以知道.htaccess文件中哪些指令是不允许使用的,也可能会发现需要纠正的语法错误。

.htaccess工具

不会写的朋友,在这介绍一款很不错.htaccess的重定向—URL重写工具htaccess生成工具


htaccess语法教程

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?xxx.com$
RewriteCond %{REQUEST_URI} !^/blog/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /blog/$1

没有输入文件名的默认到到首页

RewriteCond %{HTTP_HOST} ^(www.)?xxx.com$
RewriteRule ^(/)?$ blog/index.php [L]

 

下面我开始解说一下上面的意思:

RewriteEngine On】

表示重写引擎开,关闭off,作用就是方便的开启或关闭以下的语句,这样就不需要一条一条的注释语句了。

RewriteCond %{HTTP_HOST} ^(www.)?xxx.com$】

这是重写条件,前面%{HTTP_HOST}表示当前访问的网址,只是指前缀部分,格式是www.xxx.com不包括“http://”和“/”,^表示 字符串开始,$表示字符串结尾,.表示转义的. ,如果不转义也行,推荐转义,防止有些服务器不支持,?表示前面括号www.出现0次或1次,这句规则的意思就是如果访问的网址是xxx.com或者 www.xxx.com就执行以下的语句,不符合就跳过。

【RewriteCond %{REQUEST_URI} !^/blog/】

也是重写条件,%{REQUEST_URI}表示访问的相对地址,就是相对根目录的地址,就是域名/后面的成分,格式上包括最前面的“/”,!表示非,这句语句表示访问的地址不以/blog/开头,只是开头^,没有结尾$

【RewriteCond %{REQUEST_FILENAME} !-f】

【RewriteCond %{REQUEST_FILENAME} !-d】

这两句语句的意思是请求的文件或路径是不存在的,如果文件或路径存在将返回已经存在的文件或路径

RewriteRule ^(.*)$ /blog/$1】

重写规则,最重要的部分,意思是当上面的RewriteCond条件都满足的时候,将会执行此重写规则,^(.)$是一个正则表达的 匹配,匹配的是当前请求的URL,^(.)$意思是匹配当前URL任意字符,.表示任意单个字符,表示匹配0次或N次(N>0),后面 /blog/$1是重写成分,意思是将前面匹配的字符重写成/blog/$1,这个$1表示反向匹配,引用的是前面第一个圆括号的成分,即^(.)$中 的.* ,其实这儿将会出现一个问题,后面讨论。

【RewriteCond %{HTTP_HOST} ^(www.)?xxx.com$】

【RewriteRule ^(/)?$ blog/index.php [L]】

这两句的意思是指请求的host地址是www.xxx.com是,如果地址的结尾只有0个或者1个“/”时,将会重写到子目录下的主页,我猜想这主要因为重写后的地址是不能自动寻找主页的,需要自己指定。

现在说说出现的问题,RewriteRule ^(.)$ /blog/$1 前部分 ^(.)$ 将会匹配当前请求的url。

例如:请求网址是http://www.xxx.com/a.html,到底是匹配整个http://www.xxx.com/a.html,还是只匹配/a.html即反斜杠后面的成分,还是只匹配a.html。

答案是:根据RewriteBase规则规定,如果rewritebase 为/,将会匹配a.html,不带前面的反斜杠,所以上条语句应该写成RewriteRule ^(.*)$ blog/$1(不带/),不过实际应用上带上前面的反斜杠,也可以用,可能带不带都行。现在问题出来了,如果不设置rewritebase 为/ ,将会匹配整个网址http://www.xxx.com/a.html,显然这是错误的,所以应该添加这条:RewiteBase /

还有一个问题是,不能保证每个人输入的网址都是小写的,如果输入大写的呢,linux系统是区分大小写的,所以应该在RewriteCond后添加[NC]忽略大小写的。

至此,完整的语句应该是:

RewriteEngine On
RewiteBase /
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/blog/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ blog/$1

# 没有输入文件名的默认到到首页
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ [NC]
RewriteRule ^(/)?$ blog/index.php [L]

 

如果后面还继续有语句的,就不应该加上最后的[L],因为这是表示最后一条语句的意思。

防盗链的语句,同样需要添加RewiteBase /,如下:

RewriteEngine on
RewiteBase /
RewriteCond %{HTTP_REFERER} !^$ [NC]
RewriteCond %{HTTP_REFERER} !xxx.info [NC]
RewriteRule \.(jpg|gif|png|bmp|swf|jpeg)$ /error/daolian.gif [R,NC,L]

如果后面还继续有语句的,就不应该加上最后的[L],/error/daolian.gif为别人盗链时显示的图片。

下面附上简单的语法规则和flags

【RewriteCond语法】

RewriteCond TestString CondPattern [flags]

rewritecond的其他用法:

"-d"(目录)

将TestString视为一个路径名并测试它是否为一个存在的目录。

"-f"(常规文件)

将TestString视为一个路径名并测试它是否为一个存在的常规文件。

"-s"(非空的常规文件)

将TestString视为一个路径名并测试它是否为一个存在的、尺寸大于0的常规文件。

**"-l"(符号连接)

**将TestString视为一个路径名并测试它是否为一个存在的符号连接。

"-x"(可执行)

将TestString视为一个路径名并测试它是否为一个存在的、具有可执行权限的文件。该权限由操作系统检测。

**"-F"(对子请求存在的文件)

**检查TestString是否为一个有效的文件,而且可以在服务器当前的访问控制配置下被访问。它使用一个内部子请求来做检查,由于会降低服务器的性能,所以请谨慎使用!

"-U"(对子请求存在的URL)

检查TestString是否为一个有效的URL,而且可以在服务器当前的访问控制配置下被访问。它使用一个内部子请求来做检查,由于会降低服务器的性能,所以请谨慎使用!

【RewriteRule语法】

RewriteRule Pattern Substitution [flags]

【flags】

**"chain|C"(链接下一规则)

**此标记使当前规则与下一个规则相链接。它产生这样的效果:如果一个规则被匹配,则继续处理其后继规则,也就是这个标记不起作用;如果该规则不被匹配,则其后继规则将被跳过。比如,在一个目录级规则中执行一个外部重定向时,你可能需要删除”.www”(此处不应该出现”.www”)。

**"cookie|CO=NAME:VAL:domain[:lifetime[:path]]"(设置cookie) **

在客户端设置一个cookie。cookie的名称是NAME,值是VAL。domain是该cookie的域,比如".apache.org",可选的lifetime是cookie的有效期(分钟),可选的path是cookie的路径。

"env|E=VAR:VAL"(设置环境变量)

此标记将环境变量VAR的值为VAL,VAL可以包含可扩展的正则表达式反向引用($N和%N)。此标记可以多次使用以设置多个变量。这些变量可以在其后许多情况下被间接引用,通常是在XSSI(<!–#echo var=”VAR”–>)或CGI($ENV{"VAR"})中,也可以在后继的RewriteCond指令的CondPattern参数中通过%{ENV:VAR}引用。使用它可以记住从URL中剥离的信息。

"forbidden|F"(强制禁止URL)

强制禁止当前URL,也就是立即反馈一个HTTP响应码403(被禁止的)。使用这个标记,可以链接若干个RewriteConds来有条件地阻塞某些URL。

"gone|G"(强制废弃URL)

强制当前URL为已废弃,也就是立即反馈一个HTTP响应码410(已废弃的)。使用这个标记,可以标明页面已经被废弃而不存在了。

"handler|H=Content-handler"(强制指定内容处理器)

强自制定目标文件的内容处理器为Content-handler。例如,用来模拟mod_alias模块的ScriptAlias指令,以强制映射文件夹内的所有文件都由”cgi-script”处理器处理。

"last|L"(结尾规则)

立即停止重写操作,并不再应用其他重写规则。它对应于Perl中的last命令或C语言中的break命令。这个标记用于阻止当前已被重写的URL被后继规则再次重写。例如,使用它可以重写根路径的URL("/")为实际存在的URL(比如:"/e/www/")。

**"next|N"(从头再来)

**重新执行重写操作(从第一个规则重新开始)。此时再次进行处理的URL已经不是原始的URL了,而是经最后一个重写规则处理过的URL。它对应于Perl中的next命令或C语言中的continue命令。此标记可以重新开始重写操作(立即回到循环的开头)。但是要小心,不要制造死循环!

**"nocase|NC"(忽略大小写)

**它使Pattern忽略大小写,也就是在Pattern与当前URL匹配时,"A-Z"和"a-z"没有区别。

"noescape|NE"(在输出中不对URI进行转义)

此标记阻止mod_rewrite对重写结果应用常规的URI转义规则。 一般情况下,特殊字符("%", "$", ";"等)会被转义为等值的十六进制编码("%25′, "%24′, "%3B"等)。此标记可以阻止这样的转义,以允许百分号等符号出现在输出中,比如:

RewriteRule /foo/(.*) /bar?arg=P1%3d$1 [R,NE]

可以使"/foo/zed转向到一个安全的请求"/bar?arg=P1=zed"。

**"nosubreq|NS"(不对内部子请求进行处理)

**在当前请求是一个内部子请求时,此标记强制重写引擎跳过该重写规则。比如,在mod_include试图搜索目录默认文件(index.xxx)时,Apache会在内部产生子请求。对于子请求,重写规则不一定有用,而且如果整个规则集都起作用,它甚至可能会引发错误。所以,可以用这个标记来排除某些规则。

使用原则:如果你为URL添加了CGI脚本前缀,以强制它们由CGI脚本处理,但对子请求处理的出错率(或者资源开销)很高,在这种情况下,可以使用这个标记。

"proxy|P"(强制为代理)

此标记使替换成分被内部地强制作为代理请求发送,并立即中断重写处理,然后把处理移交给mod_proxy模块。你必须确保此替换串是一个能够被mod_proxy处理的有效URI(比如以http://hostname开头),否则将得到一个代理模块返回的错误。使用这个标记,可以把某些远程成分映射到本地服务器域名空间,从而增强了ProxyPass指令的功能。

注意:要使用这个功能,必须已经启用了mod_proxy模块。

"passthrough|PT"(移交给下一个处理器)

此标记强制重写引擎将内部request_rec结构中的uri字段设置为filename字段的值,这个小小的修改使得RewriteRule指令的输出能够被(从URI转换到文件名的)Alias, ScriptAlias, Redirect等指令进行后续处理[原文:This flag is just a hack to enable post-processing of the output of RewriteRule directives, using Alias, ScriptAlias, Redirect, and other directives from various URI-to-filename translators.]。举一个能说明其含义的例子: 如果要将/abc重写为/def, 然后再使用mod_alias将/def转换为/ghi,可以这样:

RewriteRule ^/abc(.*) /def$1 [PT]

Alias /def /ghi

如果省略了PT标记,虽然将uri=/abc/…重写为filename=/def/…的部分运作正常,但是后续的mod_alias在试图将URI转换到文件名时会遭遇失效。

注意:如果需要混合使用多个将URI转换到文件名的模块时,就必须使用这个标记。。此处混合使用mod_alias和mod_rewrite就是个典型的例子。

"qsappend|QSA"(追加查询字符串)

此标记强制重写引擎在已有的替换字符串中追加一个查询字符串,而不是简单的替换。如果需要通过重写规则在请求串中增加信息,就可以使用这个标记。

"redirect|R [=code]"(强制重定向)

若Substitution以http://thishost[:thisport]/(使新的URL成为一个URI)开头,可以强制性执行一个外部重定向。如果没有指定code,则产生一个HTTP响应码302(临时性移动)。如果需要使用在300-400范围内的其他响应代码,只需在此指定即可(或使用下列符号名称之一:temp(默认), permanent, seeother)。使用它可以把规范化的URL反馈给客户端,如将”/~”重写为”/u/”,或始终对/u/user加上斜杠,等等。

注意:在使用这个标记时,必须确保该替换字段是一个有效的URL。否则,它会指向一个无效的位置!并且要记住,此标记本身只是对URL加上http://thishost[:thisport]/前缀,重写操作仍然会继续进行。通常,你还会希望停止重写操作而立即重定向,那么就还需要使用"L’标记。

"skip|S=num"(跳过后继规则)

此标记强制重写引擎跳过当前匹配规则之后的num个规则。它可以模拟if-then-else结构:最后一个规则是then从句,而被跳过的skip=N个规则是else从句。注意:它和"chain|C"标记是不同的!

"type|T=MIME-type"(强制MIME类型)

强制目标文件的MIME类型为MIME-type,可以用来基于某些特定条件强制设置内容类型。比如,下面的指令可以让.php文件在以.phps扩展名调用的情况下由mod_php按照PHP源代码的MIME类型(application/x-httpd-php-source)显示:

RewriteRule ^(.+.php)s$ $1 [T=application/x-httpd-php-source]

JS中的prototype

JS中的phototype是JS中比较难理解的一个部分

本文基于下面几个知识点:

1 原型法设计模式

在.Net中可以使用clone()来实现原型法

原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展。我们称B的原型为A。

2 javascript的方法可以分为三类:

a 类方法

b 对象方法

c 原型方法

例子:

function People(name)
{
this.name=name;
//对象方法
this.Introduce=function(){
alert("My name is "+this.name);
}
}
//类方法
People.Run=function(){
alert("I can run");
}
//原型方法
People.prototype.IntroduceChinese=function(){
alert("我的名字是"+this.name);
}
//测试
var p1=new People("Windking");
p1.Introduce();
People.Run();
p1.IntroduceChinese();

 

3 obj1.func.call(obj)方法

意思是将obj看成obj1,调用func方法.

 

 

好了,下面一个一个问题解决:

prototype是什么含义?

javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。

A.prototype = new B();

理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。

先看一个实验的例子:

function baseClass()
{
    this.showMsg = function()
    {
         alert("baseClass::showMsg");   
    }
}
function extendClass()
{
}
extendClass.prototype = new baseClass();
var instance = new extendClass();
instance.showMsg(); // 显示baseClass::showMsg

 

我们首先定义了baseClass类,然后我们要定义extentClass,但是我们打算以baseClass的一个实例为原型,来克隆的extendClass也同时包含showMsg这个对象方法。

extendClass.prototype = new baseClass()就可以阅读为:extendClass是以baseClass的一个实例为原型克隆创建的。

 

那么就会有一个问题,如果extendClass中本身包含有一个与baseClass的方法同名的方法会怎么样?

下面是扩展实验2:

function baseClass()
{
    this.showMsg = function()
    {
        alert("baseClass::showMsg");   
    }
}
function extendClass()
{
    this.showMsg =function ()
    {
        alert("extendClass::showMsg");
    }
}
extendClass.prototype = new baseClass();
var instance = new extendClass();
instance.showMsg();//显示extendClass::showMsg

 

实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。

那么又会有一个新的问题:

如果我想使用extendClass的一个实例instance调用baseClass的对象方法showMsg怎么办?

答案是可以使用call:

extendClass.prototype = new baseClass();
var instance = new extendClass();
var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//显示baseClass::showMsg

这里的baseinstance.showMsg.call(instance);阅读为“将instance当做baseinstance来调用,调用它的对象方法showMsg”

好了,这里可能有人会问,为什么不用baseClass.showMsg.call(instance);

这就是对象方法和类方法的区别,我们想调用的是baseClass的对象方法

 

 

最后,下面这个代码如果理解清晰,那么这篇文章说的就已经理解了:

<script type="text/javascript">
function baseClass()
{
    this.showMsg = function()
    {
        alert("baseClass::showMsg");   
    }
    this.baseShowMsg = function()
    {
        alert("baseClass::baseShowMsg");
    }
}
baseClass.showMsg = function()
{
    alert("baseClass::showMsg static");
}
function extendClass()
{
    this.showMsg =function ()
    {
        alert("extendClass::showMsg");
    }
}
extendClass.showMsg = function()
{
    alert("extendClass::showMsg static")
}
extendClass.prototype = new baseClass();
var instance = new extendClass();
instance.showMsg(); //显示extendClass::showMsg
instance.baseShowMsg(); //显示baseClass::baseShowMsg
instance.showMsg(); //显示extendClass::showMsg
baseClass.showMsg.call(instance);//显示baseClass::showMsg static
var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//显示baseClass::showMsg
</script>

打印web分页

在B/S程序中,对打印页面的控制,CSS相对比较弱,例如: 自动分页, 就基本没啥实际用途。我们通常需要自己在需要的时候,强制浏览器分页,这时可以使用以下样式:

<style type="text/css">
    .page-divider {
        page-after-break: always;
    }
</style>
  • auto :对页面分割没有影响。
  • always:强制在元素后出现页分割符。
  • avoid :避免在元素后出现页分割符。
  • left :在元素后面插入页分割符直到它到达一个空白的左页边。
  • right :在元素后面插入页分割符直到它到达一个空白的右页边。
  • inherit :使用与父元素相同的属性值。
    web打印分页时,在需要分页的地方像下面这样插入标签即可!
<div class="page-divider"></div>

但在使用的时候,可能会碰到IE能正常分页,但Firefox却没有任何效果。经过分析发现,在Firefox中使用page-break-after属性时,不能像所有的打印内容都放在一个表中。也就是说Firefox是不能将表断开的。所以在Firefox中使用page-break-after进行分页打印,要避免将打印的内容放在一个表中,取代的方法可以将内容放在一个div中。

主流浏览器下背景色半透明的兼容性

最近的项目中遇到了这个问题,背景颜色半透明效果的需求。以前只是知道使用alpha通道和opacity来实现透明,这次发现问题并不是这么简单的,背景色透明了,但是文字也跟随透明了!所以做了一下研究,总结出来各浏览器的差异和文字不透明处理,文章最后提出了建议采用的方法。

一、使用rgba()样式

问题发生在这样的文档结构上:

<div class="inner">
     <p>文字</p>
</div>

div.inner使用半透明背景,文字p为白色。一般情况下,我们会这样来处理样式:

.inner {
    background-color: rgba(0, 0, 0, 0.5);
}
.inner p {
    color: #fff;
}

这样写在支持CSS3的浏览器中没有压力,但是在IE8及以下这样写就实现不了效果了。

IE6、IE7和IE8不支持rgb()中的alpha通道,rgba()他们不认识就不解析,所以背景是全透明的,没有达到预期效果。

IE9 FireFox Chrome Safari Opera

IE6 IE7 IE8

![rgba()在支持CSS3的浏览器中实现背景色半透明](/uploads/2012/04/image_thumb5.png "rgba()在支持CSS3的浏览器中实现背景色半透明") ![rgba()在不支持CSS3的浏览器中效果](/uploads/2012/04/image_thumb6.png "rgba()在不支持CSS3的浏览器中效果")
可以看到,支持rgba()的浏览器半透明效果很好!背景透明了,子节点的文字依然不透明。

二、使用rgb()和opacity

同样的结构,我们换个样式,使用rgb()和opacity,因为IE8及以下不支持opacity,因此使用filter属性。filter属性在非IE浏览器下均不能识别。

.inner {
    background-color: rgb(0, 0, 0);
    opacity: 0.5;               /*IE9 FF Chrome Opera*/
    filter: alpha(opacity=50);  /*IE*/
    *zoom: 1;                   /*IE7下激发hasLayout*/
}
.inner p {
    color: #fff;
}

这样的做法就能支持大部分的浏览器了,除了IE6。

FireFox Chrome Safari Opera IE9 IE8 IE7

IE6
![rgb()和opacity实现背景色半透明](/uploads/2012/04/image_thumb7.png "rgb()和opacity实现背景色半透明") ![IE6不支持opacity和filter](/uploads/2012/04/image_thumb8.png "IE6不支持opacity和filter")
可以看到,背景虽然是透明了,但是文字也跟随着透明了。这样的情况在IE8及以下比较好解决,反而比较标准的浏览器就不好解决了。

注:在IE9中opacity和filter它都能解析,如果两个同时存在,则以透明度较低即数字较大的为准,不会叠加。例如:filter:alpha(opacity=80);opacity:0.5;它会以80%的透明度来解析。

在IE8和IE7中对文字的节点添加“position: relative;”样式就能实现文字不透明了。

.inner p {
    color: #fff;
    position: relative;
}

效果图:

IE7和IE8使用position:relative实现文字不透明

三、总结

在文档结构不能修改的情况下,遇到这样的问题我们可以这样解决。

  1. 对支持CSS3的浏览器使用rgba()来实现;
  2. 对IE8和IE7使用rgb()、opacity和position:relative来实现;
  3. 对于IE6可以使用1像素图片repeat来实现。
    而我们往往希望使用一套代码简洁的来实现这样的效果,下面我想到两个方案来实践:
方案一:使用图片来替代。

如果你的站点打算兼容IE6而且这样的使用范围广的话,那毫不犹豫的使用上面说到的使用图片,并且在IE6下需要对图片加上IE滤镜,这样做的同时对这张1像素图片进行做data-uri转码,直接写进样式表中。不过滤镜只能使用在背景图为no-repeat的情况下,所以,完美的做法需要加上js来使它透明化。

.inner {
    background: url(alpha-bg/alpha-bg-50.png) repeat;
}

js脚本处理,这里使用了jQuery和fixPNG()方法。

<!--[if IE 6]>
    <script type="text/javascript" src="alpha-bg/jquery-1.7.1.min.js"></script>
    <script type="text/javascript" src="alpha-bg/ie6_png_patch.js"></script>
    <script type="text/javascript">$('.inner').fixPNG();</script>
<![endif]-->
方案二:不使用图片,舍弃IE6。

如果你的站点不打算兼容IE6,在IE6下背景色全黑影响不大的话,我们考虑使用hack。

同时将上面说到的第1点和第2点同时写进样式表,这样做的会产生一个问题。在IE9中,它既支持opacity又同时支持filter!所以这样在IE9下变得非常的透明!因为它在rgba()中已经半透明了,解析到filter或者opacity属性时又再透明一次,做了叠加!

所以可以这样写:

.inner {
    /*IE*/
    background-color: rgb(0, 0, 0);
    filter: alpha(opacity=50);
    *zoom: 1;
    /*NO-IE*/
    background-color: rgba(0, 0, 0, .5);
    /*IE9*/
    background-color: #0009;
}
.inner p {
    position: relative;
}

上面的样式表中使用了IE9特有的hack标记”9”,使背景色被黑色覆盖。

注:注意上面属性的抒写顺序,且只能使用16进制表示颜色,不能使用rgb()。

方案三、洁癖方案。

这个方案综合了方案一和方案二,使各浏览器下的效果都一致。

css可以这样写:

.inner {
    /*IE*/
    background-color: rgb(0, 0, 0);
    filter: alpha(opacity=50);
    *zoom: 1;
    /*NO-IE*/
    background-color: rgba(0, 0, 0, .5);
    /*IE9*/
    background-color: #0009;
    _background: url(alpha-bg/alpha-bg-50.png) repeat;
}
.inner p {
    position: relative;
}

在使用bootstrap框架中,less可以这样写:

.css-background-transparent(@color: #000, @opacity: 50) {
    /*IE*/
    background-color: @color;
    filter: ~"alpha(opacity=@{opacity})";
    *zoom: 1;
    /*NO-IE*/
    #translucent>.background(@color, @opacity / 100);
    /*IE9*/
    background-color: ~"@{color} 9";
    /*IE6*/
    _background: url("alpha-bg/alpha-bg-@{opacity}.png") repeat;
}

四、测试环境和页面

查看测试页面:css-background-transparent.html

<!DOCTYPE HTML>
<html lang="zh-cn">
<head>
    <meta charset="utf-8">
    <meta name="Author" content="mumu mumu@imozo.cn">
    <title>主流浏览器下背景色半透明的兼容性</title>
    <style type="text/css">
        .rgba,
        .rgb,
        .scheme-one,
        .scheme-two,
        .scheme-three {
            width: 400px;
            background: url(alpha-bg/bg.jpg) 0 -80px no-repeat;
        }
        p {
            margin: 1em 0;
            text-align: center;
        }
        .inner {
            margin: 0 15px;
            padding: 10px;
            color: #fff;
        }
        .inner p.relative {
            position: relative;/*IE7、8下文字不透明处理*/
        }
        /*rgba*/
        .rgba .inner {
            background-color: rgba(0, 0, 0, .5);
        }
        /*rgb*/
        .rgb .inner {
            background-color: rgb(0, 0, 0);
            opacity: .5;
            filter: alpha(opacity=50);/*IE*/
            *zoom: 1;
        }
        /*scheme-one*/
        .scheme-one .inner {
            background: url(alpha-bg/alpha-bg-50.png) repeat;
        }
        /*scheme-two*/
        .scheme-two .inner {
            /*IE*/
            background-color: rgb(0, 0, 0);
            filter: alpha(opacity=50);
            *zoom: 1;
            /*NO-IE*/
            background-color: rgba(0, 0, 0, .5);
            background-color: #0009;
        }
        /*scheme-three*/
        .scheme-three .inner {
            /*IE*/
            background-color: rgb(0, 0, 0);
            filter: alpha(opacity=50);
            *zoom: 1;
            /*NO-IE*/
            background-color: rgba(0, 0, 0, .5);
            background-color: #0009;
            _background: url(alpha-bg/alpha-bg-50.png) repeat;
            _filter: alpha(opacity=100);
        }
    </style>
</head>
<body>
    <div class="wrap">
        <div class="header">
            <h1>主流浏览器下背景色半透明的兼容性</h1>
        </div>
        <div class="main">
            <h2>1、使用rgba(0,0,0,0.5)实现</h2>
            <div class="rgba">
                <div class="inner">
                    <p>使用rgba来定义背景色</p>
                    <p>使用rgba来定义背景色</p>
                    <p>使用rgba来定义背景色</p>
                    <p>使用rgba来定义背景色</p>
                    <p>使用rgba来定义背景色</p>
                </div>
            </div>
            <h2>2、使用rgb(0,0,0)和opacity:0.5实现</h2>
            <div class="rgb">
                <div class="inner">
                    <p class="relative">使用rgb来定义背景色,使用了relative</p>
                    <p class="relative">使用rgb来定义背景色,使用了relative</p>
                    <p class="no-relative">使用rgb来定义背景色,没有使用relative</p>
                    <p class="no-relative">使用rgb来定义背景色,没有使用relative</p>
                    <p class="no-relative">使用rgb来定义背景色,没有使用relative</p>
                </div>
            </div>
            <h2>3、方案一:使用图片替代</h2>
            <div class="scheme-one">
                <div class="inner">
                    <p>使用图片</p>
                    <p>使用图片</p>
                    <p>使用图片</p>
                    <p>使用图片</p>
                    <p>使用图片</p>
                </div>
            </div>
            <h2>4、方案二:不使用图片,舍弃IE6</h2>
            <div class="scheme-two">
                <div class="inner">
                    <p class="relative">不使用图片,舍弃IE6</p>
                    <p class="relative">不使用图片,舍弃IE6</p>
                    <p class="relative">不使用图片,舍弃IE6</p>
                    <p class="relative">不使用图片,舍弃IE6</p>
                    <p class="relative">不使用图片,舍弃IE6</p>
                </div>
            </div>
            <h2>5、方案三:洁癖方案</h2>
            <div class="scheme-three">
                <div class="inner">
                    <p class="relative">各浏览器效果均一致</p>
                    <p class="relative">各浏览器效果均一致</p>
                    <p class="relative">各浏览器效果均一致</p>
                    <p class="relative">各浏览器效果均一致</p>
                    <p class="relative">各浏览器效果均一致</p>
                </div>
            </div>
        </div>
        <div class="footer">

        </div>
    </div>
    <!--[if IE 6]>
 <script type="text/javascript" src="alpha-bg/jquery-1.7.1.min.js"></script>
 <script type="text/javascript" src="alpha-bg/ie6_png_patch.js"></script>
 <script type="text/javascript">$('.scheme-one .inner').fixPNG();$('.scheme-three .inner').fixPNG();</script>
 <![endif]-->
</body>
</html>

测试环境:

操作系统版本:
Windows 7 Ultimate build 7600

浏览器版本:
IE6
IE7
IE8
IE9
Firefox 11.0
Chrome 16.0.912.75
Safari 5.1.5(7534.55.3)
Opera 11.62

测试页面:css-background-transparent.html

表格元素定位为relative的各浏览器差异(RM8024)

RM8024: 各浏览器对除 TABLE 之外的表格类元素以及它们相对于 CSS 中 display 特性值的相对定位特性的支持存在差异

一、问题发现

最近的新网站上线,发现了一个bug,这个bug居然只出现FireFox下!截个图上来就清楚了:

期待的正常的效果:

正常效果图

FireFox下的效果:

FireFox下效果图

很明显,在FireFox下,出游计划的日历飘到导航栏上了。它的文档结构是这样的:

文档结构

红色框就是日历所在的单元格,被一个div.calendar-panel包裹着,存在于一个表格里面。样式表中,td.calender-td使用了“position:relative;”,div.calendar-panel使用了“position:absolute;”这样来布局的。这样的布局在合模型里面是再正常不过了,难怪在其他浏览器中显示均正常。可是这里的“position:relative;”是作用于td,一个表格类型元素,合模型的效果在这里似乎就不是这么回事了。

很自然地,直观上就能嗅出问题所在:日历没有相对单元格定位,而是相对父级section.container定位,因为它定义了“position:relative;”。

那么为什么td的相对定位失效呢?为什么只有在FireFox下才失效呢?

二、问题解决

只能说FireFox真的是太标准的浏览器了,我在网上找了找资料,发现一篇文章讲到了这个问题,写的不错!文章地址:http://www.w3help.org/zh-cn/causes/RM8024

总结起来就是,表格类型元素的display值在不同浏览器显示效果有差异。

下面我将这篇文章转载+修改过来,因为原文的测试时间是2010年10月15日,原文的浏览器测试版本相对较旧,笔者使用当前较新版本的浏览器重新测试了一遍,将测试结果写在下文中。


RM8024: 各浏览器对除 TABLE 之外的表格类元素以及它们相对于 CSS 中 display 特性值的相对定位特性的支持存在差异

标准参考

根据 CSS2.1 规范中的描述,被设定了 ‘position’ 特性值为 ‘relative’ 的框的位置会根据其在普通流 (normal flow) 的位置进行计算。然后此框会相对于 (relative) 它在普通流中的位置进行偏移。如果一个框 B 是相对定位的,则其随后的框的定位计算并不考虑 B 的偏移。
‘position:relative’ 作用在 table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption 这些类型元素上的效果并未定义。

CSS 中的表格模型基于 HTML4 的表格模型,包括了表格,标题,行,行组,列,列组以及单元格。下列 ‘display’ 特性的值可以将表格语义指派给一个任意的元素:

‘display’ 特性的值

对应 HTML 中的元素

table-row TR
table-row-group TBODY
table-header-group THEAD
table-footer-group TFOOT
table-column COL
table-column-group COLGROUP
table-cell TD, TH
table-caption CAPTION
关于 'position' 特性 及 相对定位 的更多资料,请参考 CSS2.1 规范 [9.3.1 Choosing a positioning scheme: 'position' property](http://www.w3.org/TR/CSS21/visuren.html#choose-position) 及 [9.4.3 Relative positioning](http://www.w3.org/TR/CSS21/visuren.html#relative-positioning) 中的内容。

关于 CSS 表格模型 特性的更多信息,请参考 CSS2.1 规范 17.2 The CSS table model 中的内容。

问题描述

在 IE6 IE7 IE8(Q) 中,TD/TH 及 TD 元素对设定 ‘position:relative’ 特性及偏移有效,其他均无效;
在 IE8(S) 中,TD/TH 及 CAPTION 元素及它们相对于 CSS 中 display 特性值对设定 ‘position:relative’ 特性及偏移有效,其他均无效;
在 Firefox 中,除 TABLE 之外的所有表格类元素以及它们相对于 CSS 中 display 特性值对设定 ‘position:relative’ 特性及偏移均无效
在 Chrome Safari 中,CAPTION 元素及它相对于 CSS 中 display 特性值 ‘caption’ 对设定 ‘position:relative’ 特性及偏移有效,其他均无效;
在 Opera 中,COL、COLGROUP 元素以及它们相对于 CSS 中 display 特性值对设定 ‘position:relative’ 特性及偏移无效,其他均有效。

造成的影响

此问题可能导致设定了相对定位的符合问题描述的元素的位置在不同浏览器中产生差异,从而影响布局甚至功能实现。

受影响的浏览器

所有浏览器

问题分析

CSS2.1 规范中直接说明了 ‘position:relative’ 作用在 table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption 这些类型元素上的效果并未定义。
下面就对 HTML 中除 TABLE 之外的表格类元素 (包括 TD/TH、TR、THEAD、TBODY、TFOOT、COL、COLGROUP、CAPTION) 以及它们相对于 CSS 中 ‘display’ 特性值 (包括 ‘table-cell’、’table-row’、’table-header-group’、’table-row-group’、’table-footer-group’、’table-column’、’table-column-group’、’table-caption’) 对 ‘position:relative’ 的效果进行分析。

1. 为 TD 元素设定 ‘position:relative’

分析以下代码:cell_relative.html

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; font:20px/1.5 'Trebuchet MS'; }
  table { border:5px solid black; background:khaki; }
  td { border:2px solid navy; background:mistyrose; }
</style>
</head>
<body>
<table cellpadding="2" cellspacing="5">
  <tr>
    <td>static</td>
    <td>static</td>
    <td>static</td>
  </tr>
  <tr>
    <td>static</td>
    <td style="position:relative; left:30px; top:30px; background:lightskyblue;">relative</td>
    <td>static</td>
  </tr>
  <tr>
    <td>static</td>
    <td>static</td>
    <td>static</td>
  </tr>
</table>
</body>
</html>

 

上面代码为中间的 TD 元素设置了 position:relative 以及其偏移。

在各浏览器中效果如下:

IE6 IE7 IE8 IE9 Opera Chrome Safari

Firefox

![](/uploads/2012/04/cell1.gif) ![](/uploads/2012/04/cell2.gif)
可见,IE6 IE7 IE8 IE9 Opera Chrome Safari 中为 TD 元素设定 position:relative 有效,只有FireFox无效。
2. 为 TR 元素设定 ‘position:relative’

分析以下代码:row_relative.html

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; font:20px/1.5 'Trebuchet MS'; }
  table { border:5px solid black; background:khaki; }
  td { border:2px solid navy; background:mistyrose; }
</style>
</head>
<body>
<table cellpadding="2" cellspacing="5">
  <tr>
    <td>static</td>
    <td>static</td>
  </tr>
  <tr style="position:relative left:30px; top:30px;">
    <td style="background:lightskyblue;">relative</td>
    <td style="background:lightskyblue;">relative</td>
  </tr>
  <tr>
    <td>static</td>
    <td>static</td>
  </tr>
</table>
</body>
</html>

 

上面代码为中间的 TR 元素设置了 position:relative 以及其偏移。

在各浏览器中效果如下:

IE6 IE7 IE8(Q) Opera

IE8(S) IE9 Firefox Chrome Safari

![](/uploads/2012/04/row1.gif) ![](/uploads/2012/04/row2.gif)
可见,IE6 IE7 IE8(Q) Opera 中为 TR 元素设定 position:relative 有效,IE8(S) IE9 Firefox Chrome Safari均无效。
3. 为其他表格类元素 COL、COLGROUP、THEAD、TBODY、TFOOT、CAPTION 设定 ‘position:relative’

分析以下代码:other_relative.html

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; font:20px/1.5 'Trebuchet MS'; }
  table { border:5px solid black; background:khaki; }
  td { border:2px solid navy; background:mistyrose; }
</style>
</head>
<body>
COL
<table cellpadding="2" cellspacing="5">
  <col style="position:relative left:200px;" />
  <tr>
    <td>COL</td>
    <td>COL</td>
  </tr>
</table>
<br />
COLGROUP
<table cellpadding="2" cellspacing="5">
  <colgroup style="position:relative left:200px;">
    <col />
  </colgroup>
  <tr>
    <td>COLGROUP</td>
    <td>COLGROUP</td>
  </tr>
</table>
<br />
THEAD, TBODY, TFOOT
<table cellpadding="2" cellspacing="5">
  <thead style="position:relative left:100px;">
    <tr>
      <td>THEAD</td>
    </tr>
  </thead>
  <tbody style="position:relative left:120px;">
    <tr>
      <td>TBODY</td>
    </tr>
  </tbody>
  <tfoot style="position:relative left:140px;">
    <tr>
      <td>TFOOT</td>
    </tr>
  </tfoot>
</table>
<br />
CAPTION
<table cellpadding="2" cellspacing="5">
  <caption style="position:relative left:100px; background:lightskyblue;">CAPTION</caption>
  <tr>
    <td>table cell</td>
  </tr>
</table>
</body>
</html>

 

上面代码为 COL、COLGROUP、THEAD、TBODY、TFOOT、CAPTION 元素设置了 position:relative 以及其偏移。

在各浏览器中效果如下:

IE6 IE7 IE8(Q) Firefox

IE8(S) IE9 Chrome Safari

Opera

![](/uploads/2012/04/other1.gif) ![](/uploads/2012/04/other2.gif) ![](/uploads/2012/04/other3.gif)
可见,所有浏览器均不支持 COL 与 COLGROUP 元素的 position:relative。 _IE6 IE7 IE8(Q) Firefox_ 对 THEAD、TBODY、TFOOT、CAPTION 元素设定 position:relative 均无效。 _IE8(S) IE9 Chrome Safari_ 对 THEAD、TBODY、TFOOT 元素设定 position:relative 无效,对 CAPTION 元素有效。 _Opera_ 对 THEAD、TBODY、TFOOT、CAPTION 元素设定 position:relative 均有效。

上面测试的均为 HTML 中原生为表格类的元素,下面将分析通过设定 ‘display’ 特性1来模拟表格特性的元素对 ‘position:relative’ 是否有效。

注 1: 由于 IE6 IE7 IE8(Q) 不支持上述 ‘display’ 特性值,故下面将只考虑 IE8(S) 和IE9及其他非 IE 浏览器。

分析以下代码:dis_relative.html

<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; padding:0; font:12px/1 'Trebuchet MS'; }
  h1 { font-weight:bold; border-top:2px solid gray; }
  .table { display:table; border-spacing:5px; border:5px solid black; background:khaki; }
  .tr { display:table-row; }
  .td { display:table-cell; border:2px solid navy; background:mistyrose; padding:2px; }
  .thead { display:table-header-group; }
  .tbody { display:table-row-group; }
  .tfoot { display:table-footer-group; }
  .caption { display:table-caption; }
  .col { display:table-column; }
  .colgroup { display:table-column-group; }
</style>
</head>
<body>
<div class="table">
  <div class="tr">
    <div class="td">table-cell</div>
    <div class="td">table-cell</div>
  </div>
  <div class="tr">
    <div class="td" style="position:relative; left:30px; top:20px; background:lightskyblue;">table-cell</div>
    <div class="td">table-cell</div>
  </div>
  <div class="tr">
    <div class="td">table-cell</div>
    <div class="td">table-cell</div>
  </div>
</div>
<br />
<div class="table">
  <div class="tr">
    <div class="td">table-row</div>
    <div class="td">table-row</div>
  </div>
  <div class="tr" style="position:relative; left:30px; top:20px;">
    <div class="td" style="background:lightskyblue;">table-row</div>
    <div class="td" style="background:lightskyblue;">table-row</div>
  </div>
  <div class="tr">
    <div class="td">table-row</div>
    <div class="td">table-row</div>
  </div>
</div>
<br />
<div class="table">
  <div class="thead" style="position:relative; left:80px; top:20px;">
    <div class="tr">
      <div class="td" style="background:lightskyblue;">table-header-group</div>
    </div>
  </div>
</div>
<br />
<div class="table">
  <div class="tbody" style="position:relative; left:80px; top:20px;">
    <div class="tr">
      <div class="td" style="background:lightskyblue;">table-row-group</div>
    </div>
  </div>
</div>
<br />
<div class="table">
  <div class="tfoot" style="position:relative; left:80px; top:20px;">
    <div class="tr">
      <div class="td" style="background:lightskyblue;">table-footer-group</div>
    </div>
  </div>
</div>
<br />
<div class="table">
  <div class="caption" style="position:relative; left:80px; top:20px; background:lightskyblue;">table-caption</div>
  <div class="tr">
    <div class="td">table-caption</div>
  </div>
</div>
<br />
<div class="table">
  <div class="col" style="position:relative; left:200px;"></div>
  <div class="tr">
    <div class="td">table-column</div>
    <div class="td">table-column</div>
  </div>
</div>
<br />
<div class="table">
  <div class="colgroup" style="position:relative; left:200px;">
    <div class="col"></div>
  </div>
  <div class="tr">
    <div class="td">table-column-group</div>
    <div class="td">table-column-group</div>
  </div>
</div>
</body>
</html>

上面代码上面代码中为 ‘display’ 特性值为 ‘table-cell’、’table-row’、’table-header-group’、’table-row-group’、’table-footer-group’、’table-column’、’table-column-group’、’table-caption’ 的 DIV 元素设置了 position:relative 以及其偏移。

在各浏览器中效果如下:

IE8(S) IE9 Chrome Safari

Firefox

Opera

![](/uploads/2012/04/dis1.gif) ![](/uploads/2012/04/dis3.gif) ![](/uploads/2012/04/dis4.gif)
可见,CSS 中 'display' 特性值为 'table-cell'、'table-row'、'table-header-group'、'table-row-group'、'table-footer-group'、'table-column'、'table-column-group'、'table-caption' 的元素设定 'position:relative' 与对应的表格类元素设定 'position:relative' 的情况一致。
5. 小结

下面通过表格总结各浏览器对除 TABLE 之外的表格类元素以及它们相对于 CSS 中 ‘display’ 特性值设置相对定位 (position:relative) 特性的支持差异:

IE6 IE7 IE8(Q)

IE8(S) IE9

Chrome Safari

Firefox

Opera

CAPTION (display:table-caption)

无效

有效

有效

无效

有效

THEAD (display:table-header-group)

无效

无效

无效

无效

有效

TBODY (display:table-row-group)

无效

无效

无效

无效

有效

TR (display:table-row)

有效

无效

无效

无效

有效

TD/TH (display:table-cell)

有效

有效

无效

无效

有效

TFOOT (display:table-footer-group)

无效

无效

无效

无效

有效

COL (display:table-column)

无效

无效

无效

无效

无效

COLGROUP (display:table-column-group)

无效

无效

无效

无效

无效

解决方案

由于除 TABLE 之外的表格类元素以及它们相对于 CSS 中 display 特性值设定了相对定位后的效果 CSS2.1 规范中没有明确定义,而各浏览器的实现又存在很大差异。所以应避免为这些元素设定 ‘position:relative’。
若需要实现如冻结表格行或列的效果,可以考虑使用绝对定位其他 TABLE 元素的方式模拟。

测试环境

操作系统版本:
Windows 7 Ultimate build 7600

浏览器版本:
IE6
IE7
IE8
IE9
Firefox 11.0
Chrome 16.0.912.75
Safari 5.1.5(7534.55.3)
Opera 11.62

测试页面:
cell_relative.html
row_relative.html
other_relative.html
dis_relative.html

本文更新时间:
2012-04-02

IE6下a标签的position为relative时

昨天在抒写一个专题的页面时,在ie6下碰到了一个奇怪的问题,不过解决了现在分享一下。

专题页面地址:http://travel.ly333.com/topic/show/38

完成作品

可以看到这个页面的结构很简单,四栏的瀑布式布局。中间用了一个<ul>包裹着四个<li>,每个<li>里面由一个<a>包裹,<a>标签里面分<img>和<div>。

html结构

1、首先<a>、<span.btn>标签以块状显示,<span.btn>相对于<a>定位。

a标签样式

span.btn样式

2、4个<li>均向左浮动,<ul>使用clearfix类来清除浮动。

li样式

3、在高级浏览器中这样的显示是再正常不过了,但是在ie6下面就出现了意外。<span.btn>按钮被“挤”到下面去了,而且还被图片覆盖着。

没有激发hasLayout

4、ie7下却没有这样的问题,我的第一个反应是不是hasLayout没有激发?<a>标签的块状显示没有作用到?于是在<a>中加上了“zoom: 1;”一刷新,问题解决!

激发hasLayout

5、果然是hasLayout在作怪,不过新的问题又出现了~~~整一块<ul>“跑”到<h2>上面了,只有当鼠标移过的时候才能正确的回到位置。

层叠

6、<ul>和<h2>是兄弟,他们的父亲都是<div.content>。<ul>盖住<h2>的位置刚好是<div.content>的顶部边缘,说明<ul>浮动起来了,像文本流一样没有解析到<h2>是块级元素,整个浮动最顶端。那位什么鼠标移过的时候就能回归到原位呢?难道又是hasLayout的缘故?我尝试着在<div.content>上加上“zoom: 1;”,刷新页面,还是原样。。。

7、在最初的时候<span.btn>不是靠定位来布局的,而是使浮动到右边,那时候<a>标签还没有“position: relative;”样式,在ie6下页面都能显示正常,只是<span.btn>占据了一行,所以将它改成定位方法来实现。那么,会不会是因为<a>标签有了“position: relative;”样式导致的呢?我尝试对它的父亲<div.content>再添加一个“position: relative;”样式,刷新页面,问题解决!O(∩_∩)O哈哈~

添加了position:relative;属性

去除层叠

8、回想一下,这样做的话其实就是使<div.content>有了布局的概念。从这里可以看出<div>在ie6引擎下的布局属性会受到子标签的影响,出现流动的现象时首先应该反应过来是布局属性的问题,问题便很快解决。针对hasLayout引起的问题和激发方法也在这里顺带做一下总结。

  • ie6下浮动产生的双边距问题:对浮动的元素用“display: inline;”来解决。

  • ie6下的3像素偏移和躲猫猫问题:对偏移的元素用“_height: 1%;”来解决。
    激发hasLayout方法:

  • zoom: 1; (除normal外的任意值)

  • height: 1%; (除auto外的任意值)

  • display: inline-block;

  • width: 1%; (除auto外的任意值)

  • float: left; (float: right;)

  • position: absolute; (position: relative;)

Mailto参数和乱码

一、参数介绍

相信这个发邮件的链接都不陌生了,但是它的参数有时候却不是很清楚,我在网上找了些资料,整理了它的参数,下面介绍一下。

1、主送(to):mailto:mumu@example.com,其中mumu@example.com就是收件人地址。

2、抄送(cc):mailto:mumu@example.com?cc=javier@example.com,其中mumu@example.com是收件人地址,javier@example.com是抄送人地址。

3、密送(bcc):mailto:mumu@example.com?cc=javier@example.com&bcc=javiermu@example.com,bcc=后面的就是指密送人地址啦。

4、多个人收件人:mailto:mumu@example.com;javier@example.com;javiermu@example.com,即每个收件人之间用”;”隔开。

5、邮件主题(subject):mailto:mumu@example.com?subject=这是一封测试邮件的主题。这样单击后在邮件客户端就能将这个主题填充进去。

6、邮件正文(body):mailto:mumu@example.com?subject=这是一封测试邮件的主题&body=这是一个测试邮件的正文。

总结一下:mailto后为收件人地址,多人收件用逗号隔开,cc后为抄送地址,bcc后为密件抄送地址,subject后为邮件的主题,body后为邮件的正文内容,如果mailto后面同时有多个参数的话,第一个参数必须以”?”开头,后面的每一个都以”&”开头。

将上面的知识链接起来的一个实例:
mailto:mumu@example.com,javier@example.com?cc=javiermu@example.com&bcc=javiermumu@example.com&subject=这是一份测试邮件的主题。&body=这是一封测试邮件的正文。

二、邮件乱码

当你的subject和body后面的内容是含有中文的时候,你点击了mailto链接,会发现客户端有乱码出现。这是由于没有进行url的编码导致的,如果你的网页时utf-8的,还需要将文字的编码先转换成gbk再编码即可。

在PHP的环境中,我们可以用PHP函数iconv()将UTF-8编码转化为GBK编码,再调用urlencode()函数。例如:

echo urlencode(iconv('utf-8', 'gbk', '这是一封测试邮件的主题。'))

在Java的环境中,可以这样做:

<%=java.net.URLEncoder.encode("这是一封测试邮件的主题。", "GBK")%>

在.net的环境中,可以这样做:

HttpUtility.UrlEncode(这是一封测试邮件的主题。", Encoding.UTF8);//这是以utf-8字符编码 HttpUtility.UrlEncode(这是一封测试邮件的主题。", Encoding.Default);//这是以本地默认字符编码

三、其他解决方案

考虑到大部分客户并不是都习惯安装邮件客户端,只是偶尔需要邮件分享一下的时候,他们并不会去安装客户端,所以有了另一种解决方法,可以使用QQ邮箱推出的邮我功能。

登陆QQ邮箱,在“设置”中点击“账户”选项卡,然后拉到最底就可以看到了。

image

Javier生成的邮我:

Wordpress常用函数介绍

强大的wordpress,给我们带来无尽的方便的同时也给我们带来了无尽的折腾,这些就是Wordpress中所涉及到的常用函数,喜欢折腾的你必须要给力的收藏,因为你随时都可能会用上,以作备份!

在讲述下面的WordPress函数之前,我们需要明确这样一点,所有的WordPress函数都是已经定义好的PHP函数,它们都需要写在PHP 语句中(<?php ?>)才能执行;而且,所有这些函数在PHP语句中都应以分号”;”结尾。其实,为了用好这些函数,为你的WordPress服务,你最好具有 PHP语言的基础。

目录:

正文:

1.bloginfo()

顾名思义,该函数主要用来显示博客信息;而且根据参数的不同,可以用来显示博客信息中的不同部分。常用的有以下几种:

bloginfo(‘name’) 显示博客题名,如“JaverMu”;默认(不写参数)输出该项;

bloginfo(’description’) 显示博客描述部分,如“关注前端,关注互联网。”;

bloginfo(’url’) 输出博客URL地址,如http://www.javiermu.com

bloginfo(’rss2_url’) 显示博客的RSS2.0 feed地址,如http://www.javiermu.com/feed/

bloginfo(’template_url’) 用来获取WordPress博客的模板地址;

bloginfo(’charset’) 显示博客的编码方式,如“UTF-8”;

一种常见的使用bloginfo()函数的组合如下:

<a href="<?php bloginfo('url'); ?>" title="<?php bloginfo('description'); ?>"><?php bloginfo('name'); ?></a> 

在博客中就会输出:<a href=”http://www.javiermu.com/”title=”Jaiver’s Blog”>Javier’s Blog</a>

需要注意的是bloginfo()函数只能输出显示这些参量,如果你想在PHP语句中使用得到的这些值,则需使用get_bloginfo()函数,该函数和bloginfo()使用相同的参数,获得相同的结果。

目录

2.wp_title()

该函数用来显示页面的标题,如在文章页面,则显示文章标题;在分类页面,则显示分类名称;等等。

wp_title()函数可以跟三个参数,即wp_title(’separator’,echo,seplocation),其中 separator是title和其余部分之间的分割符号,默认是>>;echo是个bool变量,取true显示标题,取false则将标 题作为一个PHP参量返回;seplocation定义分隔符的位置,取right定义分隔符在标题后面,取其他任何值,都表示将分隔符放在标题前面。

比如形如主题文件夹下header.php中的一段代码:

<title>
<?php wp_title(' | ', true, 'right'); ?>
<?php bloginfo('name'); ?><?php bloginfo('description'); ?>
</title>

这样做的效果不仅位置明确,而且有利于搜索引擎优化。

目录

3.wp_get_archives()

该函数用来获取博客的文章存档,通过设置函数的参数,可以按各种方式获取,如按月,按年等等。

wp_get_archives()函数后面同样可以跟多种参数,只不过所有参数都需要使用&连接,并放在单引号(‘)中以字符串方式传递 给函数,形如wp_get_archives(’type=monthly&format=html& show_post_count=1&limit=10′)。

如上的参数意义描述如下:

type=monthly表示按月显示文章存档,可以使用yearly、daily、weekly等代替monthly表示按年、日、以及周显示文章存档;

format=html表示使用通常的HTML中<li>格式化文章列表;

show_post_count=1表示在文章存档后面显示属于该类别(年、月等)的文章数量,该参量是个bool值;

limit=10表示显示的文章存档的最大数量为10,超过次数,则超出部分不显示;

尽管参数稍多,显得略为复杂,但其实只需注意type、show_post_count以及limit等三个参量即可。

目录

4.wp_list_categories()

和wp_get_archives()函数类似,wp_list_categories()函数用来获取博客文章的分类信息,并可以通过设置适当的函数参数,将其显示出来。该函数的参数和wp_get_archives()函数类似,都需要使用&连接,放在单引号 (‘)中以字符串方式传递。形如wp_get_archives(‘orderby=name&order=ASC&show_count=1&use_desc_for_title=1&feed=订阅&exclude=2,5& number=10’)。

如上示例中,函数各参数的意义如下:

orderby=name表示按照分类名称的字母先后顺序显示分类信息,可以将name换为ID等;

order=ASC表示按照分类名称的字母的升序显示分类信息,将ASC改为DESC表示按降序;

show_count=1在每个分类名称后面显示属于该分类的文章数;

use_desc_for_title=1使用该分类的描述信息为每个分类名称超链接添加一个title属性;

feed=订阅:在每个分类信息旁边添加一个名为“订阅”的超链接,提供该分类的RSS订阅;

exlude=2,5:在显示的分类中去除ID为2和5的分类;也可以用include=2,5表示只显示ID为2和5的分类;

number=10:表示只显示最先的10个分类。

目录

5.get_the_category()

get_the_category()函数用来返回当前文章所属的类别的若干属性所组成的一个数组,该数组包括以下内容:

cat_ID:当前类别的ID(也可以写作’term_id’);

cat_name:当前类别的名称(也被写作’name’);

category_description:当前分类的描述(也可以写作’description’);

category_count:属于当前分类的文章数量(也被写作’count’)。

具体的使用方法,我们通过下面的几个句子来说明:

形如get_the_category()->cat_ID的语句,返回当前文章所属分类的ID号;

形如get_the_category()->description的语句,返回当前文章所属分类的描述;等等。

目录

6.the_category()

该函数返回当前文章所属的类别名称,而且是文章类别的超链接形式。

默认的无参数形式the_category()直接以超链接形式显示类别名称,显示为:精品推介;

可以在函数中跟上分隔符等参数来格式化输出,如the_category(’-’),若当前文章属于两个以上分类,可以显示这样的形式:精品推介-经验知识;如只属于一个分类,则显示为这样的形式:精品推介。

目录

7.category_description()

该函数以分类的ID为输入,得到该分类的描述。常和echo、get_the_category()配合使用,将当前分类描述输出:

echo category_description(get_the_category()->cat_ID); 

如上语句,get_the_category()得到保存有当前分类信息的一个数组;cat_ID为该数组中该分类的ID;将该ID输入给category_description()函数,即可得到该分类的描述;然后使用echo将其输出。

这个函数也有默认值的,所以可以直接这样抒写:

echo category_description(); 

也能得到上面的结果。

目录

8.is_home()

is_home()用以判断当前显示的博客页面是否是博客首页,返回的是一个Bool值。如果是在首页,则返回TRUE;否则返回FALSE。

该函数常用来控制博客侧边栏的显示方式,经常使用如下代码段:

<?php
if (is_home()) {
//此为在博客首页应该显示的内容
} else {
//此为非博客首页应该显示的内容
}
?>

目录

9.is_archive()

is_archive()用以判断当前显示的内容是否是博客存档页面,比如按日期的存档,或者按分类的存档,等等;其和is_home()函数一样,返回一个Bool值。

目录

10.is_page()

is_page()函数判断当前显示的内容是否是博客的独立页面(page),如“归档”、“关于Javier”等页面;它也返回一个Bool值。

我们可以在模板中通过该函数判断当前是否是一个独立页面,从而决定是否为当前显示的文章显示发布时间等等。

目录

11.is_paged()

该函数用以判断当前文章是否因为内容过多而分页显示;需要注意的是,如果你在写文章时手动添加了<!–nextpage–>标签,来强制分页的话,该函数并不会因此而返回TRUE。

目录

12.is_page_template()

is_page_template()函数需要跟一个参数,通常以如下方式使用:

is_page_template('guestbook.php'); 

以此判断当前显示的独立页面(page)是否使用了参数所示的模板guestbook.php;如果不跟参数,函数返回当前独立页面是否使用了模板。

目录

13.is_single()

is_single()用以判断当前显示的页面内容是否是一篇单独的文章。其后面可以跟三种参数,一种是文章ID;一种是 文章题目(title);一种是文章名称(slug,文章题目的一种简短说明形式);或者可以将三种参数组合使用,以此来判断当前页面内容是否是具体的某篇文章。

一个简单的例子如下,我们可以通过如下几种方式判断当前显示的内容是否是本文:

is_single('279');
is_single('Wordpress常用函数介绍');
is_single('wordpress-functions');
is_single('279', 'Wordpress常用函数介绍', 'wordpress-functions');

该函数后跟三个参数时,有优先级,如果第一个参数符合条件,则返回TRUE;否则,则返回FALSE;貌似后面的参数并没有什么意义。

目录

14.is_category()

该函数用以判断当前显示的页面内容是否是一个分类页面,如网站相关;其中无需参数。函数返回一个Bool值。

目录

15.is_tag()

is_tag()用以判断当前显示的页面是否是一个标签页面,比如WordPress;其后也不需要跟参数。该函数同样返回一个Bool值。

目录

16.is_date()

此函数用以判断当前显示的内容是否为按时间归档的页面,比如2012年一月,或者2012年1月1日,等等。

目录

17.is_day()、is_month()、is_year()

这些函数用以判断当前显示的内容是否为按天、按月、按年份归档的页面。它们和is_date()类似,只不过将归档时间更具体化而已。

目录

18.is_author()

该函数用以判断当前显示的内容是否为以作者名归档的页面。

目录

19.is_admin()

is_admin()函数用以判断当前是否在控制面板页面,或者管理员面板页面。

目录

20.get_bloginfo()

该函数和前面介绍的**1.bloginfo()**函数实现近乎相同的功能。主要用来显示博客的信息;而且根据后跟参数的不同,会输出博客的不同信息。

其后不跟参数时,get_bloginfo()可以显示博客名称,形如“Javier’s Blog”;

后跟其他参数时,可以显示对应的信息,比如get_bloginfo ( ‘description’ )用以显示博客描述信息;

其他还可以使用的参数包括name、url、wpurl以及admin_email等等。但因为其与bloginfo()函数实现相同的结果,所以,在bloginfo能够实现的情况下,不推荐使用get_bloginfo()函数。

目录

21.query_posts()

query_posts()函数结合适当的参数用来控制哪些文章会在页面上显示。

形如query_posts(”cat=3,6&cat=-5,-10″)表示取分类ID为3和6的文章显示,不取分类ID为5和10的文章显示;

形如query_posts(”order=ASC&showposts=10&offset=1&orderby=date&posts_per_page=5″)意义如下:

order=ASC表示按照升序排列,取为DESC则表示按降序;

showposts=10则表示获取10篇文章;

offset=1表示取最新的文章;

orderby=date表示将文章按照日期排序;

posts_per_page=5表示每页显示5篇文章。

需要注意的是该函数只是将文章内容从MySQL数据库中查询出来,要将其显示,还需要与其他语句配合,比如一个经常在侧边栏中使用的形式如下:

<li>
<h2>最近文章</h2>
<?php query_posts('showposts=5&offset=1'); ?>
<ul>
<?php while (have_posts()) : the_post(); ?>
<li><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></li>
<?php endwhile;?>
</ul>
</li>

如上的这段代码用以在侧边栏的指定位置上显示最新的5篇文章。

query_posts()函数后面可以跟众多种类的参数,功能十分强大,在此,我们不进行过多介绍。

目录

22.get_posts()

该函数和query_posts()函数功能大体相同,都是用来从数据库中查询并得到符合某条件的文章。不过get_posts()函数的使用有一个固定的形式,如下:

<?php
$lastposts = get_posts('numberposts=5');
foreach($lastposts as $post) : setup_postdata($post);
?>
<h2><a href="<?php the_permalink(); ?>" id="post-<?php the_ID(); ?>"><?php the_title(); ?></h2>
<?php the_content(); ?>
<?php endforeach; ?>

即首先使用get_posts()函数查询得到文章数据,然后使用形如foreach($lastposts as $post) : setup_postdata($post);的循环将查询得到的文章内容显示出来。

get_posts()函数使用和query_posts()函数相同的参数,在此也不再作详细介绍。

目录

23.wp_list_cats()

该函数和前文中的**4.wp_list_categories()**函数实现相同的功能,不过在最新的WordPress版本中,此函数已经被弃用,其功能为wp_list_categories()函数完全取代。

目录

24.get_calendar()

get_calendar()函数用以在WordPress上显示日历,日历样式和使用widget显示的效果相同,如下图所示:

其后可以跟一个BOOL参数,用以控制日历上方星期的显示样式。

目录 

25.wp_list_bookmarks()

该函数用来显示博客的友情链接,并可以使用各种参数来控制显示的数量、种类以及样式等等。

形如wp_list_bookmarks(’title_li=&categorize=0&orderby=rand&include=41,40,37,54′);的形式,意义解释如下:

title_li=&categorize=0是一种通常使用的组合,意为不显示WordPress后台控制面板中设置的友情链接标题,但所有友链都按照设置的分类显示出来;单独的一个title_li=还可以用来设置被显示友链的类别名称;

orderby=rand设置友链的显示方式为随机顺序,当然,还可以设置为其他的方式,比如id、url、name等等;

include=41,40,37,54表示只显示ID为这四个数字的四个友链;与此对应,还支持使用exclude,表示不显示ID为多少的友链。

此外,该函数还经常用到的参数有before和after,用来设置每个链接前后的文字,默认的是<li>和</li>标记。

目录

这两个函数实现和**25.wp_list_bookmarks()相同的功能,不过此二函数已在WordPress升级的过程中为25.wp_list_bookmarks()**所取代。

目录

27.wp_list_pages()

该函数以页面名称的超链接形式显示WordPress博客内的所有页面,经常用来建立顶端导航页面,或用来修饰侧边栏。

形如wp_list_pages(’title_li=&sort_column=menu_order&include=12,25,38,57&depth=1&’);的函数调用,各参数意义如下:

title_li=用来设置所有显示页面的一个总名称;后面没有参数值时,表示不显示名称;

sort_column=menu_order用来设置页面的显示顺序,表示按照WP后台设置的各页面顺序显示,其他的常用顺序设置可能还包括post_title、post_date、ID等等;

include=12,25,38,57表示只显示ID为这四个数值的四个页面;同样,可以使用exclude来排除相应ID的页面;

depth=1表示只显示父页面,对所有子页面不予显示;其他数值还包括默认的0,表示显示所有页面(子页面有缩进);-1显示所有页面(子页面无缩进);等等。

此外,该函数可能会用到的属性还包括link_before和link_after,用于设置显示的页面链接前后的字符。

目录

28.wp_tag_cloud()

顾名思义,wp_tag_cloud()函数用来显示WordPress博客的标签云。

一种形如wp_tag_cloud(’smallest=8&largest=22&number=30&orderby=count’);的函数调用,各参数的意义如下:

smallest=8用来设置标签云中显示出来的所有标签中,计数最少(最少文章使用)的标签的字体大小为8;

largest=22用来设置标签云的所有标签中,计数最多(最多文章使用)的标签的字体大小为22;

number=30设置标签云中显示的最多标签数量为30;

orderby=count设置标签云中标签的排序方式为计数(默认),而不是名称(相应参数为name,widget调用时的默认值)。

其他常用的参数还包括include和exclude,用来设置在标签云中是否包含或去除ID为某数字的标签。

目录

29.wp_register()

wp_register()函数用以向管理员显示“站点管理”超链接;或者当WP博客开放了注册时,向未登陆的用户显示“注册”超链接。

该函数不需要什么参数,唯一可能用到的参数形式如wp_register(’前’,’后’),可以在如上显示的超链接文字的前后分别显示一个“前”字和一个“后”字。当然,你可以据此发挥想象力来个性化自己网站的管理或注册链接。

目录

30.wp_loginout()

该函数用来在指定位置显示一个“登录”链接;当然,如果你已经登录过了,则会相应地显示一个“退出”链接。此函数后面不使用任何参数,所以无法进行灵活的自定义。

不过如果你想自定义自己的WP博客的登录或退出链接文字的话,还是可以使用下面31中介绍的函数wp_logout_url()和wp_login_url()。

目录

31.wp_logout_url()、wp_login_url()

使用如上**30.wp_loginout()**中的函数尽管可以方便地为WP博客设置登录、退出链接,但自定义不够灵活。所以,从WordPress 2.7版本开始,提供了这里的两个函数。它们分别用来获取WP博客退出或登录超链接,然后,我们使用获得的超链接即可编写如下代码,来对WP博客的登录和 退出链接进行灵活设置:

<a href="<?php echo wp_logout_url(); ?>">点击这里退出 

<a href="<?php echo wp_login_url(); ?>">点击这里登录

当然,要想实现完美的效果,还需要对访客的登录状态进行判断,使用一个if语句,根据登录状态显示相应的菜单项。

目录

32.wp_meta()

该函数通常会紧跟如上**29.wp_register()30.wp_loginout()**中的函数后面,其具体在直观显示上没有什么异样,貌似是WP主题为WP插件留下的API Hook,建议朋友们在如上函数后面跟上这一函数。

目录

33.get_recent_posts()

该函数只有当你安装了中文WordPress工具箱之后,才能使用。其作用是用来获取最新日志,函数原型如下:

get_recent_posts($no_posts = 5, $before ='<li>+', $after ='</li>', $show_pass_post = false, $skip_posts = 0); 

可以使用$no_posts控制显示文章数量,$before和$after的意义和前面函数中相同;至于后两个参数,一般不必设置,直接取默认值即可。

不过因为该函数与WordPress内置的get_posts()和query_posts()函数功能重复,所以通常情况下很少使用。

目录

34.get_recent_comments()

其实安装了如上的中文WordPress工具箱之后,最常使用的是这个函数,因为WordPress程序本身没有内置获取最新评论的函数。该函数原型如下:

get_recent_comments($no_comments = 5, $before = '<li> ', $after = '</li>', $show_pass_post = false); 

意义显然,和上面函数类似,此处不再赘言。

目录

35.get_recentcomments()

该函数是在安装了WP-RecentComments插件之后才具有的功能,与如上**34.get_recent_comments()**中的函数类似。

该函数原型如下:

get_recentcomments(int num, int size); 

num表示返回的最新评论数量;size表示返回的评论内容的长度。

目录

36.wp_get_post_tags()

该函数用来在某个文章页面或者根据某篇文章的ID来获取该文章的tag,获取的结果被放置到一个tag数组中。一个常见的使用方式如下:

if (is_single()){
$keywords ="";
$tags = wp_get_post_tags($post->ID);
foreach ($tags as $tag ) {
$keywords = $keywords . $tag->name . ",";
}
echo $keywords;
}

首先判断是否是单文章页面,如果是,则据当前文章的ID($post->ID)来获取当前文章的tag,然后取得其name($tag->name),并将其组合输出。

目录

37.single_cat_title()、single_tag_title()

这两个函数用来获取分类页面和tag页面的title,其通常的使用方式如:

<?php
$str = single_cat_title();
echo $str;
?>

<?php
$str = single_tag_title();
echo $str;
?>

然而,除此之外,single_cat_title()还可以用来在tag页面上获取当前页面的title;但single_tag_title()却不可用于获取分类页面的title。

目录

38.get_settings()、get_option()

此二函数与前文中的函数**20.get_bloginfo()**类似,使用方法也相同,可以通过后跟各种参数来获取WordPress博客的相关信息。

比如如下的调用方式:

get_settings('name');

get_option('name'); 

可以用来获取当前WordPress博客的标题。

目录

39.wp_head()

该函数与前文中的函数**32.wp_meta()**相同,是WP主题为WP插件留下的API Hook。

目录

这几个函数是用来在WordPress主题中获取并包含相应的文件的。比如:

get_header()用来包含当前主题文件夹下的header.php;

get_footer()用来包含主题文件夹下的footer.php;

get_sidebar()用来包含主题文件夹下的sidebar.php;

comments_template()用来包含comments.php。

需要注意的一点是,如果当前主题文件夹下缺少对应的文件,则函数会使用wp-content/themes/default/文件夹下的对应文件代替。

此外,以上函数后面都不能跟参数,只有get_sidebar()例外,因为一个主题中可以使用多个sidebar。形如get_sidebar(’up’)的调用方法可将sidebar-up.php侧边栏模板文件包含到主题中。

除了以上几个函数之外,在主题中如果想包含一个具体的文件,还可以使用如下方式:

include(TEMPLATEPATH . '/*.php') 

如上的函数形式可以将当前主题文件夹下名为*.php的文件包含进来;其中TEMPLATEPATH是当前主题文件夹地址的一个(不含末尾的/,所以需要添加上)。

目录

41.have_posts()、the_post()

这两个函数的使用范围有限,通常在WordPress的循环中使用,用以获取所有文章。其固定使用形式如下:

<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
此处显示文章
<?php endwhile; ?>
<?php else : ?>
此处显示未找到文章时的信息,比如404相关
<?php endif; ?>

另一种常见的形式是将如上代码中的前两行组合起来(其他地方不变):

<?php if (have_posts()) : while (have_posts()) : the_post(); ?> 

该形式通常会在模板的index.php、archive.php或者single.php等页面使用。除此之外的其他地方,我们通常不会看到此二函数的身影。

目录

42.the_title()、the_title_attribute()

the_title()函数主要用来获取当前文章的title,其后可以跟上三个参数(可全部省略,取默认值),调用形式如下:

<?php the_title('before', 'after', display); ?> 

参数before用来设置在获取的title前面显示的字符内容;after用来设置title其后显示的内容;而display是一个Bool值,用于控制获取的title是否显示出来。

the_title_attribute()函数与the_title()类似,其使用方法如下:

the_title_attribute('before=前&after=后&echo=true'); 

其中before=和after=分别用于设置title前面和后面显示的字符;echo=true或者false用户设置获取的title字符串是否显示出来。

形如<?php the_title(’当前文章’, ‘的评论:’, true); ?>或the_title_attribute(’before=当前文章&after=的评论:&echo=true’)的调用形式将会显示如下的结果:

当前文章Wordpress常用函数介绍的评论:

目录

43.single_post_title()、single_tag_title()、single_cat_title()

这一系列函数用于获取当前文章页面、tag页面或分类页面的title字符串。其后可跟两个参数,调用形式如下:

<?php single_post_title('前缀', display); ?> 

可以使用形如<?php single_post_title(’当前文章:’,TRUE); ?>或<?php single_post_title(’当前文章:’); ?>的调用形式来显示如下的结果:

当前文章:Wordpress常用函数介绍

此外,也可以像**42the_title()、the_title_attribute()**中的函数一样,将显示属性设置为false,把获取的title字符串传给一个变量,以供其他语句使用。此时的调用形式如下:

<?php $tt = single_post_title('当前文章:', false); ?> 

目录

44.the_ID()

该函数后面不跟任何参数,使用如下所示的调用方式:

<?php
$id = the_ID();
echo $id;
?>

用于获取并显示当前文章页面的ID号。不过需要特别注意的一点是,该函数只能在WordPress的大循环内使用,在其他地方使用可能也会显示ID号,但显示的内容始终不会随文章而改变。

此外,该函数通常还会在如下所示的CSS结构中使用:

<h2 id="post-<?php the_ID(); ?>">
<?php the_title(); ?>
</h2>

可为博客中不同的作者设置不同的title样式,以示区分。

目录

45.get_the_ID()

该函数与**44.the_ID()函数实现完全相同的功能,目前WordPress官方也没有提供该函数的使用说明。你可以参阅如上44.the_ID()**函数的介绍。特别提醒一点,该函数与the_ID()类似,也只能在WordPress的大循环中才能正确使用。

目录

46.the_time()、get_the_time()

the_time()用来获取并显示当前文章发布的时间,和上面几个函数类似,此函数也是只能在WordPress的大循环中使用。

该函数后面可以跟控制日期或时间格式的参数,常用的参数形式如下:

<?php the_time('F j, Y'); ?>的调用形式显示效果为:六月13, 2009(英文状态下显示June 13, 2009); 

<?php the_time('g:i a'); ?>的调用形式显示效果为:7:09 下午(英文状态下显示7:09 pm);

<?php the_time('G:i'); ?>的调用形式显示效果为:19:09。

事实上,除了使用the_time()函数之外,WordPress还提供了一个具有类似功能的get_the_time()函数。该函数除了不具有the_time()函数的显示功能之外,其余功能二者完全相同。使用get_the_time()函数时,如欲将获取的时间显示出来,需要使用专用语句。

下面,简单了解一下WordPress中时间的格式。在WordPress中,通常用于控制时间格式的有一下字符:l, F, j, S, Y, G, g, i, a等等,其详细意义如下:

l(小写L)用来显示一周之中每一天的名称,比如星期六,或者在英文中显示Saturday;

F用来显示月份名称,比如六月,或者June;

j用来显示一月之中的某一天,比如13;

Y用来以4位数字形式显示年份,使用y则以末两位数字显示年份,比如2009或09;

G, g, i, a等四个字符通常组合使用,如前例子,有两种形式:

g:i a以形如7:09 下午或7:09 pm的形式显示时间;

G:i以形如19:09的24小时进制形式显示时间。

S通常紧跟在j后面,表示是否在一月之中某天之后添加英文后缀(st, nd, th等)。

目录