又给Vejis添新东西了, 所以说有需求才有动力啊

再为腾讯的比赛写程序, 话说这个程序本身没什么难度, 就是普通的富JS页面的网页而已, 要比的有两点, 一个是主题, 一个是UI. 不过难度在我刚开始两天, 还有不到十天的时间. 虽然说貌似不用在那之前作出成品, 但半成品总得有吧.

后台选择的是PHP, 我最恨的一种脚本, 哪有什么语法, 纯粹就是堆砌! (PHPer莫生气)

那说下今天给vejis添加/改变的内容.

1. enum_ 用法如下:

var Option = enum_(“abc”, “def”, “ghi”);
//Option.abc instanceof Option == true

2. static_/public_/private_这个是针对类的, 例子如下:

var Class = class_(function (pub, pri) {
    this._(function () {
        //pub.test1 == “123”
        //pri.test2 == “321”
    });
}).static_(function () {
    this.public_(function () {
        this.test1 = “123”;
    });
    this.private_(function () {
        this.test2 = “321”;
    });
});

//Class.test1 == “123”
//Class.test2 == undefined

3. Typed Dictionary, 例子如下:

var dict = new (Dictionary(Object, Integer))();
var o1 = {}, o2 = {}, o3 = {};
dict.set(o1, 123);
dict.set(o2, 456);
//dict.get(o1) == 123
//dict.get(o2) == 456
//dict.exists(o3) == false

JavaScript 阻止通过改变 window.location/window.location.href 实现的页面跳转

首先, 要说明的是, 这并非一个万能的方法. 兼容性:

经测试兼容的浏览器:
Firefox 4 / Chrome 11
IE 9 / Safari 5 (只对window.location有效, 对window.location.href报错)

经测试不兼容的浏览器:
IE 8- (据说蓝色的网友说Chrome 12+也不行, 未实测.)

其他浏览器的运行情况我就不清楚了.

下面进入正题. 首先要介绍的是在JavaScript 1.8.5中引入的一个接口:
Object.defineProperty(obj, prop, descriptor)

顾名思义, 就是定义属性. 然后要做的事情也很简单, 使用它来覆盖 window.location / window.location.href, 代码如下:

Object.defineProperty(window, “location”, { value: window.location, writable: false });
Object.defineProperty(window.location, “href”, { value: window.location.href, writable: false });
window.location = “http://www.vilic.info/”;
alert(window.location);

那, 就这样咯… 使用的时候try一下就好. 因为毕竟只是作为提高体验的代码, 实在不行还可以用beforeunload事件, 只是就会有窗口弹出了.

我想这个对于 “在浏览器里的浏览器” 会比较有意义. 比如WebQQ那个又丑又弱的浏览器… 不过我猜这个接口在其他地方一定还会大有用途, 哈哈.

JavaScript 完美实现文本框高度自适应 (绝对精确)

这是做ViT的时候遇到的问题, 按说应该是一个非常基础的问题, 因为遇到的情况应该也比较多, 但是很遗憾自己之前却没有一套有效的解决方案. 后来Google了很多, 不过效果并不理想.

后来到群里和众大大们讨论, 想到的第一个方案是用一个div装下textarea中的文本, 让各种相关样式相同, 这样div的高就应该是textarea的高了. 于是很快写了出来. 但因为毕竟一个是text, 一个是html, 各种转换也比较麻烦. 遇到了不换行的长文本(英文), 处理起来就更不方便了. 还有空格什么的处理. 比如 “abc abc” 这样, 中间是不会换行的, 如果替换两个空格为一个空格加一个 “ ”, 依旧有小问题, 具体就不说了.

说到这里, 大家可能会提出一个常见的方案, 也就是利用textarea自身的scrollHeight属性. 不错, 但是当textarea变高之后, 即使内容删掉, 也变不回原来的高度了. 但, 如果说, 一个textarea的高度很小, 那么scrollHeight不就一直都表示内容的高度了么? 这就是key所在了, 用div做副本不行, 我们可以用textarea啊!

