隐藏滚动条

2012/07/17 · tech · front end

与 OSX Lion 原生的滚动条相比,Firefox 以及Windows下的滚动条就显得惨不忍睹了,有时我们想让它干脆不显示。W3C有关滚动条方面的标准几乎是没有,而且不是所有浏览器都能对滚动条进行自定义,我们只能另辟蹊径。

虽然说是隐藏,但是滚动功能还是要有的,否则 overflow: hidden 就可以了。在此我们采取的是用层遮罩的方式来实现。

首先要知道滚动条的宽度。由于JS中并没有直接获取滚动条宽度的方法,我们再耍一个小技巧:先生成一个不显示滚动条的元素块,计算其宽度,然后让其显示滚动条,则当前宽度跟原宽度的差值即是滚动条的宽度。感谢 alexandre 提供的跨浏览器的解决方案:

function getScrollBarWidth () {  
    var inner = document.createElement('p');  
    inner.style.width = "100%";  
    inner.style.height = "200px";

    var outer = document.createElement('div');  
    outer.style.position = "absolute";  
    outer.style.top = "0px";  
    outer.style.left = "0px";  
    outer.style.visibility = "hidden";  
    outer.style.width = "200px";  
    outer.style.height = "150px";  
    outer.style.overflow = "hidden";  
    outer.appendChild (inner);

    document.body.appendChild (outer);  
    var w1 = inner.offsetWidth;  
    outer.style.overflow = 'scroll';  
    var w2 = inner.offsetWidth;  
    if (w1 == w2) w2 = outer.clientWidth;

    document.body.removeChild (outer);

    return (w1 - w2);  
};

拿到滚动条宽度后,我们利用外部块级元素的overflow: hidden;属性将内部元素超出的部分隐藏掉。可使用margin或者手动调整内部元素宽度的方式来改变内部元素滚动条相对于外部元素的位置。

需要注意的是,OSX Lion Webkit内核的滚动条是悬浮在文本框之上的,因此宽度是零。好在我们可以通过设置CSS伪类的方式来达到目的。

<head>
    <style type="text/css">
        #mask {
            overflow: hidden;
            width: 200px;
            height: 200px;
        }
        #wrap {
            width: 100%;
            height: 100%;
            background-color: #D8D7CF;
            overflow-y: scroll;
        }
        #wrap::-webkit-scrollbar, #wrap::scrollbar {
            width: 0;
            height: 0;
        }
    </style>
</head>
<body>
    <div id="mask">
        <div id="wrap">
        </div>
    </div>
    <script type="text/javascript">
        document.getElementById("wrap").style.marginLeft 
            = getScrollBarWidth() + "px"
    </script>
</body>

大功告成。原生的滚动条不见了,通过监听元素的 scroll 事件我们可以自定义的各种样式的滚动条。

胡杨

2012/06/19 · life

胡杨是我在火车上认识的一位52岁的阿姨。阿姨年轻时去过新疆,“胡杨”是她的网名。

阿姨跟我是老乡,生活在皖北的一个三线城市里。去上海的火车上我住中铺,她住下铺。我见阿姨面相和善,在帮她将行李箱放在行李架上之后,便盘腿坐在对面的下铺上跟她聊上两句。

得知她的火车票是自己在网上订的之后,我表示诧异,再知道她为了订到下铺,两次取消订单,第三次成功订到,发现她对网上订火车票比我了解的还多(我没想过订完后看上中下铺,也不知道每天有两次取消订单的机会),我很佩服,接着攀谈起来,之后我所了解的就让我大吃一惊了:

  1. 阿姨自己网上买的火车票/飞机票,并在网上查找地铁、公交等换乘路线,并用百度知道来对具体行程进行提问
  2. 熟练使用淘宝、当当等网购网站,生活中大部分商品均是通过网络购买
  3. 懂得淘宝网的商业模式!知道沉淀的现金流是淘宝盈利的主要途径
  4. 懂得通过 URL 来辨别钓鱼网站,有基本的防骗、放钓鱼经验
  5. 尝试性投资黄金,了解金价和美元/欧元的正负相关性,于是在美国副总统拜登访华、法国总统萨克齐访华之前均对金价的波动做出了准确的预估
  6. 对目前国内的社会保障、医疗保障、教育体系的不足有明确的认识
  7. 谈政治,对党内政治斗争和宣传手段有一定的认识,熟悉敏感词,意外的是阿姨是 BO 的粉丝
  8. 从亲友那里了解欧美生活的基本形态,对欧美的基本法律、税收等制度有一定了解
  9. 好学,经常网上查资料、看帖到很晚,夜猫子一枚

对于这样有趣的人我绝不放过:D 我们在车厢关灯后继续聊到了接近12点,最终由于对面下铺女孩的抗议才终止,当然意犹未尽,第二天早起又接着聊起来了……

52岁了,阿姨并没有像身边大多数同龄人一样,或纠缠于家长里短,或闭塞无知而浑浑噩噩的活着。

为她的人生喝彩。

Morse IM

2012/06/11 · tech

数月前无意看到TeleTweet这个APP,这是一个Twitter客户端,富有创意的是它允许使用者以发电报的方式来发推。TeleTweet提供了一个精致的模拟电报机,你只需按照摩尔斯电码轻敲屏幕上的模拟电键,一个个英文字码便蹦出来,绝妙。

