惊闻360综合搜索上线,前去围观了一下,果然牛逼,搜索结果页整个就是一个百度嘛,页面抄的挺像。
要做搜索,肯定是要“做”出来才行,页面抄成这样,连背景图片、CSS都直接拿来用,貌似“做”的不够道德啊。不过,抄风格这事在中国互联网界早已蔚然成风,企鹅早就驾轻就熟,因为这个就责怪360貌似有点冤,凭什么企鹅山寨就可以,我大360就不可以?
好吧,咱还是继续围观。在好奇、自恋等各种情绪的支配下,我在360的搜索框里输入了本博客的站点网址“site:www.zhujianfeng.info”。这个大家都懂的,就是看搜录了多少页面呗。搜索结果出来之后哥那个兴奋啊,360真是太给鄙人面子了,哥从来没有给360提交过url,哥的网站流量这么小,居然收录了,居然有3个页面!!!想当年哥想让百度收录,提交url之后苦等了好几个月啊!!苦等好几个月之后也才只收录了3个页面啊!!等等,怎么360收录的这3个页面跟百度一个月之前收录的那三个页面是一样的?顺序还是一样的,这让我情何以堪,合着您就是个二道贩子么?
额,这样下结论未免太早了,于是我做了一个不太艰难的决定,我决定去apache的访问日志里头找360的蜘蛛,如果没有,那就有得怀疑了。蜘蛛嘛,就是搜索引擎抓取网页的程序(详见http://baike.baidu.com/view/2755932.htm),搜索引擎给我们的结果都是蜘蛛事先从各个网站抓取过来的。那也就是说,既然我能在360综合搜索搜到我的网站,那么360的蜘蛛肯定要事前到我的网站上抓取过页面,我的apache日志里肯定就有360蜘蛛的“踪迹”。
比如,百度蜘蛛在我这里的踪迹如下:
123.125.71.113 – - [05/Jul/2012:06:59:34 +0000] “GET /wp-includes/wlwmanifest.xml HTTP/1.1″ 200 1314 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.27 – - [05/Jul/2012:06:59:36 +0000] “GET /?feed=rss2 HTTP/1.1″ 200 9435 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.25 – - [05/Jul/2012:06:59:38 +0000] “GET /?feed=rss2&p=18 HTTP/1.1″ 200 1314 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.74 – - [05/Jul/2012:06:59:40 +0000] “GET /?p=18&replytocom=2 HTTP/1.1″ 200 7297 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.48 – - [05/Jul/2012:06:59:42 +0000] “GET /?feed=rss2&page_id=2 HTTP/1.1″ 200 1041 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.101 – - [05/Jul/2012:06:59:44 +0000] “GET /?feed=rss2&cat=4 HTTP/1.1″ 200 4828 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.101 – - [05/Jul/2012:06:59:46 +0000] “GET /?feed=rss2&p=47 HTTP/1.1″ 200 1089 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.103 – - [05/Jul/2012:06:59:48 +0000] “GET /?feed=rss2&cat=3 HTTP/1.1″ 200 2864 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.53 – - [05/Jul/2012:06:59:50 +0000] “GET /?feed=rss2&p=27 HTTP/1.1″ 200 1082 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.23 – - [05/Jul/2012:06:59:52 +0000] “GET /?feed=rss2&p=13 HTTP/1.1″ 200 1079 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.102 – - [05/Jul/2012:06:59:54 +0000] “GET /?p=50&replytocom=3 HTTP/1.1″ 200 7843 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.83 – - [05/Jul/2012:06:59:56 +0000] “GET /?feed=rss2&p=50 HTTP/1.1″ 200 1209 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.113 – - [05/Jul/2012:06:59:58 +0000] “GET /?feed=rss2&cat=5 HTTP/1.1″ 200 4827 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.36 – - [05/Jul/2012:07:00:00 +0000] “GET /?feed=rss2&cat=7 HTTP/1.1″ 200 3824 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”
123.125.71.45 – - [05/Jul/2012:07:00:02 +0000] “GET /?feed=rss2&cat=6 HTTP/1.1″ 200 2250 “-” “Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”

google的:
66.249.73.201 – - [23/Jun/2012:10:48:07 +0000] “GET /robots.txt HTTP/1.1″ 404 512 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.73.201 – - [23/Jun/2012:10:48:07 +0000] “GET /?p=mxvrrqtcpsp HTTP/1.1″ 200 19085 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.73.201 – - [23/Jun/2012:11:13:51 +0000] “GET /?p=mxvrrqtcpsp&paged=2 HTTP/1.1″ 200 6873 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.68.52 – - [23/Jun/2012:16:45:26 +0000] “GET /robots.txt HTTP/1.1″ 404 512 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.68.52 – - [23/Jun/2012:16:45:26 +0000] “GET /?p=41 HTTP/1.1″ 200 4450 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.68.52 – - [23/Jun/2012:19:45:24 +0000] “GET /?m=201204 HTTP/1.1″ 200 8477 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.67.162 – - [23/Jun/2012:22:03:28 +0000] “GET /robots.txt HTTP/1.1″ 404 510 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.67.162 – - [23/Jun/2012:22:03:28 +0000] “GET /?m=201206 HTTP/1.1″ 200 5522 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.67.162 – - [24/Jun/2012:04:03:36 +0000] “GET /wp-trackback.php?p=13 HTTP/1.1″ 302 604 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”
66.249.67.162 – - [24/Jun/2012:04:03:37 +0000] “GET /?p=13 HTTP/1.1″ 200 6593 “-” “Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)”

