Monthly Archives: June 2011

一个提供Mash-up Service的站点本身是否应该以Mash-up方式建立?

一个提供Mash-up Service的站点本身是否应该以Mash-up方式建立? 也就是说facebook站点里面的like button也是通过iframe或者xfbml包含进来的?

我看了一下facebook,它没这样搞; twitter呢,现在连不上,等下再研究

我们可以分析它的好处和坏处

1.好处:

  a. HTML代码只写一套,相应的校验、展现逻辑,如果有的话,也只需写一套

  b. 确保第三方站点嵌入的mash-up的页面风格和原站点(如facebook)一致

2.坏处:

  a. 每mash一个页面,就是一个http request; 如果一个主页要mash 30个页面,性能可能会很糟糕

  b. 页面设计将处处掣肘,要使它既符合本站,又符合mash站点,这比较难

有个折衷的办法是“服务端包含”。 mash站点通过html包含一个对mash-up的URL请求,而本站则的主页则包含mash-up的jsp。当然,这个也不能玩过火,如果一个button都包含,则灵活性就会差了。

Mash-up Service中一些常见的usability问题

我遇到的usability问题有这些:

   1. iframe中的页面变大后,会出现滚动条

   2. 被嵌入的按钮被点击,或者被嵌入的表单被提交后,在原位置应该显示什么东西?

   3. 被嵌入页面代表一个web flow操作(wizard),web flow进行到一半时,用户刷新浏览器会导致web flow从头开始

1.
iframe里的页面内容变多导致滚动条

  这种情况一般出现在表单提交时。iframe的大小以表单页面的大小为准,而提交后的结果页面又比大表单页面大的多

  解决办法有:

    a. 提供一个宽高的参考值,建议用户采用

    b. Mashup消费者不指定宽高,而让服务端根据结果页面的大小自动设定。这时候Mashup消费者一般不会直接写iframe,而是通过服务端现成的javascript来构建自己的widget.

2.
提交后该显示什么结果

  提交后的结果页面应该与表单页面具备相当的信息量。如果结果页面只显示“提交成功”几个字,会让用户觉得很奇怪。

  按照我对facebook和twitter的观察,大概有以下几种方式: 

    1. 表单页面即结果页面,结果页面即表单页面。比如facebook的 like button,既提供一个按钮让人点,同时按钮本身上的图案也表征当前的like状态。facebook的comments是另一个例子。这个widget的上方是一个评论输入框,而下方则是最近最新几条评论,所以它既适用于表单页面,又适于结果页面。

    2. 提交后强行跳转到第三个页面,规避这种问题。facebook的register plugin就是这样,等你注册后,不允许再呆在原页面。

    3. 只准嵌入按钮,不准嵌入页面,也可以规避这种问题。Twitter就是这样干的。用户点了按钮后,浏览器就会弹出一个窗口,然后在窗口里完成未竞的事业; 虽说twitter也可以嵌入比较大的widget,但点击widget中的每个按钮,都会弹出窗口。

3.
被嵌入页面中的web flow被用户的刷新动作中断

  一个超过三个页面的web flow执行一半时,如果用户按了一下F5刷新浏览器,那被嵌入的iframe就会显示这个flow的第一个页面,用户辛辛苦苦填入的数据就会化为乌有。

  目前我还没发现一种银弹式的解决方案。不过twitter的简单风格可以帮你化解这个问题。前面说了,twitter所有的表单、结果页面都不希望被嵌入,而是作为弹出窗口使用的。弹出窗是独立的,这样就不存在刷新主窗口导致子窗口从头开始的问题。

Facebook的 Mash-up Service的集成方式

两种方式:

  1. iframe

  2. XFBML

1.
iframe

<iframe src="http://www.facebook.com/plugins/like.php?href=google.com"
        scrolling="no" frameborder="0"
        style="border:none; width:450px; height:80px"></iframe>

2.
XFBML

<script src="http://connect.facebook.net/en_US/all.js#appId=APP_ID&amp;xfbml=1"></script>
<fb:comments href="example.com" num_posts="2" width="500"></fb:comments>

它实际上还是会生成一个iframe

Twitter 的 Mash-up Service的集成方式

Twitter 的 UI Mash-up Service可分为三大块:

  1. Web Intents  — 一些链接,点了就能产生twitter的内容

  2. Button       — 你的页面上将看到一些Button

  3. Widget       — 你的页面上将看到一些widget,点其中的按钮或链接后将弹出新页面