联想到Charles Petzold在《编码的奥秘》一书中所描述的两个小朋友通过手电筒交流的场景,我萌生了这样一个APP的想法:通过智能手机上的闪光灯实现“光通信”聊天 :P

使用方式很简单,A首先输入一段英文,点击发送,然后将手机的闪光灯一册面向B,程序将文字转换为摩尔斯码,并控制闪光灯的闪烁。而B只需将自己的摄像头对着A,则程序自动将闪烁的光点翻译为文字展示出来。如此反复,便可实现基本的IM功能。

程序的关键技术也应该不复杂,把文字编码为有规律的闪烁这个比较简单,而将闪烁还原成文字则需要一些专业知识。以我有限的图像处理知识来看,只需定时抓取摄像头的图像,灰度化之后寻找区域亮度的峰值,然后将连续的数据模拟化处理,便可大致还原成摩尔斯码的“嘀”和“嗒”,也就解码了文字。

当然这样的APP是没有什么实用价值的,但却非常有意思。我目前没有更多的时间做个Demo出来,图像处理的知识也很有限,如果有人有兴趣做一个出来,我当第一个用户:D

Reflekt

2012/05/19 · python · project

公司之前有做过类似Q卡的项目,现在不做了,于是闲置下来很多机器,就是一般挂在电梯里或者便利店里的那种。于是团队决定拉回来几个放在办公室玩玩。

机器有上下两个屏幕,下面的可触摸,系统是Ubuntu,我便想在这个上面可以玩点什么。想到之前在iOS上玩过一个叫Reflekt的游戏,属于消除类,移动方块使得与镜面中的元素一致即可消除。而我们的机器有两个屏幕,正好可以当作镜面,于是我就想模拟一个出来放在上面玩玩。

写Linux上的游戏我自然想到Pygame,一个Python的2D游戏库,使用起来颇为简单,而且游戏本身也不复杂,所以实现起来还算容易。

唯一复杂的部分在于,游戏窗口一般无法使用多线程来实现多窗口,只能通过多进程的方式,于是我需要开启两个相同的进程,一个作为主窗口,处理输入,并将相应的命令传递个另外一个窗口。而处理用户输入与发送命令之间需要异步操作,因此主进程中要开一个单独的线程来发送命令。将主进程接收的命令并传递到发送线程,采用Python内置的Queue队列实现,于是一个小小的程序,因为要多一点点多进程的交互,变得稍显复杂了起来。大致框架如下

 +----------------------------+         +-----------------------------+
 |        Main Process        |         |       Mirror Process        |
 +----------------------------+         +-----------------------------+
 |     +----------------+     |         |                             |
 |     |   User Input   |     |         |                             |
 |     +-------+--------+     |         |                             |
 |             |              |         |                             |
 |             | Queue        |         |                             |
 |             v              |         |                             |
 |     +----------------+     |         |     +-----------------+     |
 |     |                |     |         |     |                 |     |
 |     |                |     | socket  |     |                 |     |
 |     | Sender Thread  +-------------------> | Receiver Thread |     |
 |     |                |     |         |     |                 |     |
 |     +----------------+     |         |     +-----------------+     |
 +----------------------------+         +-----------------------------+

目前还不完善,接下来要实现自动识别游戏结束,加入无尽模式。放在Github上,有兴趣可以瞧一瞧。

电池技术需要一场革命

2012/05/15 · tech

上个礼拜,同事拿回来一台 The new iPad, 新搭载的Retina屏幕着实惊艳,翻阅书籍、杂志的感觉舒服的不得了,可美中不足的是,甚至可以说深深遗憾的是:仍然太重了。

原因很简单:电池由上一版本的25Whr上升到了42.5Whr,容量足足提升了70%。实际上屏幕、处理器、主板等部件的重量和体积已经到达了合理的水平,而从iPad背部拆解图来看,3大块电池霸道的占据了绝大部分空间,有点惨不忍睹。

大部分情况下iPad是最好的平板,这一点毫无疑问,但从一代以来就有的一个问题是,因为太重,不适合长时间手握,所以也就无法像Kindle那样随身携带,人们更多的是把iPad放在支架上,或者用身体的某个部位支撑着,才能长时间的使用,否则一定是累得手酸臂痛。

问题不是现在才有,随着移动计算设备的流行,它们承载了过多的功能,用户对更强处理器、更清晰屏幕的需求导致设备耗电速度急速上升。早期手机的电量一般可用3-5天,现在最流行的iPhone/Android手机一般只能使用1天,尤其是出货量最大的Android,如果您再玩点游戏,可能连一天也支撑不了,这还是在电池容量翻一翻甚至翻两翻的情况下。

试想如果电池可以做到轻薄容量大,会发生什么事呢?iPad只有目前的一半厚度,且重量跟一个大号手机差不多,我想这下没人不愿意在自己的包里腾出点空间给iPad了吧;手机充电一次可以使用起码一个月,背包客就不用发愁手机充电的事了。

再想点别的,床头的台灯从此抛弃电线,随便把它拿到哪儿;甚至汽车也充电就跑,不用加油站了⋯⋯

如此种种必将对现有的工业产品产生极大的影响,甚至可能催生出划时代的电子产品,称之为一场革命也并不为过。