Django 自带的 Comments 模块还蛮好用的,但是提交的时候貌似有点麻烦,虽然可以手动去掉那个预览的按钮,只留下提交按钮,但还是想用户体验更好一些,用 Ajax 的方式来改进评论的提交。
想要的效果很简单,用户写完评论,点击提交按钮,这时候出现 loading 图标,显示正在提交,提交成功后,用 YFT 的方式把刚才的评论加到评论列表最后,同时评论数加一,loading 图标消失。当然,需要用到我最喜欢的 jQuery 和她的伙伴 Effect.Highlight。
在我的页面中,需要对每一个产品作评论,于是在 product_detail.html 的头部,加上如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <script type="text/javascript" charset="utf-8">
function bindComment() {
$('#comments form').submit(function() {
$('input[type=submit]').attr('disabled', 'disabled');
$.ajax({
type: "POST",
data: $('#comments form').serialize(),
url: "{% comment_form_target %}",
cache: false,
dataType: "html",
success: function(html, textStatus) {
n = Number($('#commentCount').text());
c = $(html).find('[class^=comment]:last');
c.hide();
if (n == 0)
{
$('h2.comment').after(c);
}
else
{
$('[class^=comment]:last').after(c);
}
$('#commentCount').text(n+1);
c.effect("highlight", {}, 5000);
$('input[type=submit]').removeAttr('disabled');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('Sorry, your comment was unable to be posted at this time. Please try later.');
}
});
return false;
});
}
$(document).ready(function() {
bindComment();
$("#loading").bind("ajaxSend", function() {
$(this).show();
}).bind("ajaxComplete", function() {
$(this).hide();
});
});
</script> |
然后,需要在 Submit 按钮下加个隐藏的 loading 图标:
1
| <span id="loading"><img src="/media/loading.gif" />Submitting your comment, please wait... </span> |
最后,记得在 css 文件中添加 loading 的样式,这样评论的改进就完成了。当然还可以加上对提交数据的验证和提示,通过 jQuery,实现起来会很简单。
Tags: AJAX, comments, Django, jquery
界面字体设置
修改 C:\Program Files\Common Files\GTK\2.0\etc\gtk-2.0\gtkrc 就可以了,比如:
1 2 3
| gtk-font-name = "SimSun 9"
gtk-theme-name = "Raleigh" |
对话框的字体设置
在 C:\Program Files\Common Files\GTK\2.0\etc\pango\pango.aliases 中添加一行:
在 C:\Program Files\Common Files\GTK\2.0\etc\gtk-2.0\ 下新建文件 gtkrc.zh_CN,输入内容:
1 2 3 4 5 6 7
| style "user-font" {
font_name = "msst 9"
}
widget_class "*" style "user-font"
gtk-font-name="msst 9" |
这也是修改 GTK 程序界面的方法。
Tags: gtk, pidgin
Greasemonkey 会把对象包裹起来返回 XPCNativeWrapper,写 JS 的时候需要留心。下面这些要点来自 Greasemonkey Hacks。
1. 调用函数
1 2 3 4 5
| //工作
window.setTimeout(my_func, 1000)
//不工作
window.setTimeout("my_func()", 1000) |
2. 事件处理
1 2 3 4 5 6 7 8 9 10
| //工作
var elmLink = document.getElementById('somelink');
elmLink.addEventListener("click", my_func, true);
//不工作
var elmLink = document.getElementById('somelink');
elmLink.onclick = my_func;
var elmLink = document.getElementById('somelink');
elmLink.onclick = 'my_func(this)'; |
3. 命名表单和表单元素
1 2 3 4
| <!--假如有表单-->
<form id="gs">
<input name="q" type="text" value="foo" />
</form> |
1 2 3 4 5 6 7
| //工作
var form = document.forms.namedItem("gs");
var input = form.elements.namedItem("q");
var q = input.value;
//不工作
var q = document.gs.q.value; |
4. 自定义属性
1 2 3 4 5 6 7
| //工作
var elmFoo = document.getElementById('foo');
elmFoo.setAttribute('myProperty', 'bar');
//不工作
var elmFoo = document.getElementById('foo');
elmFoo.myProperty = 'bar'; |
5. 迭代集合
1 2 3 4 5 6 7 8 9 10 11
| //工作
for (var i = 0; i < arInputs.length; i++) {
var elmInput = arInputs[i];
…
}
//不工作
var arInputs = document.getElementsByTagName("input");
for (var elmInput in arInputs) {
…
} |
6. scrollIntoView
1 2 3 4 5 6 7 8
| //工作
var elmFoo = document.getElementById('foo');
var elmUnderlyingFoo = elmFoo.wrappedJSObject || elmFoo;
elmUnderlyingFoo.scrollIntoView();
//不工作
var elmFoo = document.getElementById('foo');
elmFoo.scrollIntoView(); |
7. location
1 2 3 4 5
| //工作
window.location.href = "http://example.com/";
//不工作
window.location = "http://example.com/"; |
8. 调用远程页面脚本
1 2 3 4 5 6 7 8 9
| //工作
var searchForm = getNode("s");
searchForm.elements.namedItem("q").value = this.getRunnableQuery();
top.js._MH_OnSearch(unsafeWindow, 0);
//不工作
var searchForm = getNode("s");
searchForm.elements.namedItem("q").value = this.getRunnableQuery();
top.js._MH_OnSearch(window, 0); |
9. watch
1 2 3 4 5 6 7
| //工作
unsafeWindow.watch("location", watchLocation);
unsafeWindow.location.watch("href", watchLocation);
//不工作
window.watch("location", watchLocation);
window.location.watch("href", watchLocation); |
10. 样式
1 2 3 4 5 6 7 8
| //工作
var elmFoo = document.getElementById("foo");
elmFoo.style.margin = 0;
elmFoo.style.padding = 0;
//不工作
var elmFoo = document.getElementById("foo");
elmFoo.setAttribute("style", "margin:0; padding:0;"); |
Tags: greasemonkey
Peterzahlt 很不错,天下竟然有免费的午餐。不过现在学精了,会在中途插播广告(人家也要吃饭的嘛),过了 10 分钟以后,会随机出现 5、6 次广告,如果在 30 秒之内不点击的话就自动切断,够狠啊。这样就必须一直紧盯着它广告,万一漏点就要重新排队,很长很长的队哦。
不过还好有强大的 Firefox,再加上 Greasemonkey,那么这件非常不人性化的事情就可以由机器代劳了。
假设你已经装好 Greasemonkey,那么点击安装就可以了。代码很简单。
1 2 3 4 5 6 7 8 9 10 11 12 13
| // ==UserScript==
// @name Peterzahlt Auto Click
// @namespace http://userscripts.org/users/ant21
// @description Auto click Peterzahlt ads and you can lie on bed to call.
// @include http://www.peterzahlt.de/*
// ==/UserScript==
window.detect = function()
{
location.href = "javascript:void(clickbanner(0));"; //click banner
}
window.setInterval(detect, 10000); |
Tags: firefox, greasemonkey, peterzahlt
Google Chrome 3.0 Dev 版已经放出,可以从这里下载,非常不错哦。而且还有一个小工具可以帮你检测最新版本并下载。想要为 Chrome 开发扩展的话,官方的开发者老家和 ChromePlugins 都不容错过哦。
Tags: Chrome, Google
Sphinx 0.6.1 没有 0.5.1 好用,而且用来编译 Django 文档时会出错。用 easy_install 安装的,调用的时候总是默认选择了最新版,没找到切换版本的方法,还是把 0.6.1 卸载了吧。运行命令:
1
| easy_install -m PackageName |
两遍以后,再调用 Sphinx 就会切换到 0.5.1 版本了。
Tags: Django, easy_install, sphinx
貌似从用上 WP 乱码就如影随形,现在倒也见怪不怪了。今天鼓足勇气升级到 2.7.1 还是乱码,手动解决吧。
wp-includes 目录下,wp-db.php 在 348 行
的上面加上
就行了。
Tags: wordpress
on May 3rd, 2009痘,逗?
好笑啊,想知道,从脸上的痘如何上升到苦难的生活。或许已经惯于用一种悲观和敌对的态度来看待周遭的人和事。再通过自己的放大镜来无休止的放大,好让自己觉得受了天大的委屈,全世界都因为这点鸡毛蒜皮而蠢蠢欲动、风起云涌。或许时刻生活在这种感觉中才会让自己觉得踏实和舒服,我痛苦我存在?
生活本就是充满亿万种可能,风平浪静也好,风起云涌也好,乐也好,苦也好。本来如此,更不必去寻个是非曲直好坏享乐苦难的来头上安头,担得起才是真丈夫,一来一档,二来二收,找什么葛藤往自己身上遮羞。歇了吧。
两个黄鹂鸣翠柳,一行白鹭上青天。
美!
diggfoto 上的图片还蛮不错的,但是要一张一张去点确实有点不人道(总在期望下一张更精彩?),下面的程序可以帮忙把它的图片都下回来,事先最好准备一个 diggfoto 文件夹,嘿嘿。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #! /usr/bin/env python
#coding=utf-8
import os
import sys
import urllib
import urllib2
from BeautifulSoup import BeautifulSoup
def download(url='http://diggfoto.com/'):
try:
r = urllib2.urlopen(url)
page = r.read()
soup = BeautifulSoup(page)
entry = soup.find('div', 'entry')
a = entry.find('a')
nextLink = a['href']
img = a.find('img')
imageUrl = img['src']
dotindex = imageUrl.rindex('.')
except AttributeError, e:
print e
except IndexError, e:
print e
except UnicodeDecodeError, e:
print e
except:
print 'Oops'
else:
if len(img['alt']) == 0:
slash = url.rfind('/', 0, len(url)-2)
rand = url[slash+1:url.rfind('/')]
else:
rand = img['alt']
if not os.path.exists('diggfoto'):
print 'Is there a directory named diggfoto?'
sys.exit(0)
name = os.path.join('diggfoto', rand + imageUrl[dotindex:dotindex+4])
exist = os.path.exists(name)
if imageUrl and not exist:
try:
print 'Downloading Image ==> %s' % name
except:
print 'Downloading Image ...'
try:
urllib.urlretrieve(imageUrl, name)
except:
download(nextLink)
if nextLink:
print 'Next url ==> %s' % nextLink
if nextLink.endswith('tags/') or nextLink.endswith('archive/') \
or nextLink.endswith('about/'):
print 'Complete'
else:
download(nextLink)
if __name__ == "__main__":
sys.exit(download()) |