下面逐个介绍一下这三类Service,重点将放在集成方式上(js or iframe, 页面大小等)

1.
Web Intents

Web Intents就是指向twitter网站一些特定内容的链接

<p><a href="http://twitter.com/intent/tweet?in_reply_to=51113028241989632">Reply</a></p>
<p><a href="http://twitter.com/intent/retweet?tweet_id=51113028241989632">Retweet</a></p>
<p><a href="http://twitter.com/intent/favorite?tweet_id=51113028241989632">Fav</a></p>

不过,twitter建议以pop-up的方式使用这些链接,并让弹出窗口的大小保持在550 * 420

你可以手动实现这种方式,也可以使用twitter提供的out-of-box支持:引入http://platform.twitter.com/widgets.js

<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
<p><a href="http://twitter.com/intent/tweet?in_reply_to=51113028241989632">Reply</a></p>
<p><a href="http://twitter.com/intent/retweet?tweet_id=51113028241989632">Retweet</a></p>
<p><a href="http://twitter.com/intent/favorite?tweet_id=51113028241989632">Fav</a></p>

那用iframe行不行?

<iframe src="http://twitter.com/intent/tweet?in_reply_to=51113028241989632"/>

我试了一下,第一个页面的展现没有问题,但如果在iframe里玩tweet时,很容易出现窗口大小问题和滚动条等问题。所以Twitter并不推荐这种做法:“While you can provide links to intents within IFRAMEs and widgets, the resultant pages cannot be loaded in an IFRAME.”

2.
Button

顾名思义,就是可以在你的网页上产生一个Twitter按钮。你可以通过三种方式集成这种按钮。

a.链接

<style type="text/css" media="screen">
  #custom-tweet-button a {
    display: block;
    padding: 2px 5px 2px 20px;
    background: url('http://a4.twimg.com/images/favicon.ico') 1px center no-repeat;
    border: 1px solid #ccc;
  }
</style>
<div id="custom-tweet-button">
  <a href="http://twitter.com/share?url=http%3A%2F%2Fdev.twitter.com%2Fpages%2Ftweet-button" target="_blank">Tweet</a>
</div>

b.javascript

<script src="http://platform.twitter.com/widgets.js" type="text/javascript"></script>
<a href="http://twitter.com/share" class="twitter-share-button">Tweet</a>

它的本质是通过javascript生成一个面积很小的iframe

c.iframe

 <iframe allowtransparency="true" frameborder="0" scrolling="no"
        src="http://platform.twitter.com/widgets/tweet_button.html"
        style="width:130px; height:50px;"></iframe>

点一下按钮,会跳到或弹出twitter相关页面,提示你执行操作,操作完合再回来

这个就不如facebook的like button。点like button时会触发ajax请求,勿需渲染新页面

3.
Widget

通过javascript在你的页面中渲染出一个窗体,里面放了几个链接

 
<script src="http://widgets.twimg.com/j/2/widget.js"></script>
<script>
new TWTR.Widget({
  version: 2,
  type: 'profile',
  rpp: 4,
  interval: 6000,
  width: 250,
  height: 300,
  theme: {
    shell: {
      background: '#333333',
      color: '#ffffff'
    },
    tweets: {
      background: '#000000',
      color: '#ffffff',
      links: '#4aed05'
    }
  },
  features: {
    scrollbar: false,
    loop: false,
    live: false,
    hashtags: true,
    timestamp: true,
    avatars: false,
    behavior: 'all'
  }
}).render().setUser('chenjianjx').start();
</script>
 

点里面的链接,一般会弹出新窗口

注意,这个新产生的窗体并不是一个iframe,而仅仅是一个div. 上面的代码会强行在页面内插入div和其相关的css

List 与 null 的故事

把 null 加到 list里会怎么样?

        List<String> list = new ArrayList<String>();
        list.add(null);
        list.add(null);

        print(list.size());  //将打印:2

        list.remove(null);
        print(list.size());  //将打印:1

随贴附送“清除null”的java方法

    static <T> List<T> getNonNullElements(List<T> list){
        List<T> resultList = new ArrayList<T>();
        for(T t: list){
            if(t != null){
                resultList.add(t);
            }
        }
        return resultList;
    }

开源框架的出错信息经常会有误导性

很多开源框架,包括高质量的hibernate, spring等,有时给出的出错信息都会有误导性。

错误实际是在A部分,框架却把错报在B部分。

这种情况下,你可以试着把你的改动先减到最低,测一下;再逐渐一步一步加回来,加一步,测一步。这样就可以定位到出错的原因