Javascript 的噩梦可以结束了

Firebug 是针对Firefox 的一个插件,它与Firefox 很好的集成到了一起,帮助你分析与网页在客户端的一切行为,当然,获益最大的大概就是Javascript 的调试了。 下面是一个例子,红色部分代表遇到了一个脚本错误。 点开后,Firebug 指示出了错误文件与相关代码行。  再继续查看,就直接定位到了相关上下文,这里我们可以看到,是在line 22 多了一个额外的注释标记 "*/",导致此错误。 修复后,显示正常状态。 如果错误不太容易找到,还可以设置断点进行调试,直接在行号部分点击即可设置断点,然后刷新一次网页重新执行脚本,执行到断点处会自动停下,可以像通常调试工具一样选择执行进度,观察并设置变量。 Firebug...

Firebug 是针对Firefox 的一个插件,它与Firefox 很好的集成到了一起,帮助你分析与网页在客户端的一切行为,当然,获益最大的大概就是Javascript 的调试了。

下面是一个例子,红色部分代表遇到了一个脚本错误。

firebug status

点开后,Firebug 指示出了错误文件与相关代码行。

firebug interface

 再继续查看,就直接定位到了相关上下文,这里我们可以看到,是在line 22 多了一个额外的注释标记 "*/",导致此错误。

firebug interface

修复后,显示正常状态。

firebug status

如果错误不太容易找到,还可以设置断点进行调试,直接在行号部分点击即可设置断点,然后刷新一次网页重新执行脚本,执行到断点处会自动停下,可以像通常调试工具一样选择执行进度,观察并设置变量。

Firebug 是完全免费的,要了解更多的功能,请参考考官方网站 。 

无法覆盖css 中display: none 的问题

在客户端脚本中,我们经常使用对象的CSS 属性style.display 来控制对象在浏览器中的显示与隐藏,一般的习惯是这样写: document.getElementById("div").style.display = "none"; // Hide this div document.getElementById(”div").style.display = ""; // Show...

在客户端脚本中,我们经常使用对象的CSS 属性style.display 来控制对象在浏览器中的显示与隐藏,一般的习惯是这样写:

  document.getElementById("div").style.display = "none"; // Hide this div