bing的:
157.55.18.23 – - [28/Jun/2012:08:52:12 +0000] “GET /robots.txt HTTP/1.1″ 404 535 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.18.23 – - [28/Jun/2012:08:52:46 +0000] “GET /?C=M;O=A HTTP/1.1″ 200 9419 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.17.150 – - [29/Jun/2012:06:13:25 +0000] “GET /robots.txt HTTP/1.1″ 404 535 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.18.23 – - [29/Jun/2012:06:56:05 +0000] “GET /?C=M;O=A HTTP/1.1″ 200 9419 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.16.11 – - [29/Jun/2012:08:12:05 +0000] “GET /robots.txt HTTP/1.1″ 404 535 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.16.11 – - [29/Jun/2012:08:23:58 +0000] “GET /phpinfo.php HTTP/1.1″ 404 508 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.17.150 – - [29/Jun/2012:08:55:06 +0000] “GET /wiki/index.php/%E9%A6%96%E9%A1%B5 HTTP/1.1″ 404 527 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.16.11 – - [29/Jun/2012:14:56:49 +0000] “GET /robots.txt HTTP/1.1″ 404 535 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.16.11 – - [29/Jun/2012:15:16:30 +0000] “GET / HTTP/1.1″ 200 9419 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
157.55.16.11 – - [23/Jun/2012:16:21:24 +0000] “GET /robots.txt HTTP/1.1″ 404 535 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”

作为一个有身份的搜索引擎,相信360应该也是有蜘蛛的。接下来就是日志里找360蜘蛛啦。首先我们要猜,360的蜘蛛会叫啥呢?至少应该带上360或者带上qihu之类的词吧。如果真的没带,那就当我上面这些都在放P好了。在所有的日志里搜索一把“360”,大小写都算上,OH,no,这么多360浏览器的身影,去掉360EE和360SE,结果都是数字里恰好有个360。这。。。难道是真的真的真的没有360的蜘蛛来么?好吧,下面咱反过来找好了,先找所有带有bot或者spider的记录好了。正常的蜘蛛在名字里应该会有这两个单词中的一个吧,如果360的蜘蛛叫做“zhizhu”,那我无话可说,只能找块豆腐撞死算了。先查找含有bot或者spider的行,然后里面在查找里面是否有和360有关的单词。结果是。。。。。没有!!

这说明什么呢?这说明有很大的可能360的蜘蛛从来没有来过我的网站,但是他的结果页却有我的网站。套用小沈阳的一句名言:这是为什么捏?
为了避免是因为我的文本查找能力太差导致冤枉了360,我把日志放出来好了,大家帮我找找有360蜘蛛来过没,如果谁找到了请告诉我一声,我好好准备点苍蝇虫子啥的迎接360蜘蛛的到来。
日志下载地址:http://www.zhujianfeng.info/temp/access.tar.gz

作为一个菜鸟,最近学习了一下Jquery插件开发,写完一个练手的插件之后发现在Jquery上开发插件实在是很令人愉悦。Jquery插件分为两种,一种是类级别的,另一种是对象级别的。由于这篇文章里我学习的是对象级别的,所以本文主要记录对象级别插件开发。
首先插件开发需要对Jquery的fn进行扩展,一般采取下述几种方式之一

