前两天想为推特中文圈添加OAuth登陆的功能,因为我整个站用的是twitter4j,所以必须得用twitter4j提供的方法去进行 OAuth登陆,但是twitter4j官方站的例子实在太诡异了,而且是针对java应用程序的例子而不是J2EE的例子,看了半天都没法把它转到 J2EE上来,网上搜了挺久也没有相关教程可以模仿,OAuth方式登录实在是够迷惑人的,两种tonke很容易就混了,源代码也很复杂看不懂,实在是折腾死人,但最终还是折腾出来了,虽然可能做twitter应用的人不多,用twitter4j做twitter应用的人更不多,但还是分享下 twitter4j的OAuth登陆方法吧。我也不太懂里面的运行原理,只把我的用法写出来。
想做点东西练练javascript,于是打算为饭否AIR客户端爱饭加上额外的功能,例如上传图片等,先尝试了使用javascript验证和发送饭否消息,仅这个就花了不少时间,很多时间花在了去除低级错误上,例如jquery ajax的type:”post”被我写成了method:”post”,花了很多时间才找出来。
先放上主要代码,使用jquery框架以及jquer.base64插件:
var name = "yourname";
var pass = "yourpassword";
$.ajax({
url: "http://api.fanfou.com/statuses/update.xml",
type:"POST",
data: "status=信息内容",
beforeSend: function(xhr){
xhr.setRequestHeader('Authorization', 'Basic ' + $.base64.encode(name + ':' + pass));
},
success: function(data, textStatus){
alert(data);
}
});
有两个主要问题:
1.验证用户
饭否API验证方式为 HTTP Basic 验证,需要对“用户名:密码”进行base64编码,添加进ajax请求的http头信息。
XMLHttpRequest.setRequestHeader(‘Authorization’, ‘Basic ‘ + $.base64.encode(name + ‘:’ + pass));
使用饭否需要验证的API(例如读取私信、发送消息)时,都要在请求前加上这一条HTTP头信息。
爱饭使用YUI框架,可以通过YAHOO.util.Connect.initHeader设置每次ajax请求的默认HTTP头信息,
initHeader(‘Authorization’, ‘Basic ‘ + Base64.encode(name + ‘:’ + pass), true);
最后一个参数”true”代表设为默认http头信息。
设置之后每次使用YAHOO.util.Connect.asyncRequest进行ajax请求都不需要再添加验证。
2.跨域问题
使用ajax请求资源总有跨域问题,即请求只能发生在相同的域内。
以上那段代码请求的域为api.fanfou.com,如果放在网上,除非放在饭否服务器,有相同的域,否则无法运行。
对本地网页,在跨域上,不同浏览器有不同规则,IE允许跨域访问,firefox与chorme都不行。以上代码放在本地,用IE打开,就可以运行,用firefox打开,会出现Access to restricted URI denied” code: “1012。
使用IE可以通过设置可信任站点实现跨域获取内容,其他跨域方法网上很多,还未细究,但都是要在客户端设定或者两站互相配合。
所以,使用javascript发送饭否消息只适合运用在AIR程序上,AIR有自己特定的安全沙箱,允许跨域请求。
另,饭否与Twitter的API几乎一样,可直接套用。
P.S 早上起来,发现已经有人对爱饭扩展,做了查看上传的图片的功能,他还在做上传图片的功能,我也没必要再做这部分功能了。开源的好处之一,就是有很多人帮忙完善这个程序啊~
上一篇: 改善你的jquery—25条jquery实用技巧<一>
11.适当地使用动画效果
我第一次使用jQuery的时候就喜欢上了像slideDown()、fadeIn()等这些预定义的动画函数,使用它们可以很简单地做出很酷的动画效果。jQuery的animate()函数的强大和易用让人很容易进一步实现更好的效果,事实上,如果你看了jquery的源代码你会发现fadeIn()、slideDown()等这些函数的内部都使用了animate()函数,它们只是让animated()更易使用。
slideDown: function(speed,callback){
return this.animate({height: "show"}, speed, callback);
},
fadeIn: function(speed, callback){
return this.animate({opacity: "show"}, speed, callback);
}
animate()函数只是简单地接收所有的CSS属性,平滑地把属性从一个值转换到另一个值,形成动画。你可以使用它平滑地改变任何你想改变的属性,如width, height, opacity, background-color, top, left, margin, color, font-size等等。
下面这段简单的代码实现了当鼠标放在菜单上时菜单上所有列表元素的高度都平滑地改变到100px。
$('#myList li').mouseover(function() {
$(this).animate({"height": 100}, "slow");
});
animation函数不像jquery的其他函数,它是自动队列的,即如果你想在一个效果执行完后接着执行另一个效果,只需要连续使用两次animate函数,无需任何回调。
$('#myBox').mouseover(function() {
$(this).animate({ "width": 200 }, "slow");
$(this).animate({"height": 200}, "slow");
});
如果你想让两个动画同时执行,把参数放在一个object里,调用一次即可:
$('#myBox').mouseover(function() {
$(this).animate({ "width": 200, "height": 200 }, "slow");
});
你可以传入值是数字的属性形成动画,如果要传入非数字的属性,那就要使用插件,例如平滑过渡颜色效果的插件:Color Animations
12.学习事件委托
使用jQuery可以很容易地为DOM元素绑定事件,但如果绑定太多事件会让程序效率降低,事件委托可以让你可以让你绑定更少的事件但达到同样的效果,解释事件委托最好的办法是通过例子:
$('#myTable TD').click(function(){
$(this).css('background', 'red');
});
这是一个简单的函数,为表格的所有单元格绑定事件,当鼠标点击单元格即变红色,假设表格有50行10列,那么总共绑定了500个事件。如果我们能值为table绑定一个事件,让事件处理函数找出所点击的单元格,再让它变成红色,那是再好不过的了。事实上,这就是事件委托,也是我们接下来要做的:
$('#myTable').click(function(e) {
var clicked = $(e.target);
clicked.css('background', 'red');
});
参数”e”包含了所有关于event信息,包括了实际接收鼠标点击的元素,我们所需要做的就是检查鼠标点击的是哪个单元格,非常简洁。
事件委派还有一个好处。当你为一个块(表格、列表或div块等)里所有的元素绑定事件,当增加元素到这个块里,新增加的元素并不会自动绑定事件,如果使用事件委托,事件绑定后即使新增加元素也可以正常工作。
13.用class保存状态
这是html块保存状态最基本的方法,jQuery擅长通过class操纵元素,因此如果你想储存状态信息,为什么不创建一个额外的的class去保存它呢?
这是一个例子,我们想创建一个可展开的菜单,点击按钮时如果面板是关闭的,则调用slideDown(),如果是打开着则调用slideUp(),先看看HTML:
<div class="menuItem expanded">
<div class="button">
click me
</div>
<div class="panel">
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</div>
</div>
很简单,我们添加一个额外的class属性,目的只是为了说明元素现在的状态。添加后,我们要做的只是添加鼠标点击时执行slideUp()和slideDown()的事件处理函数。
$('.button').click(function() {
var menuItem = $(this).parent();
var panel = menuItem.find('.panel');
if (menuItem.hasClass("expanded")) {
menuItem.removeClass('expanded').addClass('collapsed');
panel.slideUp();
}
else if (menuItem.hasClass("collapsed")) {
menuItem.removeClass('collapsed').addClass('expanded');
panel.slideDown();
}
});
这是个很简单的例子,只作演示用,通过添加额外的class,你可以储存各种各样的值在HTML元素里。
然而,大多数情况下,使用下一条技巧里的方法更好。
14.使用jQuery的内部函数data()储存状态
jQuery有个内部函数data()可以用来在任何DOM元素上储存键/值形式的数据,因为一些原因,这个函数并没有很好的文档说明。储存数据就像下面写的这样简单:
$('#myDiv').data('currentState', 'off');
我们可以改良上一个例子的程序,我们仍然使用同样的HTML(但去掉class”expanded”),使用data()储存状态:
$('.button').click(function() {
var menuItem = $(this).parent();
var panel = menuItem.find('.panel');
if (menuItem.data('collapsed')) {
menuItem.data('collapsed', false);
panel.slideDown();
}
else {
menuItem.data('collapsed', true);
panel.slideUp();
}
});
我想你会同意,这样写比之前更简洁。要了解更多关于data()与removeData(),看这里:jQuery internals
15.创建自定义选择器
jQuery有很多内置的选择器可以通过id、class、标签、属性等查找元素,但如果你想通过其他jQuery里没有的方式查找元素,该怎么做?
或许可以在选择之前为元素添加一个class属性再进行选择,但其实扩展jQuery写新的选择器并不难。下面我们通过例子来说明:
$.extend($.expr[':'], {
over100pixels: function(a) {
return $(a).height() &gt; 100;
}
});
$('.box:over100pixels').click(function() {
alert('The element you clicked is over 100 pixels high');
});
第一部分代码创建了一个新的选择器,用来查找高度大于100像素的元素。第二部分代码使用这个新选择器为所有符合条件的元素添加click事件。
关于自定义选择器在这里就不多说了,你可以上google搜索“custom jquery selector”,肯定能找到很多很好的例子。
16.合理化你的HTML,并在页面载入的时候修改它
这个标题看起来似乎没什么意义,但实际上这个技巧不仅可以让你的代码变得整洁,还可以减少页面的大小,对SEO也有帮助。看看下面的HTML:
<div class="fieldOuter">
<div class="inner">
<div class="field">This is field number 1</div>
</div>
<div class="errorBar">
<div class="icon"><img src="icon.png" alt="icon" /></div>
<div class="message"><span>This is an error message</span></div>
</div>
</div>
<div class="fieldOuter">
<div class="inner">
<div class="field">This is field number 2</div>
</div>
<div class="errorBar">
<div class="icon"><img src="icon.png" alt="icon" /></div>
<div class="message"><span>This is an error message</span></div>
</div>
</div>
上面是一个表可能的结构,为了作为例子稍微做了下修改,我想你一定会觉得上面这段代码十分难看,如果表里有很长的内容,页面将会很长,重复元素也很多。如果只是放下面这段代码到你的页面,会更好:
<div class="field">This is field 1</div> <div class="field">This is field 2</div> <div class="field">This is field 3</div> <div class="field">This is field 4</div> <div class="field">This is field 5</div>
我们需要做的只是使用jQuery做一点点处理,把之前那些需要重复的的HTML代码加进来,像这样:
$(document).ready(function() {
$('.field').before('<div class="fieldOuter"><div class="inner">');
$('.field').after('</div><div class="errorBar"><div class="icon">
<img src="icon.png" alt="icon" /></div><div class="message">
<span>This is an error message</span></div></div></div>');
});
不建议经常使用这个技巧,使用了它,在页面载入时会有闪烁的现象,但在有很多重复的HTML元素的情况下,这个技巧能有效地减小你页面的大小,对SEO也有好处,因为除去了很多重复无关的元素。
译者注:如果要考虑向后兼容,即考虑没有javascript的浏览器,任何情况下都不应该这样使用。
17.通过延迟加载内容提高速度和SEO友好度
还有另一个方法,可以加快页面载入,使爬虫蜘蛛抓取的页面更整洁,就是在页面其他部分载入完成后,再用AJAX载入内容。用户能看到正常的一面,爬虫蜘蛛也能只抓取到你想让它抓取的内容。
我们已经在自己的网站上使用这个技巧了,上面那些紫色的按钮能打开3个表单,一个导航和一个google map,这些都会让页面大小加倍,所以,我们把上面那些全部放在一个静态的HTML文件里,当页面读取完毕时再使用load()读取这个文件获得这部分元素,像这样:
$('#forms').load('content/headerForms.html', function() {
// 内容读取完毕时执行这里的代码,只执行一次
// 把所有事件处理程序都放这里
});
我不会到处使用这个技巧,你应该考虑它的优缺点,它会增加对服务器的请求,你的页面刚打开时载入的部分不能马上使用,但如果能正确地使用,它会是一个很好的优化技巧。
18.使用jQuery里的工具函数
jQuery里有很多实用的函数,填补了javascript的空白。
特别地,浏览器对javascript里一些数组函数的支持并不好(IE7甚至不支持indexOf()),jQuery有迭代、筛选、复制、合并和去除重复元素这一系列针对数组的函数。
其他在javascript很难实现的功能,像获取下拉列表的值,在传统javascript里,必须使用getElementById获取<select>元素,再获取它所有的子元素,迭代检查它们有没有selected,十分繁琐。而使用jQuery很容易就能获取:
$('#selectList').val();
很值得花一点时间仔细看看jQuery文档,探索那些相对少人知道的函数。
19.同时使用多个框架时,用noconflict重命名jQuery对象
大部分javascript框架使用符号$作为记号,当页面上使用了超过一个框架时,这会产生冲突。幸运的是有一个很简单的解决方法,nofonflict()函数让你能自定义jQuery的名字:
var $j = jQuery.noConflict();
$j('#myDiv').hide();
20.怎样提示图片已经加载完毕
这个问题似乎没有怎么被提及到,但这在做相册的时候是很常见的问题,其实这个问题很简单。
你需要做的只是在<img>标签上使用.load()函数,给它一个回调函数。下面的例子改变了<img>标签的”src”属性,载入一张新的图片,并为它加了一个简单的load()函数。
$('#myImage').attr('src', 'image.jpg').load(function() {
alert('Image Loaded');
});
你会发现图片载入完毕时提示框会弹出。
21.总是使用最新版本
jQuery一直在改进,它的创建者John Resig一直在寻找方法改进jQuery性能。
jQuery现在的版本是1.2.6(翻译时已经是1.3.2),但john透露它在开发一个新选择器引擎:Sizzle 。它能提升选择器的效率,在firefox里能达到4倍。所以,应该使用最新版本以获得更好的性能。
译者注:sizzle引擎已经开发完成,jquery1.3已经使用此引擎,sizzle主页:http://sizzlejs.com/
22.怎样检查元素存在
在你操纵一个元素前你不需要检查那个元素是否存在,因为如果你选择的元素不在DOM里jQuery不会做任何事。但如果你需要检查是否有元素被选择了,或者检查有多少个元素被选择,你可以使用length属性。
if ($('#myDiv).length) {
// 你的代码
}
很简单,但并不易见。
23.用js向HTML标签添加一个class属性
我是从Karl Swedberg的两本书 (1) (2) 里学到这招。
他在我最近的一片文章的评论里提到这个技巧,它的原理是这样的:
首先,jQuery加载完成后用它为<HTML>标签增加一个名为”JS”的class属性:
$('HTML').addClass('JS');
因为这只会在javascript可用的情况下发生,所以你可以利用它添加只有javascript可用时才有的css属性,像这样:
.JS #myDiv{display:none;}
这意味着,当javascript可用时我们可以隐藏一些内容,再在需要时用jQuery让它显现,而javascript不可用时(以及搜索引擎抓取页面时),内容并没有隐藏,用户能正常看到那些内容。我会在以后经常使用这个技巧。
可以来这里读取Karl Swedberg关于这个例子的全文:
24.返回”false”阻止默认行为
这可能是显而易见的,但有时候却不是,如果你习惯这样做:
<a href="#" class="popup">Click me!</a>
然后给它绑定一个事件,像这样:
$('popup').click(function(){
// Launch popup code
});
它会很好的工作,直到你在一个长页面使用它,才会发现问题,你会发现”#”使鼠标点击它时自动返回页面顶部。
你需要做的是阻止它的默认行为,在事件处理函数里添加”return false”可以阻止任何事件的任何默认行为:
$('popup').click(function(){
// Launch popup code
return false;
});
25.缩写ready事件
这是个很小的技巧,可以通过缩写函数$(document).ready为你腾出几个字节的空间。
可以把
$(document).ready(function (){
// your code
});
缩写成这样:
$(function (){
// your code
});
后话
终于翻译完了,好长的文章,真佩服他这么有耐性写这么长的文章。似乎我耐心还是不够,一口气是翻译不了那么长的,分了好几个次。第二部分代码还没排版,没有缩进,以后再修改。
原文链接:Improve your jQuery – 25 excellent tips
jquery是令人惊叹的框架,我已经使用它一年多了,我发觉使用它的时间越长,就会越喜欢它,也越理解它内部的工作原理。
我不是一个jquery专家,我也不奢求成为专家,所以如果这篇文章里出现一些错误我非常乐意接受大家的批评和改正。
我常常称自己为jquery中级使用者,我一年以来学到的、总结出来的技巧和技术,应该可以让一些人从中获益。
1.从google code载入jquery
Google挺久以前就开始提供各种javascript库供使用者载入,从google载入javascript框架相对于直接从自己的服务器载入有许多优势,首先它节省了自己服务器的带宽,从google载入也十分快,最重要的是如果用户之前已经访问过其他从google载入javascript库的网站,再访问你的网站时直接从缓存里取出即可,无需再次请求,会大大加快载入速度。
这很有意义,有多少网站储存着同一个版本的jquery呢,它们都没有被缓存。从google载入jquery是很容易做到的:
<script src=”http://www.google.com/jsapi”></script>
<script type=”text/javascript”>
// 载入jQuery
google.load(”jquery”, “1.2.6″);
google.setOnLoadCallback(function() {
//代码放这里
});
</script>
或者,你也可以直接包含jquery对应的网址,像这样:
<script src=”http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js” type=”text/javascript”></script>
完整的说明在这里
2.使用参考表(cheat sheet)
这不仅仅是个关于jquery的建议,对于很多语言,都有相应的很好的参考表,它很方便地把所有函数都列在可打印的A4格式的文档上,对于jquery1.2,下面这两个网址给出了两个很好的参考表:
http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/
http://colorcharge.com/jquery/
3.组合你所有的代码并压缩它们
嗯,这本来是一个普遍的javascript的建议,但任何使用jquery的大项目通常都会使用很多插件,所以这条建议也适用于jquery。
现在的浏览器不能同时载入几个脚本,这意味着如果你一次载入很多个脚本,会减慢载入网页的速度,所以,如果你的脚本需要载入到所有页面上,就可以考虑把你所有的代码放在一起,然后压缩它们。
有一些插件脚本已经被压缩过,你要考虑的是那些没有被压缩过的脚本。压缩脚本需要花费的时间很少,个人来说,推荐Dean Edwards制作的Packer这个工具。
4.使用firebug的控制台记录工具
如果你还没有安装firebug,那应该立即去下载。它除了提供其他一些常用的功能例如检查http传输和查找CSS错误外,还有优秀的控制台记录命令让你能轻易地检测脚本里的错误。
我个人喜欢的功能是“console.info”,它能输出信息或变量,代替了弹出窗口的alert,还有“console.time”让你轻易地在一段代码间设置一个计时器,得出执行这段代码所用的时间。这些console命令都很容易使用:
console.time('create list');
for (i = 0; i &lt; 1000; i++) {
var myList = $('.myList');
myList.append('This is list item ' + i);
}
console.timeEnd('create list');
这个例子我故意写了一些效率很低的代码,在接下来几条技巧/建议里,我会说明如何使用这个计时器展示代码的改进。
5.通过暂存减少选择器的使用
jquery选择器让人赞叹,它以难以置信的简单方式选择页面上任何元素,但在其内部,选择器需要做大量的工作,所以如果大量使用选择器,你会发现程序开始变得很慢。
如果你多次地选择同一个元素(例如在一个循环里),你可以只选择它一次并赋给一个变量,再在你的核心代码里使用它。下面这个例子我们通过循环添加元素到一个无序列表里。
for (i = 0; i &lt; 1000; i++) {
var myList = $('.myList');更能描述问题
myList.append('This is list item ' + i);
//译者注:我觉得直接用$('.myList').append('This is list item ' + i),去掉myList更能说明问题
}
这在我的电脑里用firefox3花费了1066毫秒(想象下如果是IE6将会是多长时间!),这在javascript来说是很慢的。现在我们看看下面的代码,只使用选择器一次:
var myList = $('.myList');
for (i = 0; i &lt; 1000; i++) {
myList.append('This is list item ' + i);
}
只花费了224毫秒,快了4倍多,只是移动了一行代码。
6.减少DOM处理
通过减少插入DOM的次数,我们可以让刚才那个例子运行得更快。DOM插入操作像.append().prepend().after()和.wrap()都相对地更耗费资源,如果运行很多DOM插入处理会让网页变得很慢。
我们需要做的是使用字符串连接建立列表,然后使用函数把列表一次性添加到无需列表上,使用.html()会更快,看看下面的例子:
var myList = $('#myList');
for (i=0; i&lt;1000; i++){
myList.append('This is list item ' + i);
}
在我的电脑里运行需要216毫秒,差不多1/5秒,但如果我们先建立一个字符串,再使用.html()插入,像这样:
var myList = $('.myList');
var myListItems = '';
for (i = 0; i &lt; 1000; i++) {
myListItems += '&lt;li&gt;This is list item ' + i + '&lt;/li&gt;';
}
myList.html(myListItems);
用了185毫秒,虽然没有快多少,但还是节省了31毫秒。
7.插入DOM时包含所有内容在单个元素里
嗯,别问我为什么这样做(我一定会有更有经验的程序员可以解释)
上一个例子中我们通过.html()函数插入1000个元素到一个无序列表里。如果我们在插入前将它包含在一个UL标签里,然后将整个UL插入到另外一个标签(一个DIV)里,这样就只插入了一个标签,而不是1000个,这会让程序块很多,像这样:
var myList = $('.myList');
var myListItems = '&lt;ul&gt;';
for (i = 0; i &lt; 1000; i++) {
myListItems += '&lt;li&gt;This is list item ' + i + '&lt;/li&gt;';
}
myListItems += '&lt;/ul&gt;';
myList.html(myListItems);
只花费了19毫秒的时间,巨大的改进,比第一个例子快了50倍。
8.尽可能使用ID而不是class
jquery优秀的选择器使通过Class选择元素变得跟通过ID选择元素一样简单,让人比以前更放心大胆地使用class。但事实上最好还是使用ID而不是class,因为使用ID获取元素时,jquery使用了浏览器默认的方法(getElementByID)获取元素,这无需经过遍历元素即可找到所需要的元素,比通过class查找元素更快。有多快?让我们来看看。
我使用了前面的例子,并对它进行小小的改动,让每一个li元素都有class属性,然后通过循环选择每一个元素。
// 创建list
var myList = $('.myList');
var myListItems = '&lt;ul&gt;';
for (i = 0; i &lt; 1000; i++) {
myListItems += '&lt;li class="listItem' + i + '"&gt;This is a list item&lt;/li&gt;';
}
myListItems += '&lt;/ul&gt;';
myList.html(myListItems);
// 每一个元素都选择一次
for (i = 0; i &lt; 1000; i++) {
var selectedItem = $('.listItem' + i);
}
跟我想的差不多,我的浏览器卡住了,它使用了5066毫秒(超过5秒)。现在修改一下代码,给每一个元素一个ID代替class,然后做同样的事:
// 创建list
var myList = $('.myList');
var myListItems = '&lt;ul&gt;';
for (i = 0; i &lt; 1000; i++) {
myListItems += '&lt;li id="listItem' + i + '"&gt;This is a list item&lt;/li&gt;';
}
myListItems += '&lt;/ul&gt;';
myList.html(myListItems);
// 每一个元素都选择一次
for (i = 0; i &lt; 1000; i++) {
var selectedItem = $('#listItem' + i);
}
这段代码只需要61毫秒的时间,差不多快了100倍!
9.给你的选择器定一个范围
默认地,当你像#(“.myDiv”)这样使用一个选择器,页面上所有的DOM元素将会被遍历,去查找符合条件的元素,这将会十分耗资源。
jquery的选择函数提供了第二个参数:
jQuery( expression, context )
通过提供一个上下文参数给选择器,可以让选择的范围缩小在所提供的元素内,不需要遍历整个页面。
为了演示,让我们引用上一个例子的代码,创建1000个元素的无序列表,每个li标签都有class属性,循环选择每一个元素,像上一个例子所看到的,将会花费超过5秒的时间运行这段代码。
var selectedItem = $('#listItem' + i);
然后我为选择器增加了一个上下文参数,让它只在.myList元素里遍历,像这样:
var selectedItem = $('#listItem' + i, $('.myList'));
它仍然使用了3818毫秒的时间,因为选择class还是一个效率低的做法。但这已经比之前快了25%,而且只为选择器添加了一个上下文参数而已。
译者注:我想如果把上面的代码放在一个大页面里执行,效果会很明显。
10.使用jquery链
jquery最酷的特性之一就是它能把函数调用连接在一起,例如,如果你想转换某个元素的class,可以这样写:
$('myDiv').removeClass('off').addClass('on');
如果你像我的话,会在学习jquery的前5分钟就知道这个特性,但jquery链不仅仅是这样。
首先,它可以跨行运行(因为jquery=JavaScript),这意味着你可以像这样简洁地写代码:
$('#mypanel')
.find('TABLE .firstCol')
.removeClass('.firstCol')
.css('background' : 'red')
.append('&lt;span&gt;This cell is now red&lt;/span&gt;');
养成使用jquery链的习惯可以减少选择器的使用。
假设你想在某一个元素上执行几个函数,但其中有一个函数通过某种途径改变了元素本身,像这样:
$('#myTable').find('.firstColumn').css('background','red');
上面的代码首先选择了一个table,然后选择table里class为”firstColumn”的单元格填充红色。
假设我们现在想把所有class为”lastColumn”的单元格都填上蓝色。因为我们之前已经用find()函数把所有class不是”firstColumn”的单元格排除了,所以我们要再次使用选择器获取table元素,所以我们就不能使用jquery链了,是不是?其实不是,jquery还有一个end()函数可以让链恢复到未被改变的时的状态,这样就可以继续链接下去,像这样:
$('#myTable')
.find('.firstColumn')
.css('background','red')
.end()
.find('.lastColumn')
.css('background','blue');
创建一个有链接功能的jquery函数比你想象中的还要简单,需要做的只是在函数里修改完元素后返回它:
$.fn.makeRed = function() {
return $(this).css('background', 'red');
}
$('#myTable').find('.firstColumn').makeRed().append('hello');
简单不?
昨天被人叫去看了一个人的空间,突然有兴趣试试ACM。最近一直在看RIA相关的博客,了解了挺多,但开始怀疑自己有没有在进步。。网页相关方面 是进步了,但编程能力毫无疑问完全没长进,在没有实践的日子里,做下纯编程的东西还是挺好的,算法、编程能力是基础~~做了即使没成绩也有好处没坏处。很 久没编程,昨晚那么一试,竟然试到我睡不着。。本来一个多小时做完没再碰了,但我的脑袋估计是太久没运转了,一下子过度使用,搞到要睡觉的时候还十分活 跃,睡不着。。。这题提交了4次才被Accepted。。看到这个单词挺有成就感的~~呵~~~也许我对这个会三分钟热度,随我喜好了~~呵呵。。
此题是problem 1088:System Overload,类似于以前在课本上看到的“一群孩子围成一圈数数出列”的一道题,自然是简单题~~
#include <iostream>
using namespace std;
int a[150];
int b[150];
int m,n=1,r,p,cn;
void init(){
for(int i=0;i<150;i++)
a[i]=0;
m=0;
r=0;
p=0;
}
void popAt(int num,int cn){
while(num<cn){
a[num]=a[num+1];
num++;
}
a[cn]=0;
}
int calculate(int n){
init();
while(r!=2){
for(int i=0;i<n;i++)
a[i]=i+1;
m++;
cn=n;
popAt(0,cn-1);
cn--;
p=m;
while(cn>1){
while(p>cn)
p-=cn;
popAt(p-1,cn-1);
cn--;
p+=m-1;
}
r=a[0];
}
return m;
}
int main()
{
int k=0;
while(n!=0){
cin>>n;
if(n==0) break;
if(n<3||n>150) return 0;
b[k]=calculate(n);
k++;
}
for(int j=0;j<k;j++){
cout<<b[j]<<endl;
}
return 0;
}
之前做完AIR账本程序的时候就想分享一下制作AIR的一些~~技巧吧~~因为网上有关AIR的教程实在太少。但后来没激情了,就罢了。今天一位网 友问我怎样把AIR的外观制作成我那种不规则形状的有点半透明的效果的。嗯~反正有空,就写个详细制作过程吧~~我是用FLEX3做的,至于在FLASH 里怎么做我就不知道了~~没试过~~~第一次写教程,难免表达等方面会有些问题,这个BLOG又不能插图,所以只有文字,不能图文并茂,看起来该会痛苦 点~~凑合着看吧。。
一、基础
打开FLEX3 新建一个AIR工程:File-New-Flex Project
输入工程名 在Application type处选择 Desktop application(runs in Adobe AIR) 直接点finish
打开这个工程所在的文件夹,默认是:我的文档/Flex Builder 3/工程名
打开src文件夹 拖张有透明效果的PNG图片进去。
因为不知道怎么直接在FLEX的工程面板里直接添加文件,所以我直接跑到文件夹去添加,知道的人知会一声啊~~~
接下来插入这张图片,在<mx:Application>标签内插入<mx:Image x=”0″ y=”0″ source=”bg1.png” id=”bgImage”/>
bg1.png是刚才那张PNG图片的文件名。
按CTRL+F11看下,图片是插入了 但有窗口 不透明,接下来就去掉窗口,让它透明。
二、透明
把<mx:WindowedApplication xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute”></mx:WindowedApplication>
改成<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute”></mx:Application>
因为只要是WindowedApplication就会有窗口出现,貌似是这样。。
在此标签内加入
<mx:Style>
Application
{
background-color:””;
background-image:””;
}
</mx:Style>
打开跟example.mxml在同一目录下的example-app.xml,是个配置文件。
里 面可以设置的所有属性都列好了,只是很多都用<!– –>注释掉了,按需求去掉注释添加属性。这里我们需要设置的是<initialWindow>里 的<systemChrome>、<transparent>和<visible>标签。去掉这三个标签的注释,在 这三个标签里分别输入none,true,true。结果就是这样:
<systemChrome>none</systemChrome>
<transparent>true</transparent>
<visible>true</visible>
也可以直接添加这三行到<initialWindow>标签里。
好 这时候按ctrl+F11看效果,已经是透明不规则窗体了。
三、拖动
但这窗体不能拖动,又没有关闭跟最小化按钮,现在我们来实现这些功能。
在mxml文件的<mx:Application>标签里插入如下语句:
<mx:scrīpt>
<![CDATA[
private function init():void{
bgImage.addEventListener(MouseEvent.MOUSE_DOWN, onStartMove)
}
//窗口最小化、关闭、拖动函数
public function minimizeWindow():void{
this.stage.nativeWindow.minimize();
}
public function closeWindow():void{
this.stage.nativeWindow.close();
}
public function onStartMove(event:MouseEvent):void{
this.stage.nativeWindow.startMove();
}
]]>
</mx:scrīpt>
再插入
<mx:Button click=”closeWindow();” x=”10″ label=”close” y=”10″ />
<mx:Button click=”minimizeWindow();” x=”100″ y=”10″ label=”min” />
到<mx:Image x=”0″ y=”0″ source=”bg1.png” id=”bgImage”/>后面,插入到前面的话按钮会没有响应,因为图片的鼠标事件优先了。。
再为<mx:Application>标签添加一个属性:applicationComplete=”init();” 结果是这样:<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” applicationComplete=”init();”>
代码很简单。程序运行完成的时候执行init()函数,函数里为bgImage就是刚才添加的png图片添加鼠标事件侦听,鼠标按下就开始移动。
下面两个按钮,不用多说~~基本功能就这样实现啦~~~
附:完整example.mxml和example-app.xml代码:
example.mxml:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” applicationComplete=”init();” width=”440″ height=”310″>
<mx:Style>
Application
{
background-color:””;
background-image:””;
}
</mx:Style>
<mx:scrīpt>
<![CDATA[
private function init():void{
bgImage.addEventListener(MouseEvent.MOUSE_DOWN, onStartMove)
}
//窗口最小化、关闭、拖动函数
public function minimizeWindow():void{
this.stage.nativeWindow.minimize();
}
public function closeWindow():void{
this.stage.nativeWindow.close();
}
public function onStartMove(event:MouseEvent):void{
this.stage.nativeWindow.startMove();
}
]]>
</mx:scrīpt>
<mx:Image x=”0″ y=”0″ source=”bg1.png” id=”bgImage”/>
<mx:Button click=”closeWindow();” x=”10″ label=”close” y=”10″ />
<mx:Button click=”minimizeWindow();” x=”100″ y=”10″ label=”min” />
</mx:Application>example-app.xml:
<?xml version=”1.0″ encoding=”UTF-8″?>
<application xmlns=”http://ns.adobe.com/air/application/1.0″>
<id>example</id>
<filename>example</filename>
<name>example</name>
<version>v1</version>
<initialWindow>
<content>[This value will be overwritten by Flex Builder in the output app.xml]</content>
<systemChrome>none</systemChrome>
<transparent>true</transparent>
<visible>true</visible>
</initialWindow>
</application>
这两天看AS3 cookbook和AS3的帮助文档,里面很多代码执行后都会出现“TypeError: Error #1009: 无法访问空对象引用的属性或方法。”这个错误。几经周折,才知道解决办法:使用addEventListener( Event.ADDED_TO_STAGE, enterDLHandle ),把要用的stage代码放到enterDLHandle里面,就没问题了。不知道有没有其他解决方法,知道的说声啊~
在经典论坛上提问这个问题,终于有人做出全面回答了,在此感谢zjs35
使用stage有下面几种方法:
1、文档类的构造函数中可以直接使用stage属性
2、非文档类可以通过参数传递到类里面。
class Test extends Shape
{
function Test(stage:Stage)
{
}
}
3、不想传递参数时,要注意代码的顺序。
class Test extends Shape
{
function Test()
{
}
functon useStage()
{
trace(stage)
}
}
这样使用
var test=new Test()
test.useStage()//null,你的问题出在这里
addChild(test)//添加到显示列表后,就可以使用stage属性。
test.useStage()//[object Stage]
总之,理解stage是显示对象的属性,位于显示列表中的显示对象的stage才引用舞台
当时是暑假,对AS很有热情,天天在钻研,当时距接触AS还不到20天的时间,这是我目前为止唯一一次参加练习活动。是初学者才能看啊!!
题目:用圆形公式画特效
内容:用纯AS画如下效果(可以是多边形,只要效果相似就行)
评论:
xx=1
a=550/2
b=400/2
r=100
_root.createEmptyMovieClip(“mc”,1)
with(mc){
moveTo(a+r,b)
lineStyle(1)
}
onEnterFrame=function(){
x=a+Math.cos(xx*Math.PI/180)*r//(PS.我到高二开学才知道为什么用三角函数能画出圆,原来是圆的参数方程~~)
y=b+Math.sin(xx*Math.PI/180)*r
mc.lineTo(x,y)
xx+=123//此处若是xx+=1的话就是典型的画圆~+120是正三角形,让它+123是为了在画三角形的时候有所偏转以至达到效果。
}
其中改一些变量就能改变效果。
为了效果多样,不妨多加几个变量。
xx=1
yy=1
a=550/2
b=400/2
r1=100
r2=100
_root.createEmptyMovieClip(“mc”,1)
with(mc){
moveTo(a+r1,b)
lineStyle(1)
}
onEnterFrame=function(){
x=a+Math.cos(xx*Math.PI/180)*r1
y=b+Math.sin(yy*Math.PI/180)*r2
mc.lineTo(x,y)
xx+=123
yy+=123
r1=Math.sin(xx*Math.PI/180)*100
r2=100
}
改变其中的 xx yy r1 r2就能达到不同的效果:
效果文件已被删~