document.getElementById(”div").style.display = ""; // Show the div again
不过我最近遇到一个问题,当已经在CSS文件中为这个对象静态设置了display: "none" 属性,那么上面第二行代码将不起作用,不会按我们的预想将对象显示出来。最后找到了一个解决方法,对于以上情况,以下代码可以实现预期的效果。
 document.getElementById(”div").style.display = "inline"; // Show the div again

display 属性 可以有以下取值,上面的inline 可以换成任何你需要的值。

  • block
  • none
  • inline (this is default)
  • inline-block
  • list-item
  • table-header-group
  • table-footer-group

题外参考:CSS属性Display与Visibility的不同, Ten CSS tricks you may not know

Get rollable entry list in MT - postroll.js

Most of blogers have the recent entry list at the sidebar. Sometime it's difficult to...

Most of blogers have the recent entry list at the sidebar. Sometime it's difficult to balance spacing and convenience. People may want more entries in the list, but they may also want to see other feature area without rolling scrollbar too much. I wrote a Javascript postroll.js that make the entry list rollable as far as you expect.

How does it work? Download postroll.js to your web server path and include it in your web page that you need the feature. Then edit your tempate like below. The template code is a little thick but works.

<h2>最近更新|Recent Entries</h2>
<div id="recententry" class="module-content">
<ul id="recententry1">
<MTEntries lastn="5">
<li><$MTInclude module="Entry Link"$></li>
</MTEntries>
</ul>
<MTEntries offset="5" lastn="1">
<MTIfNonEmpty tag="EntryTitle"><$MTSetVar name="recententry2" value="1"$></MTIfNonEmpty>
</MTEntries>
<MTIf name="recententry2">
<ul id="recententry2">
<MTEntries offset="5" lastn="5">
<li><$MTInclude module="Entry Link"$></li>
</MTEntries>
</ul>
</MTIf>
<MTEntries offset="10" lastn="1">
<MTIfNonEmpty tag="EntryTitle"><$MTSetVar name="recententry3" value="1"$></MTIfNonEmpty>
</MTEntries>
<MTIf name="recententry3">
<ul id="recententry3">
<MTEntries offset="10" lastn="5">
<li><$MTInclude module="Entry Link"$></li>
</MTEntries>
</ul>
</MTIf>
<MTEntries offset="15" lastn="1">
<MTIfNonEmpty tag="EntryTitle"><$MTSetVar name="recententry4" value="1"$></MTIfNonEmpty>
</MTEntries>
<MTIf name="recententry4">
<ul id="recententry4">
<MTEntries offset="15" lastn="5">
<li><$MTInclude module="Entry Link"$></li>
</MTEntries>
</ul>
</MTIf>
<MTEntries offset="20" lastn="1">
<MTIfNonEmpty tag="EntryTitle"><$MTSetVar name="recententry5" value="1"$></MTIfNonEmpty>
</MTEntries>
<MTIf name="recententry5">
<ul id="recententry5">
<MTEntries offset="20" lastn="5">
<li><$MTInclude module="Entry Link"$></li>
</MTEntries>
</ul>
</MTIf>
<label id="recententrybar1"></label><label id="recententrybar2"></label>
<!--end #recententry-->
</div> 
 The emphasis must be followed in your code, otherwise need to configure yours in postroll.js.
// Configuration
Postroll = {
box: ["recententry"],
bar1: ["recententrybar1"],
bar2: ["recententrybar2"],
bar1_txt: "&nbsp;&nbsp;&laquo;&nbsp;&nbsp;&nbsp;&nbsp;",
bar2_txt: "&nbsp;&nbsp;&nbsp;&nbsp;&raquo;&nbsp;&nbsp;",
bar1_lnk_title: "Previous 5 entries",
bar2_lnk_title: "Next 5 entries"
};

Then have this style in the css. I don't use script to initial the style because this method is quicker for the page first loading. There won't be a long entry list at a moment then hided by the script. I use script to initial the text link for rolling entries and control the entry roll after all stuffs were loaded.

#recententry2,
#recententry3,
#recententry4,
#recententry5 {
display: none;
} 

There's more action you need to take if want it works perfect! Create a file name as ie_onload.js, and have below only line. About ie_onload.js here's an explanation.

 try{Postroll.run()}catch(e){} 

This script is able to serve multi-area in one page. That case you should have the configuration like below. It could be 3 groups or more.

 // Configuration
Postroll = {
box: ["recententry", "othertag"],
bar1: ["recententrybar1", "othertagbar1"],
bar2: ["recententrybar2", "othertagbar2"]
bar1_txt: "&nbsp;&nbsp;&laquo;&nbsp;&nbsp;&nbsp;&nbsp;",
bar2_txt: "&nbsp;&nbsp;&nbsp;&nbsp;&raquo;&nbsp;&nbsp;",
bar1_lnk_title: "Previous 5 entries",
bar2_lnk_title: "Next 5 entries"
};

Update 2007-02-14 

I found that there's one post missed on each 5 posts in the postroll list. The point is that I had  wrong offset value in MTEntries tag. I've updated the template code above from offset="6" to offset="5" and also for the value of 11, 16 and 21.

window.onload problem

I use several javascript for some features on blog, such as highlighting keywords , collapse...

I use several javascript for some features on blog, such as highlighting keywords , collapse and expand the entry area and switch the style sheets . There's a problem that the javascript would not apply untill the whole page is loaded completely. If there's big images in the page or the Internet is very slow, the visitor will have the real bad expereices. Is there's a way to have the javascript work after the document is loaded but before the images are loading? I'm really in luck, the guy  make this work on Firefox, IE and  Safari.

So now I have below code for my each .js file that need this feature. (no Safari supported so for)

// Only for Mozila/Firefox Browser
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", Switchcss.run, false);
}
// Only for IE
/*@cc_on @*/
/*@if (@_win32)
document.write("<script defer src=/ie_onload.js><"+"/script>");
/*@end @*/
// For all other Browsers
if (window.onload) {
Switchcss._old_onload = window.onload;
window.onload = function(e) {
Switchcss._old_onload(e);
Switchcss.run();
}
} else {
window.onload = function(e) {
Switchcss.run();
}
} 