//方式一
jQuery.fn.myPlugin = function() {
    //我们的代码
};

//方式二
$.fn.myPlugin = function() {
    //我们的代码
};

//方式三
jQuery.fn.extend({     
    myPlugin:function(){     
        //我们的代码       
    }     
});

//方式四
$.fn.extend({     
    myPlugin:function(){     
        //我们的代码       
    }     
})

这里面的$符号其实就是变量jQuery的一个别名而已,另外,我们可以使用extend方法来扩展fn,也可以直接在fn上定义新的对象。除此之外,我们还需要把插件封装起来,防止插件的代码污染其他逻辑代码,所以使用一个匿名函数来做这件事情

(function( $ ) {
  $.fn.myPlugin = function() {
    // 我们的代码
  };
})( jQuery );

这样我们就可以使用$(“somediv”).myPlugin()来使用这个插件了。为了能够让插件有多个方法可用,那么可以使用如下方式来组织代码

(function( $ ){

  var methods = {
    init : function( options ) { 
      // 代码
    },
    show : function( ) {
      // 代码
    },
    hide : function( ) { 
      // 代码
    },
    update : function( content ) { 
      // 代码 
    }
  };

  $.fn.myPlugin = function( method ) {
    
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist' );
    }    
  
  };

})( jQuery );

//可以使用如下方式来调用
$("somediv").myPlugin({...}); //调用了init方法
$("somediv").myPlugin("update",{...});//调用了update方法

代码会首先判断调用者传入的第一个参数所对应的函数名在不在定义的函数哈希里,在的话使用apply方法调用该函数,并把被调用函数的this设置为当前this,同时把剩余的参数传给被调用的函数。如果第一个参数是一个对象或者为空,那么同样使用apply调用init初始化方法。
在插件运行过程中,如果有数据需要存储,比如上例中的options需要存储起来,供插件运行时其他方法使用,那么我们最好使用jquery的data方法来管理。

(function( $ ){

  var methods = {
    init : function( options ) { 
      // 这里存储数据
      $(this).data("mydata", options);
      // 其他代码
    },
    show : function( ) {
      // 这里使用数据
      var myData = $(this).data("mydata");
      //其他代码
    },
    hide : function( ) { 
      // 代码
    },
    update : function( content ) { 
      // 代码 
    }
  };

  $.fn.myPlugin = function( method ) {
    
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist' );
    }    
  
  };

})( jQuery );

最后放上练手的例子,一个可以点击表头排序的表格插件

