可以随意拖动网址排序,删除或添加网址。Simple面向的用户是追求简洁实用的小众群体,并不针对小白用户,我觉得可能白领居多,不知是否合您的口味。跟大家简单分享一下纯静态版的实现,以及我的一些想法,本菜并不擅长做前端,如果出现低级错误,可不要贱笑啊。代码与最新的代码可能有所差别,可以直接查看源代码,注释比较详细。
一. 页面布局
<!doctype html>//省略了若干js,css引用,省略了不重要的页面元素
<html lang="zh">
<head>
<meta charset="utf-8">
<title>Simple 最简洁的上网导航</title>
<link rel="shortcut icon" type="image/ico" href="img/favicon.ico" />
</head>
<body>
<div>
<div id="head">
<a href="#" onclick="showAbout()">帮助</a> <a href="#" onclick="reset()">重置</a>
</div>
<div id="logo">Simple</div>
<div id="trashContainer">
<img id="trash" src="img/trash.png"/><img id="trash_tip" src="img/trash_tip.png" style="display:none"/>
</div>
<div id="searchContainer">
<form id="searchForm" action="http://www.baidu.com/s" target="_blank">
<input id="search" type="text" name="wd" baiduSug="2" />
</form>
</div>
<div style="margin-top: 50px">
<ul id="sortable">
<li no="1"><a href="http://www.baidu.com" target="_blank" style="background: url(img/defaultIcon.png) no-repeat 0px 0px">百 度</a></li>
<!--省略无数网址-->
</ul>
</div>
</div>
<div id="about">
<ol>
<li>按空格键,可将焦点置于搜索框内; 按 Ctrl+<- 键,可清空搜索框</li>
<li>默认搜索为百度,关键词前空一格则使用google搜索</li>
<li>网址可拖动调换位置并随意删除</li>
<li>点击重置可恢复到最最原始的页面</li>
<li>看在我们连logo都省了的份上,推荐给身边的朋友吧</li>
</ol>
<a style="float: right; text-decoration: none;" href="#"
onclick="$('#about').hide('fast');">关闭</a>
</div>
</body>
<script charset="gbk" src="http://www.baidu.com/js/opensug.js"></script>
</html>
先说说功能系数,功能系数是指模块功能所占整个页面功能的百分比。我要使页面布局符合每个模块的功能系数。也就是说某模块的功能系数越高,那么它的位置就越显眼,在用户视野范围内的时间就越长。
页面主要是三个部分:Logo文字、搜索框、网址列表。其中Logo文字以显示一秒随后隐藏的方式来展现,我觉得以这种方式来展现Logo显得页面不那么呆板,最终隐藏掉Logo显得整个页面又不乏稳重,同时还保持了页面的简洁。最有用的当然是搜索框和下边的网址导航了,搜索框没有搜索按钮,因为我觉得搜索按钮的功能系数也是非常的低,Simple针对的用户不是小白用户,所以直接省略掉搜索按钮。网址列表仍然没有达到我理想的效果,后续还会慢慢改善。如何保持网站列表清晰又不花哨是一个值得探讨的问题,相信会有一个比较好的方案。
还有一个删除网址的垃圾桶,Simple没有在周围添加一个设置图标按钮,点击后在网址边上显示删除符号。而是直接在拖动的过程中,显示垃圾桶提示用户可以删除,保持了页面的简洁。
帮助、重置、添加是这里最不常用的功能,所以让它靠在了右上方不起眼的地方,以与它们的功能系数匹配。
二. 搜索框功能
点开帮助看一下,会看到有几个关于搜索框的功能点。js库使用的是jquery和jquery.cookie。
平时用搜索的时候有两点稍有不便,一个是焦点问题。我们的页面加载完成就将焦点放在了搜索框中,直接输入即可。另外按下空格键就可以将焦点放到搜索框中,如果按了空格键并且搜索框没有焦点,则使它获得焦点。这里采用的是keyup事件,如果用keydown事件的话,等文本框获得焦点之后,空格字符仍然会输入到文本框中。
$(document).keyup(function(e) {
if (e.keyCode == 32 && document.activeElement.id != "search") {
$("#search").focus();
}
});
另一个是删除关键字问题,如果想删除关键字直接按ctrl+backspace即可,比ctrl+a再删除还方便,整个过程不需要鼠标的参与。是不是很爽啊,什么?你还是习惯咔咔咔咔摁删除?哎,习惯问题,我刚开始也是咔咔咔咔摁删除,但这是无意识的操作,如果有意识地用几次ctrl+backspace就会觉得由衷的爽。代码如下:
$("#search").keydown(
function(e) {
if (e.ctrlKey == 1 && e.keyCode == 8) {
$("#search").val("");
}
});
默认情况下按回车键调用百度搜索,搜索内容前置一个空格将调用google搜索,最近封网越加严重,google基本上不了了,裆中央看来是不想让同志们愉快地玩耍了。看代码吧,当看到有空格时就改变相应的属性,然后提交表单。这里为什么用表单而不用window.open呢?window.open兼容性有问题,至少在我的手机上点回车是不响应的。
$("#search").keydown(
function(e) {if (e.keyCode == 13) {
var keyword = $("#search").val();
if (keyword.length > 0 && keyword.charAt(0) == ' ') {
$("#searchForm").attr("action","https://www.google.com.hk/search");
$("#search").attr("name","q");
} else {
$("#searchForm").attr("action","http://www.baidu.com/s");
$("#search").attr("name","wd");
}
$("#searchForm").submit();
return false;
}
});
当你输入关键字时,会得到提示,这里的提示来自百度,在搜索框上加baiduSug属性,再引入下边的opensug.js即可,baiduSug等于1时,用鼠标点击提示项会自动提交表单,等于2时不会自动提交表单。提示框最下边的“百度搜索框提示”稍微有点别扭,可以把js下载下来将提示删除。我刚开始是这么干的,后来想了想又直接用了原版,万一百度找上门来让我赔钱就麻烦了。
<script charset="gbk" src="http://www.baidu.com/js/opensug.js"></script>
三. Logo显示
logo显示有啥好说的?logo的颜色是会变的奥,不信明天再刷一下看看,我们让logo一周七个颜色,每天都不一样,每天带给大家不一样的心情。代码使logo透明度用一秒的时间从0变到1,停留一秒,再用一秒的时间从1变到0。
function loadLogo() {
var colorArray = [ "#45b97c", "green", "violet", "#faa755", "#6950a1",
"#4c4c4c", "#ef5b9c" ];
$("#logo").css("color", colorArray[new Date().getDay()]);
$("#logo").fadeTo(1000, 1, function() {
setTimeout(function() {
$("#logo").fadeTo(1000, 0);
}, 1000);
});
}
四. 网址添加
点击右上角的添加即可弹出网址添加框,输入网址或网站名会有提示,选择并回车即可。网址提示框的实现可以看我的另一篇博客《贡献个网址搜索提示框》,就不再重复介绍了。这里只看一下添加网址的逻辑。先是大概的判断一下输入,校验一下网址,校验逻辑不是很严格。然后将网址名字、网址、编号保存到cookie中,过期时间设为1000天,如果不设的话,默认关闭浏览器cookie就没了。中间省略部分函数的代码,太多了就不贴了,看名字应该知道是什么意思。
function add() {
var name = $("#mysite-name-add").val().trim();
var url = $("#mysite-url-add").val().trim();
if (name == '' || url == '') {
addtip("添加内容不能为空", "red");
return;
}
url = url.replace(/^(http|https):\/\//, '');
if (!isURL(url)) {
addtip("网址不规范", "red");
return;
}
if (name.length == 2)//网站名两个字时中间加一个空格
name = name[0] + ' ' + name[1];
var customArray;
var custom = $.cookie('custom');
if (custom == undefined)
customArray = [];
else
customArray = $.parseJSON(custom);
var currentNo = getCustomMaxNo() + 1;
customArray.push({
"name" : name,
"url" : url,
no : currentNo
});
//save to cookie
$.cookie('custom', JSON.stringify(customArray), {
expires : 1000
});
appendSite(currentNo, name, url);//添加网址
changeOrder();//保存网址顺序
$("#mysite-name-add").val('');
$("#mysite-url-add").val('');
$("#btn-site-back").focus();
addtip(name + " 添加成功", "green");
}
五. 网址拖动
每个人常用的网址都不一样,每个网址的使用频率也不一样,所以我们的网址可以直接拖动变换位置。拖动用到了jquery.ui库的sortable,可以任意拖动对象排序,并设置排序的一系列回调函数,changeOrder就是排序完毕并发生改变时的回调函数。每个网址都有一个编号,当位置变动时,将编号依次纪录到cookie中。
function changeOrder(){
var order=[];
$("#sortable li").each(function(){
order.push($(this).attr("no"));
});
$.cookie('order',JSON.stringify(order),{expires:1000});
}
六. 网址删除
网址拖动的过程中,搜索框上方会出现一个垃圾桶的图标,当网址覆盖垃圾桶时,垃圾桶的颜色会变成红色,这时候松开鼠标,网址就被删掉了。这里使用了jquery.ui库的droppable,它允许其他对象拖放到它上面,并提供了一系列的监听事件,例如覆盖、移除、放下等。垃圾桶是使用了两个不同的img,默认显示绿色的隐藏红色的。监听到开始拖放网址时(这个是sortable的事件)显示垃圾桶,网址覆盖到垃圾桶时隐藏绿色img显示红色img。如果松开鼠标直接将网址删除,并隐藏垃圾桶。这里为什么要选取两个img,而不是用一个img,监听到事件改变它的src属性呢?如果这样的话,每次改变src属性,浏览器都会重新请求资源,所以图片切换会跟不上。就算可以解决重新请求资源的问题,第一次改变src还是要请求的,这样会使第一次图片切换跟不上。所以直接用两个img,页面加载完成就开始请求图片,再切换时就不会因为请求资源带来延时了。看代码吧。
$("#trashContainer").droppable({
drop : function(event, ui) {
$(ui.draggable).remove();
deleteCustom($(ui.draggable).attr("no"));//如果网址是用户添加的,将在cookie中将添加的网址删除
$("#trash_tip").css("display", "none");
$("#trash").css("display", "block");
},
out : function(event, ui) {
$("#trash_tip").css("display", "none");
$("#trash").css("display", "block");
},
over : function(event, ui) {
$("#trash").css("display", "none");
$("#trash_tip").css("display", "block");
}
});
七. 网址加载
说一下我们的网址加载策略吧,像这些导航类的网站,默认网址列表可能会发生变化,比如我在后台删除或者添加了网址。为了最大化的提高用户体验,针对自定义过的用户,我们不让他受任何影响,没有自定义过的就按照后台定义的最新网址来。如果时间长了,后台变换的网址多了,想重新整理网址让所有用户都变为最新的网址列表,就变换网址版本,如果网址版本出现变化,不管有没有自定义都重新来过。如何实现呢,对于后台删除的网址,在网址对应的li上加个type="delete"属性,添加的网址直接添加即可。打开网站时,读取cookie,判断是否有版本变更,判断用户是否自定义过。如果没有自定义过将带有type="delete"属性的网址删除。如果自定义过,先把用户添加的网址追加到网址列表,再按保存的顺序把相应编号的网址移动到最后,可能还剩几个网址没有在order里出现,这些网址就是被用户删除掉的,算一下有几个,再把前边的几个删掉就ok了。
function loadWebSites() {
//判断版本变更
if ($.cookie('ver') != '0.9') {
$.removeCookie("order");
$.removeCookie("custom");
$.cookie('ver', '0.9', {
expires : 1000
});
}
//判断是否已经自定义过
var order = $.cookie('order');
if (order != undefined) {
var custom = $.cookie('custom');
if (custom != undefined) {
//add custom
$($.parseJSON(custom)).each(function() {
appendSite(this.no, this.name, this.url);
});
}
//change order
var orderObject = $.parseJSON(order)
$(orderObject).each(function() {
$("#sortable li[no='" + this + "']").appendTo($("#sortable"));
});
//remove deleted item
var deletedCount = $("#sortable li").length - orderObject.length;
$("#sortable li:lt(" + deletedCount + ")").remove();
} else {
$("#sortable li[type=delete]").remove();
}
}
今天是网站正式上线的第一天,后续还会不断地完善更新,欢迎大家提出任何建议。感兴趣的朋友请关注Simple上网导航的官方微博(左上角公告里有新浪微博关注按钮),我们会进行更多的互动。如果能分享给身边的朋友那更是感激不尽,先谢过了。其实文章和代码已经写好很久了,今天才上线是因为走了些弯路,以后再跟大家聊一下这些非技术方面的问题吧。