ie_onload.js 

try{Switchcss.run()}catch(e){}
try{Keyword.run()}catch(e){}
try{Hidebody.run()}catch(e){} 

使用Javascript 高亮搜索引擎关键词

需求 很大一部分网站,搜索引擎是其最重要的外部访问来源,某些情况,用户宁愿在简洁的搜索页面敲入关键词,也不愿按照一条已知的访问路径来找到资源。如果你的页面很大,定位搜索的关键词会不太容易,并不是每个使用者都知道使用"Ctrl+F",如果能将这些关键词高亮显示,是个很好的主意。 当用户在Google 中使用“db2 学习笔记”作为关键词进行搜索时,如果你的网页列在了结果中,用户点开你的网页,页面中所有出现"db2" 和"学习笔记" 地方,都使用特殊的底色进行了标识。 Hilite 我在Scott Yang 的网站,看到了Search Engine Highlight Javascript ,使用他编写的程序:se_hilite.js 1.1 ,可以很轻松的在网站实现以上功能。 安装很简单,将se_hilite.js 保存在网站目录,并在每一个需要高亮关键词的网页中引用这个js...

需求

很大一部分网站,搜索引擎是其最重要的外部访问来源,某些情况,用户宁愿在简洁的搜索页面敲入关键词,也不愿按照一条已知的访问路径来找到资源。如果你的页面很大,定位搜索的关键词会不太容易,并不是每个使用者都知道使用"Ctrl+F",如果能将这些关键词高亮显示,是个很好的主意。

当用户在Google 中使用“db2 学习笔记”作为关键词进行搜索时,如果你的网页列在了结果中,用户点开你的网页,页面中所有出现"db2" 和"学习笔记" 地方,都使用特殊的底色进行了标识。

Hilite

我在Scott Yang 的网站,看到了Search Engine Highlight Javascript ,使用他编写的程序:se_hilite.js 1.1 ,可以很轻松的在网站实现以上功能。

安装很简单,将se_hilite.js 保存在网站目录,并在每一个需要高亮关键词的网页中引用这个js 文件:

<script type="text/javascript" xsrc="se_hilite.js"></script>

之后在CSS 样式单中加入如下定义:

.hilite { background-color: #ff0; }

如果在se_hilite.js 中设定了:

Hilite.style_name_suffix: true; 

则还需要定义额外的CSS 样式:

.hilite1 { background-color: #ff0; }
.hilite2 { background-color: #f0f; }
.hilite3 { background-color: #0ff; }
.hilite4 ...

原理

如果在A 页面点击链接到达B 页面,则在B 页面可通过document.refferer 读到A 页面的链接。如果A 页面是一个搜索结果页面,则在B 页面读到的refferer 看起来会像下面这个样子:

http://www.google.com/search?q=db2+%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0&hl=en&lr=&newwindow=1

通过解析这个链接,取出每一个关键词,并在B 页面装载完成之后,使用Javascript 对页面进行搜索,对每一个关键词位置加入描述底色的代码。

这个动作实际是在用户的客户端浏览器中完成的,并没有对你的实际网页内容做任何更改。

功能扩展

笔者下载并在网站安装了Hilite,同时做了以下功能扩展:

  1. 增加了对中文关键词的支持。
  2. 增加了对关键词的链接索引,可以通过锚点(anchor)迅速链接到关键词首次出现的地方。
  3. 增加了国内流行的搜索引擎,因为要分析refferer,所以针对每个搜索引擎需提供单独的代码。作者的程序结构非常好,所以很容易扩充。
  4. 增加了搜索站内相关文章的功能,不需要动态程序,只需要利用搜索引擎和Meta 标签,当然这也需要对网站页面进行更多的修改。
  5. 额外增加了一个微不足道的小功能,把用户搜索的关键词再次放到这个页面上,让用户可以快速的发起第二次搜索(可以是在你网站内部)。

中文支持

搜索时浏览器已将URI 进行编码处理,根据页面所采用的字符集不同,编码结果也不同。对于同一个关键词“db2 学习笔记”,Google(UTF-8) 和Baidu(GB2312) 的页面分别会产生不同的编码:

http://www.google.com/search?hl=en&q=db2+%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0
http://www.baidu.com/s?wd=db2+%D1%A7%CF%B0%B1%CA%BC%C7&cl=3

Javascript 中相应提供了用于解码的函数:

decodeURI(encodedURIString)
decodeURIComponent(encodedURIString)

上述decode 函数只能处理UTF-8 编码的URI,如果把GB2312 编码的URI作为参数,会抛出一个错误:

The URI to be decoded is not a valid encoding

我们必须自己实现一个处理GB2312 编码URI 的函数。

Keyword.decodeGBURI = function(strcode) {
    try {
        var result = '';
        for ( var i = 0; i < strcode.length; i ++) {
            var thischr = strcode.substr(i,1);
            if (thischr == '%') { // 则后面为16进制编码
                var ascii = eval('0x' + strcode.substr(i+1,2)); // 取出2位16进制值,转成10进制ascii码
                if ((ascii > 0x20 && ascii < 0x30) ||
                    (ascii > 0x39 && ascii < 0x41) || 
                    (ascii > 0x5a && ascii < 0x61) ||
                    (ascii > 0x7a && ascii < 0x91)) { // !"#$%&'()*+,-./ :;<=>?@ [\]^_;` {|}~
                    try {
                        result = result + String.fromCharCodeAt(ascii); // 还原为单字节字符    
                    } catch (e)    { // ie6不支持,放弃,继续处理
                        i = i + 2;
                        continue;
                    }
                    
                    i = i + 2;
                } else { // 双字节字符
                    ascii = eval('0x' + strcode.substr(i+1,2) + strcode.substr(i+4,2)); // 取出4位16进制值,转成10进制ascii码
                    try    {
                        result = result + chrval(ascii); // 还原为双字节字符,调用vb函数处理gb2312编码
                    } catch (e) { // 不支持vb脚本,放弃这个双字节字符,继续处理下面
                        i = i + 5; 
                        continue;
                    }
                    i = i + 5;
                }
            } else if (thischr == '+')
                    result = result + ' '; // 加号还原为空白
            else // 字母,不需要解码
                    result = result + thischr;
        }
    } catch(e) { return false; };
        
    return result;
};

这个函数由Javascript 编写,但为了完成转换,额外调用了一个自定义的VBscript 函数chrval(vstrin) :

function chrval(vstrin)
    chrval = chr(vstrin)
end function

函数chr() 根据ASCII 码取得对应字符。Javascript 语言使用Unicode 编码,未提供此函数。因此,我们必须将这个函数保存在一个单独的.vbs 文件中,并通过如下语句进行引用,供Javascript 调用。

<script type="vbscript" xsrc="/js/chr.vbs"></script>

关键词链接索引

如果希望打开此功能,需要设定:

Keyword.index: true,

对应实现此功能,增加了函数:

Keyword.indexHTML = function(html, query) {
    var re = new Array();
    var q = '您的查询关键词标明如下,点击可以跳到文中首次出现的位置:';
    for (var i = 0; i < query.length; i ++) {
        if (query[i]) {
            var classname = Keyword.style_name;
            if (Keyword.style_name_suffix)
                classname += (re.length==0?'':re.length);
            re.push([new RegExp('('+query[i]+')', "gi"), classname]);
            q += '<span class="' + classname + '">' + (query[i]).link('#kIdx' + i) + ' </span>';
        }
    }
    var last = 0;
    var tag = '<';
    var skip = false;
    var skipre = new RegExp('^(script|style|textarea)', 'gi');
    var part = null;
    var result = '';
    while (last >= 0) {
        var pos = html.indexOf(tag, last);
        if (pos < 0) {
            part = html.substring(last);
            last = -1;
        } else {
            part = html.substring(last, pos);
            last = pos+1;
        }
        if (tag == '<') {
            if (!skip) {
                for (var j = 0; j < re.length; j ++) {
                    part = part.replace(re[j][0], ''.anchor('kIdx' + j) + '$1');
                }
            } else
                skip = false;
        } else if (part.match(skipre)) {
            skip = true;
        }        result += part + (pos < 0 ? '' : tag);
        tag = tag == '<' ? '>' : '<';
    }
    result = q + '<p>' + result;
    return result;
};

支持更多搜索引擎

不同的搜索引擎会产生不同结构的URI ,需要对其进行分析,确定解码函数(UTF-8 或者GB2312),并提取出关键词。因此,要实现某个搜索引擎关键词的高亮显示,在以下函数中增加相关搜索引擎定义即可:

Keyword.decodeReferrer(referrer) 

搜索相关文章

原理:在每个网页中通过Meta 标签定义关键词,如果用户通过搜索引擎找到了页面A,那么将页面A 中定义的关键词(如果定义了多个,只取前两个)提交到搜索引擎继续搜索。

要使用此功能,需要:

  • 修改参数refill2:
Keyword.refill2: true,
  • 修改参数element2:
Keyword.element2: 'w',
  • 在页面中加入如下代码(以Baidu 为例),参数element2 的值应与搜索引擎用于提交关键词的文本框名称一致。
<!-- Search Baidu -->
<form name="baidu2" method="get" action="http://www.baidu.com/baidu">
  <input name="tn" type="hidden" value="bds" />
  <input name="cl" type="hidden" value="3" />
  <input name="si" type="hidden" value="aiview.com" />
  <input name="ct" type="hidden" value="2097152" />
  <input id="w" name="w" type="hidden" size="34" maxlength="100" class="frame" />
  <a xhref='javascript:document.baidu2.submit()'>站内相关文章&nbsp;&gt;</a>
</form>
<!-- Search Baidu -->

便捷搜索

要使用此功能,需要:

  • 修改参数refill1:
Keyword.refill1: true,
  • 修改参数element1:
Keyword.element1: 'word',
  • 在页面中加入如下代码(以Baidu 为例),参数element1 的值应与搜索引擎用于提交关键词的文本框名称一致。
<!-- Search Baidu -->
<form name="baidu" method="get" action="http://www.baidu.com/baidu">
  <input name="tn" type="hidden" value="bds" />
  <input name="cl" type="hidden" value="3" />
  <input name="si" type="hidden" value="aiview.com" />
  <input name="ct" type="hidden" value="2097152" />
  <input id="word" name="word" size="34" maxlength="100" class="frame" value="wwf" tabindex="1" />
  <input type="submit" value="站内搜索" class="buttonface" tabindex="2" />
</form>
<!-- Search Baidu -->

代码下载

Scott Yang 的原程序只有一个文件se_hilite.js 1.1 (24 October 2004) - latest ,笔者修改的版本包含2个文件:keywords.js 1.2.0 chr.vbs

由于程序修改后,已经不仅是Highlight 的功能,因此更改了程序中对象的名称为Keyword 。

参考资源

更新 2007-02-07

优化了针对不同浏览器的onload 事件处理 ,使highlight 加载得更快。这里下载更新的keyword.js v1.30.

mail.png


标签订阅|Tag Subscription

If you use an RSS reader, you can subscribe to a feed of all future entries tagged 'Javascript'. [What is this?]

Subscribe to feed Subscribe to feed

最近更新|Recent Entries

不定期更新|Handy Entries

其它标签|Other Tags

分类栏目|Categories

按月归档|By Month

2008
11
10
07
05
04
03
02
01
2007
12
10
07
06
05
04
03
02
01
2006
12
11
10
09
08
07
06
05
04
03
02
01
2005
11
10
09
08
07
04
03
2004
12
11
10
09
08
07
06
05
04
03
02
01
2003
12
10
09
08
06
2002
09
08
04
03
02
2001
12
09
07
06
05

站内链接|Site Links

Powered by
Movable Type 3.34