(function($) {
	var arrowUp = "▲", arrowDown = "▼";
	var sortArray = function(arr, sortBy, order) {
		var sortFunc = function(a, b) {
			if (order === "desc") {
				console.log(typeof a[sortBy]);
				if (typeof a[sortBy] === "string" && typeof b[sortBy] === "string") {
					return a[sortBy].localeCompare(b[sortBy]);
				} else {
					return b[sortBy] - a[sortBy];
				}
			} else {
				if (typeof a[sortBy] === "string" && typeof b[sortBy] === "string") {
						return b[sortBy].localeCompare(a[sortBy]);
				} else {
					return a[sortBy] - b[sortBy];
				}
			}
		};
		return arr.sort(sortFunc);
	};
	var drawBody = function(options){
		var dCount = 0, ddCount = 0;
		dCount = options["data"].length;
		ddCount = options["data"][0].length;
		var htm = [];
		for (var i = 0; i < dCount; i++) {
			htm.push("<tr>");
			for (var j = 0; j < ddCount; j++) {
				htm.push("<td>");
				htm.push(options["data"][i][j]);
				htm.push("</td>");
			}
			htm.push("</tr>");
		}
		var htmStr = htm.join("");
		$(this).find("div > table > tbody").html(htmStr);
	};
	var methods = {
		"init" : function(opts) {
			var options = $.extend({
				"thead" : ["c1", "c2"],
				"data" : [[1, 2], [3, 4],[5, 3]],
				"sortBy": 1,
				"order" : "desc"
			},opts);
			var headStr = "";
			cCount = options.thead.length;
			var colWidthAll = 100 / cCount;
			for (var i = 0; i < cCount; i++) {
				var arrow = "";
				if (options.sortBy === i) {
					if (options.order === "desc") {
						arrow = arrowDown;
					} else {
						arrow = arrowUp;
					}
				}
				var thWidth = "";
				if (options.colWidth) {
					if (options.colWidth[i]) {
						thWidth = "width='" + options.colWidth[i] + "'";
					}
				} else {
					thWidth = "width='" + colWidthAll + "%'"
				}
				headStr += "<th " + thWidth + "><span rel='" + i + "'>" + options.thead[i] 
						+ " <span>" + arrow + "</span></span></th>";
			}
			var tableStr = "<div class='sGrid_wrap'><table class='sGrid'>"
								+"<thead><tr>"
								+ headStr
								+"</tr></thead>"
								+"<tbody></tbody>"
							+"</table></div>";
			$(this).html(tableStr);
			
			options["data"] = sortArray(options["data"], options["sortBy"], options["order"]);
			drawBody.apply(this, [options]);
			var me = $(this);
			$(this).find("div > table > thead th span").click(function(){
				var c = $(this).attr("rel");
				if (c == options.sortBy) {
					if (options.order === "desc"){
						options.order = "asc";
						$(this).find("span").html(arrowUp);
					} else {
						options.order = "desc";
						$(this).find("span").html(arrowDown);
					}
				} else {
					me.find("div > table > thead th span span").html("");
					options.sortBy = c;
					options.order = "desc";
					$(this).find("span").html(arrowDown);
				}
				options["data"] = sortArray(options["data"], options["sortBy"], options["order"]);
				drawBody.apply(me, [options]);
			});
		}
	};
	$.fn.rankTable = function(method) {
		if ( methods[method] ) {
      		return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    	} else if ( typeof method === 'object' || ! method ) {
      		return methods.init.apply( this, arguments );
    	} else {
      		$.error( 'Method ' +  method + ' does not exist' );
    	}
	};
})(jQuery);
//调用方式
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>rankTable</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js" type="text/javascript"></script> 
    <script src="jquery.ranktable.js" type="text/javascript"></script>
    <link href="style.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript">
        $(function () {
            $("#rank_table").rankTable({
                "thead" : ["姓名", "年龄", "成绩"],
                "data" : [["张三", 16, 98], ["李四", 15, 88], ["王五", 18, 100], ["孙六", 17, 60]],
                "sortBy": 2,
                "order" : "desc",
                "colWidth" : ["33%","33%"]
            });

        });  
    </script>  
</head>  
<body> 
    <div id="rank_table">  
    </div>
</body>  
</html> 

今天贝贝同学问了我一个问题,怎样在可编辑的div中的光标处插入图片。网上search了一把,果然如贝贝所说,一堆都是往光标处插入文本的。
最后发现使用document.execCommand()方法即可简单的往光标处插入图片。在chrome和firefox下只需要执行document.execCommand(‘InsertImage’, false, _imgUrl);就能达到目的,可是在IE下就有bug:当光标停留在某个地方,不选中任何东西的情况下,该方法无效。当选中编辑区内的一部分内容时,该方法有效。经过一番摸索,终于找到解决方案。原来在不选中任何东西的情况下,当我去点击插入按钮时,编辑区就失去了焦点,这个时候插入会失败。所以需要先保存焦点状态,插入之前恢复状态即可。具体内容看代码

<html>
<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title>edit</title>
</head>
<body>
    <div id="editor" 
        style="width:400px;margin:100px auto;height:300px;border:1px solid #DFDFDF;" 
        contenteditable="true">
        这里插入一个图片!
    </div>
    <a href="javascript:void(0);" onclick="edit()">强力插入!</a>
    <script>
    var editor = document.getElementById("editor");
    var range, bookmark;
    var saveFocus = function(){//保存焦点状态
        if (document.selection) { //只有坑爹的IE才执行下面的代码
            range = document.selection.createRange();
            bookmark=range.getBookmark();
        }
    }
    editor.onclick = saveFocus;//在鼠标点击编辑区时保存焦点
    editor.onkeydown = saveFocus;//在输入内容时也保存焦点
    function edit() {
        insertImg("http://www.baidu.com/img/baidu_sylogo1.gif");
    }
    function insertImg(_img) {
        if (range) { //同样,坑爹IE专用代码
            range.moveToBookmark(bookmark);
            range.select();
        }
        document.execCommand('InsertImage', false, _img);

    }
    </script>
</body>
</html>

将代码中方法document.execCommand(‘InsertImage’, false, _img)更改参数,应该可以插入html代码等其他元素。