最终代码如下:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head>
    <title>文本框高度自适应</title>
    <style type=”text/css”>
        #shadow, #text { font: 12px/16px Arial; width: 200px; overflow: hidden; height: 16px; }
        #shadow { position: absolute; border-width: 0px; padding: 0px; visibility: hidden; }
        #text { resize: none; }
    </style>
    <script type=”text/javascript”>
        /*
            文本框高度自适应
            by VILIC VANE
            Web www.vilic.info
            Email i@vilic.info
        */

        window.onload = function () {
            var text = document.getElementById(“text”); //用户看到的文本框
            var shadow = document.getElementById(“shadow”); //隐藏的文本框

            text.oninput = //非IE的
            text.onpropertychange = //IE的
            onchange;
           
            function onchange() {
                shadow.value = text.value;
                setHeight();
                setTimeout(setHeight, 0); //针对IE 6/7/8的延迟, 否则有时会有一个字符的出入
                function setHeight() { text.style.height = shadow.scrollHeight + “px”; }
            }
        };
    </script>
</head>
<body>
    <textarea id=”text”></textarea>
    <textarea id=”shadow”></textarea>
</body>
</html>

最新VT (JavaScript/HTA) SDK, 支持Twitter/腾讯/新浪微博, 支持图片

今天想着, 干脆就扩展了VT SDK的功能. 现在支持Twitter/腾讯/新浪微博, 并且支持发送图片 (限腾讯/新浪微博).

里面有3个Demo, 分别是twitter.hta, txweibo.hta, xlweibo.hta, 里面有简单的例子, 大家可以下载解压后双击执行.

下载地址 http://www.vilic.info/demo/vt.rar

在页面中添加以下脚本引用即可:

<script src=”script/crypto.js” type=”text/javascript”></script>
<script src=”script/sha1.js” type=”text/javascript”></script>
<script src=”script/hmac.js” type=”text/javascript”></script>
<script src=”script/vejis.js” type=”text/javascript”></script>
<script src=”script/vejis.api.js” type=”text/javascript”></script>

要是不嫌麻烦的话, 可以把上面的文件合并到一起, 不过我就懒得弄啦. 最后上个图, 就是其中的三个例子.

腾讯微博API之发送带图片的微博 (JavaScript/HTA)

今天 (严格地讲是昨天) 下午开始写发送图片的部分, 其实整个代码的结构都变了, 现在调用也更加方便.

注意, 本文所讲的JavaScript是指在HTA或者其他能够自由创建ActiveXObject对象的环境中的JavaScript, 并不是指普通权限的浏览器中运行的JavaScript.

发送图片等文件需要使用multipart/form-data类型的数据, 偷偷懒地话, 可以用form来提交, 但是想全程XMLHTTP, 就绕了下.

这次遇到的问题主要有两个, 然而这两个问题如果通过form来提交, 则都能轻松搞定.

第一个问题是字节文件的读取. 我使用了ADODB.Stream对象. 详细方法请Google或者参照我的代码.

第二个问题是multipart/form-data的boundary.

当时调用API的时候一直返回file size error这个错误. 一开始我一直以为是图片的问题, 毕竟它是说的file… 但后来, 下意识地修改了一些重要参数, 甚至直接点开API, 都是这个错误. 这才意识到, 或许参数根本没有成功传递.

一开始我使用xmlhttp发送的是string, 但貌似一闪而过, 没有 “上传” 的动作在其中, 毕竟文件也有些大小, 上传是需要一定的时间的. 这时开始就起了疑心, 后来改成了stream, 先把stream改成文本模式, 写入文本, 再改成字节模式, 写入文件内容, 再改回来, 再改过去. 如此反复后, 使用xmlhttp发送了这个stream. 这时总算是有点等待的意思了. 但之后的返回内容依旧提示file size error.

这里纠结了很久, 又去查了很多资料, 最后看到这样一个.

在程序中定义了一个变量boundary,大部分例子中这个boundary变量的起始字符是”–“,因为在HTTP消息体中要使用”–“,但是,如果这样定义,那么调用
xhr.setRequestHeader(‘Content-Type’, ‘multipart/form-data; boundary=’ + boundary);
设置HTTP消息头的时候,就将”–“也声明进去了,我发现在我的运行环境中这样不行,如果定义的变量boundary中没有起始字符”–“就可以了。当然此时要注意在整个消息的结尾需要在boundary字符串前后都加”–“,可以参照HTML规范构造符合规范的消息体。

说实在的我没读懂他的意思… 但是直觉告诉我, 难道是后面的分隔符必须在定义的boundary的基础之上, 前面再加一个 “–” ? 于是试了试… 于是成功了!

具体的操作我也不多说了, 感兴趣的话可以看我的代码.

http://www.vilic.info/demo/vt.rar