月度归档:2013年12月

CSS:IE,Chrome,Firefox兼容性和CSS Hack

hack列表(全部经笔者测试,均为标准模式下,混杂模式由于很少会用到所以未对其进行测试):

点击查看原图

其中粉红色部分为属性hack,黄色部分为选择器hack,它们可以结合使用。此外Firefox和Chrome也有它们专有的hack,详细hack方式及使

用示例如下:

Firefox:

@-moz-document url-prefix()    /*写在选择器外层时(只可写在此处):Firefox only*/

Chrome:

@media screen and (-webkit-min-device-pixel-ratio:0)    /*写在选择器外层时(只可写在此处):Chrome only*/

使用示例-写在选择器前面:

 

 

@-moz-document url-prefix()    /*Firefox*/

{

        body

        {

                background-color:pink;

        }

}

注意事项:

浏览器对css的解析是从前到后的,并且采用最后一个样式声明。

 还是不知道怎么区分.好吧,来看个例子:

<!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>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>区别IE6、IE7、IE8、FireFox的CSS hack - http://www.52css.com%3c/title>

<style type="text/css">

<!--

#test,#note{

    margin:0 auto;

    text-align:center;    

}

#test {

    width:200px;

    height:30px;

    border: 1px solid #000000;

    color:#fff;

    line-height:30px;

}

.color{

    background-color: #CC00FF;        /*所有浏览器都会显示为紫色*/

    background-color: #FF0000\9;    /*IE6、IE7、IE8会显示红色*/

    *background-color: #0066FF;        /*IE6、IE7会变为蓝色*/            

    _background-color: #009933;        /*IE6会变为绿色*/

}

-->

</style>

</head>

<body>

<div id="test" class="color">测试方块 www.mycsu.net </div>

<div id="note">

    <strong style="color:#009933">IE6</strong>

    <strong style="color:#0066FF">IE7</strong>

    <strong style="color:#FF0000">IE8</strong>

    <strong style="color:#CC00FF">FireFox</strong>

</div>

</body>

</html>

---------------------------------------------------------------------------------------------------

background: red;       /* 对FF Opera和Safari有效 */

#background: blue;      /* 对 IE6 和 IE7有效 */

_background: green;      /* 只对IE6有效 */

/*/background: orange;*/      /** 只对IE8有效 **/

!important         /*FF、IE7有效*/

*         /*IE都有效*/

============================================================

IE8是可以和IE7兼容的,简单一行代码,让IE8自动调用IE7的渲染模式

只需要在页面中加入如下HTTP meta-tag:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

只要IE8读到这个标签,它就会自动启动IE7兼容模式,保证页面完整展示。

 --------------------------------------------------

<!--[if lt IE 8]> <html class="no-js lt-ie9 lt-ie8" lang="en-us"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en-us"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en-us"> <!--<![endif]-->

条件注释参考:https://msdn.microsoft.com/en-us/library/ms537512%28v=vs.85%29.aspx

来源:http://www.cnblogs.com/wuchao/archive/2012/07/18/2596867.html

mobile check

if(/AppleWebKit.*Mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|ZTE/.test(navigator.userAgent))){
	if(window.location.href.indexOf("?mobile")<0){
		try{
			if(/Android|Windows Phone|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)){
				window.location.href="http://m.aooshi.com/";
			}else if(/iPad/i.test(navigator.userAgent)){
			}else{
				window.location.href="http://m.aooshi.com/simple/"
			}
		}catch(e){}
	}
}

js oauth_v1.0

/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FireUploader
*
* The Initial Developer of the Original Code is Rahul Jonna.
*
* Portions created by the Initial Developer are Copyright (C) 2007-2009
* the Initial Developer. All Rights Reserved.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

var SoundCloud = {};

(function()
{
    /**
    * USAGE:
    * 
    * @param {Object} loginUrl - The webpage url for login
    * @param {Object} apiUrl - The api end point
    * @param {Object} apiKey
    * @param {Object} secretKey
    * @param {Object} additionalParams - Additional parameters to send if any, like version number etc
    * @param {Object} afterAuthorizeCallback - callback function that is called after authentication
    *
    * var oAuth = new SoundCloud.OAuth("http://api.soundcloud.com/oauth/authorize", "http://api.soundcloud.com/", 
    *	"your_api_key", "your_api_secret", {"version": "1.0"}, function(oauthObj) {});
    * oAuth.startAuthentication(); 
    *	
    * At the end, oauthObj.accessToken and oauthObj.accessTokenSecret will have the access token and token secret respectively
    *
    */
    function x_OAuth(loginUrl, apiUrl, apiKey, secretKey, additionalParams, afterAuthorizeCallback)
    {
        this.loginUrl = loginUrl;
        this.apiUrl = apiUrl;
        this.apiKey = apiKey;
        this.secretKey = secretKey;

        this.requestToken;
        this.accessToken;

        this.requestTokenSecret;
        this.accessTokenSecret;

        this.afterAuthorizeCallback = afterAuthorizeCallback;
        this.userName;

        for (var key in additionalParams)
            this[key] = additionalParams[key];
    }

    x_OAuth.prototype = {

        //starts the authentication process	
        startAuthentication: function()
        {
            this.getRequestToken();
        },

        getParamString: function(params)
        {
            var arr = [], i = 0;
            for (var key in params)
            {
                arr[i++] = key + "=" + params[key];
            }
            return arr.join("&");
        },

        //encodes the special characters according to the RFC standard
        rfcEncoding: function(str)
        {
            var tmp = encodeURIComponent(str);
            tmp = tmp.replace('!', '%21');
            tmp = tmp.replace('*', '%2A');
            tmp = tmp.replace('(', '%28');
            tmp = tmp.replace(')', '%29');
            tmp = tmp.replace("'", '%27');
            return tmp;
        },

        //assigns the common parameters for all requests
        getCommonParams: function(params)
        {
            params = params || [];
            params["oauth_consumer_key"] = this.apiKey;
            params["oauth_timestamp"] = Math.ceil((new Date()).getTime() / 1000);
            params["oauth_nonce"] = (new Date()).getTime();
            params["oauth_version"] = this.version;
            if (this.format)
                params["format"] = this.format;
            params["oauth_signature_method"] = "HMAC-SHA1";

            return params;
        },

        getSecretKey: function(tokenType)
        {
            return this.secretKey +
			"&" +
			((tokenType == "beforeAuthentication") ? "" : ((tokenType == "request") ? this.requestTokenSecret : this.accessTokenSecret));
        },

        //makes the signature using SHA1 algorithm
        getSignature: function(method, url, paramString, tokenType)
        {
            var stringToSign = [this.rfcEncoding(method), this.rfcEncoding(url), this.rfcEncoding(paramString)].join("&");
            return Soundcloud.SHA1.b64_hmac_sha1(this.getSecretKey(tokenType), stringToSign);
        },

        //gets the request token
        getRequestToken: function()
        {
            var params = this.getCommonParams();

            var url = this.apiUrl + "oauth/request_token";
            var paramString = this.normalizeParams(params);
            var method = "POST";
            var signature = this.getSignature(method, url, paramString, "beforeAuthentication");
            paramString += "&oauth_signature=" + this.rfcEncoding(signature);

            Soundcloud.xhttp.doRequest(method, url, paramString, "", false, null, this, function(objResponse)
            {
                if (!objResponse.hasErrors)
                {
                    objResponse.responseText = Soundcloud.utils.trimWhitespace(objResponse.responseText) + "&";
                    var reg1 = /oauth_token=(.*?)&/gi;
                    var reg2 = /oauth_token_secret=(.*?)&/gi;
                    var arrToken = reg1.exec(objResponse.responseText);
                    if (arrToken)
                    {
                        this.requestToken = arrToken[1];
                        this.showLoginPage(arrToken[1]);
                    }
                    else
                        throw new Error("Failed to get request token");

                    var arrTokenSecret = reg2.exec(objResponse.responseText);
                    if (arrTokenSecret)
                        this.requestTokenSecret = arrTokenSecret[1];
                    else
                        throw new Error("Failed to get request token");
                }
                else
                    throw new Error("Failed to get request token");
            });
        },

        //get access token
        getAccessToken: function(token)
        {
            var params = this.getCommonParams();
            params["oauth_token"] = token;
            var url = this.apiUrl + "oauth/access_token";
            var paramString = this.normalizeParams(params);
            var method = "POST";
            var signature = this.getSignature(method, url, paramString, "request");
            paramString += "&oauth_signature=" + this.rfcEncoding(signature);

            Soundcloud.xhttp.doRequest(method, url, "", paramString, false, null, this, function(objResponse)
            {
                if (!objResponse.hasErrors)
                {
                    var tokenList = objResponse.responseText.split("&");

                    var reg1 = /oauth_token=(.*)/gi;
                    var reg2 = /oauth_token_secret=(.*)/gi;

                    var accessToken, tokenSecret;
                    var arrToken = reg1.exec(tokenList[0]);
                    if (arrToken)
                    {
                        this.accessToken = arrToken[1];
                    }
                    else
                    {
                        throw new Error("Failed to get access token. Check if your username and password is valid.");
                    }
                    var arrTokenSecret = reg2.exec(tokenList[1]);
                    if (arrTokenSecret)
                    {
                        this.accessTokenSecret = arrTokenSecret[1];
                    }
                    else
                    {
                        throw new Error("Failed to get access token. Check if your username and password is valid.");
                    }
                    if (this.afterAuthorizeCallback)
                    {
                        this.afterAuthorizeCallback.call(null, this);
                    }
                }
                else
                    throw new Error("Failed to get access token. Check if your username and password is valid.");
            });
        },

        //sorts the parameters and creats a GET string to be sent to the server
        normalizeParams: function(params)
        {
            for (var key in params)
                params[key] = this.rfcEncoding(params[key]);

            return Soundcloud.utils.join("&", "=", params, true);
        },

        //show the login page
        showLoginPage: function(token)
        {
            var doneAuthorizing = false;
            var callbackFunc = function(isDone)
            {
                doneAuthorizing = isDone;
            };

            var url = this.loginUrl + "?oauth_token=" + token;
            window.openDialog("chrome://fireuploader/content/loginPanel.xul", "Login/Authorization Panel", "chrome,centerscreen,modal,width=350,height=400", url, callbackFunc);
            if (doneAuthorizing)
            {
                this.getAccessToken(token);
            }
        }
    };

    this.OAuth = x_OAuth;

    this.utils = {
        join: function(separator1, separator2, arr, sort)
        {
            var arrKeys = [];
            for (var key in arr)
            {
                arrKeys.push(key);
            }
            if (sort)
                arrKeys.sort();

            var newArr = [];
            for (var i = 0; i < arrKeys.length; i++)
            {
                if (separator2 != "")
                {
                    newArr.push(arrKeys[i] + separator2 + arr[arrKeys[i]]);
                }
                else
                {
                    newArr.push(arrKeys[i]);
                    newArr.push(arr[arrKeys[i]]);
                }
            }

            return newArr.join(separator1);
        },

        // Remove leading and trailing whitespace from a string
        trimWhitespace: function(str)
        {
            return str.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
        }
    }

    this.xhttp = {
        //a wrapper to XMLHttpRequest object

        /**
        * @param {string} verb - GET, POST, PUT, DELETE
        * @param {string} resLoc - Url of the resource
        * @param {string} getData - Data that's sent in the url
        * @param {string} objData - Data that's sent during POST, PUT
        * @param {bool} isSync - whether to make a syncronous or asynchronous request
        * @param {Object} arrHeaders - array of headers(name, value pairs) that's sent in the request 
        * @param {Object} callbackObject - scope of the callback function
        * @param {Object} callbackFunc - callback function that's called after asyncronous response
        */
        doRequest: function(verb, resLoc, getData, objData, isSync, arrHeaders, callbackObject, callbackFunc)
        {
            try
            {
                var xmlhttp = new XMLHttpRequest();
                if (getData != "")
                    getData = "?" + getData;

                resLoc = encodeURI(resLoc);
                var aUrl = (resLoc.indexOf("http") == -1) ? this.host + resLoc + getData : resLoc + getData;
                xmlhttp.open(verb, aUrl, !isSync);

                if (verb == "POST")
                    xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');

                if (arrHeaders instanceof Array)
                {
                    for (var i = 0; i < arrHeaders.length; i++)
                    {
                        xmlhttp.setRequestHeader(arrHeaders[i].name, arrHeaders[i].value);
                    }
                }

                xmlhttp.send(objData);

                var domParser = new DOMParser(); //Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
                if (isSync)
                {
                    if (xmlhttp.status >= 200 && xmlhttp.status < 300)
                    {
                        try
                        {
                            var xmlDoc1 = domParser.parseFromString(xmlhttp.responseText, "text/xml");
                        }
                        catch (ex)
								{ }

                        var responseObject = {
                            responseText: xmlhttp.responseText,
                            xmlDoc: xmlDoc1,
                            strHeaders: xmlhttp.getAllResponseHeaders()
                        };
                        callbackFunc.call(callbackObject, responseObject);
                        return responseObject;
                    }
                    else
                    {

                        try
                        {
                            var xmlDoc1 = domParser.parseFromString(xmlhttp.responseText, "text/xml");
                        }
                        catch (ex2)
                        {
                            alert(ex2);
                        }
                        var errorMessage = "Error connecting! Try again - " + xmlhttp.status + " " + xmlhttp.statusText;

                        if (xmlDoc1 != null && xmlDoc1.getElementsByTagName("Message")[0])
                            errorMessage = xmlDoc1.getElementsByTagName("Message")[0].firstChild.nodeValue;

                        var responseObject = {
                            responseText: xmlhttp.responseText,
                            xmlDoc: xmlDoc1,
                            strHeaders: xmlhttp.getAllResponseHeaders(),
                            errorMessage: errorMessage,
                            hasErrors: true
                        };

                        callbackFunc.call(callbackObject, responseObject);

                        return false;
                    }
                }
                else
                {
                    xmlhttp.onreadystatechange = function()
                    {
                        if (xmlhttp.readyState != 4)
                            return;
                        else
                        {
                            if (xmlhttp.status >= 200 && xmlhttp.status < 300)
                            {
                                try
                                {
                                    var xmlDoc1 = domParser.parseFromString(xmlhttp.responseText, "text/xml");
                                }
                                catch (ex)
								{ }
                                var responseObject = {
                                    responseText: xmlhttp.responseText,
                                    xmlDoc: xmlDoc1,
                                    strHeaders: xmlhttp.getAllResponseHeaders()
                                };
                                callbackFunc.call(callbackObject, responseObject);
                            }
                            else
                            {
                                try
                                {
                                    var xmlDoc1 = domParser.parseFromString(xmlhttp.responseText, "text/xml");
                                }
                                catch (ex)
								{ }
                                var errorMessage = "Error connecting! Try again - " + xmlhttp.status + " " + xmlhttp.statusText;
                                if (xmlDoc1 != null && xmlDoc1.getElementsByTagName("Message")[0])
                                    errorMessage = xmlDoc1.getElementsByTagName("Message")[0].firstChild.nodeValue;

                                var responseObject = {
                                    responseText: xmlhttp.responseText,
                                    xmlDoc: xmlDoc1,
                                    strHeaders: xmlhttp.getAllResponseHeaders(),
                                    errorMessage: errorMessage,
                                    hasErrors: true
                                };
                                callbackFunc.call(callbackObject, responseObject);
                            }
                        }
                    }
                }
            }
            catch (ex)
            {
                alert(ex);
            }
        }
    }

    this.SHA1 =
    {
        /*
        * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
        * in FIPS PUB 180-1
        * Version 2.1a Copyright Paul Johnston 2000 - 2002.
        * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
        * Distributed under the BSD License
        * See http://pajhome.org.uk/crypt/md5 for details.  
        */

        /*
        * Configurable variables. You may need to tweak these to be compatible with
        * the server-side, but the defaults work in most cases.
        */
        hexcase: 0,  /* hex output format. 0 - lowercase; 1 - uppercase        */
        b64pad: "=", /* base-64 pad character. "=" for strict RFC compliance   */
        chrsz: 8,  /* bits per input character. 8 - ASCII; 16 - Unicode      */

        /*
        * These are the functions you'll usually want to call
        * They take string arguments and return either hex or base-64 encoded strings
        */
        hex_sha1: function(s) { return this.binb2hex(this.core_sha1(this.str2binb(s), s.length * this.chrsz)); },
        b64_sha1: function(s) { return this.binb2b64(this.core_sha1(this.str2binb(s), s.length * this.chrsz)); },
        str_sha1: function(s) { return this.binb2str(this.core_sha1(this.str2binb(s), s.length * this.chrsz)); },
        hex_hmac_sha1: function(key, data) { return this.binb2hex(this.core_hmac_sha1(key, data)); },
        b64_hmac_sha1: function(key, data) { return this.binb2b64(this.core_hmac_sha1(key, data)); },
        str_hmac_sha1: function(key, data) { return this.binb2str(this.core_hmac_sha1(key, data)); },

        /*
        * Perform a simple self-test to see if the VM is working
        */
        sha1_vm_test: function()
        {
            return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
        },

        /*
        * Calculate the SHA-1 of an array of big-endian words, and a bit length
        */
        core_sha1: function(x, len)
        {
            /* append padding */
            x[len >> 5] |= 0x80 << (24 - len % 32);
            x[((len + 64 >> 9) << 4) + 15] = len;

            var w = Array(80);
            var a = 1732584193;
            var b = -271733879;
            var c = -1732584194;
            var d = 271733878;
            var e = -1009589776;

            for (var i = 0; i < x.length; i += 16)
            {
                var olda = a;
                var oldb = b;
                var oldc = c;
                var oldd = d;
                var olde = e;

                for (var j = 0; j < 80; j++)
                {
                    if (j < 16) w[j] = x[i + j];
                    else w[j] = this.rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
                    var t = this.safe_add(this.safe_add(this.rol(a, 5), this.sha1_ft(j, b, c, d)),
						    this.safe_add(this.safe_add(e, w[j]), this.sha1_kt(j)));
                    e = d;
                    d = c;
                    c = this.rol(b, 30);
                    b = a;
                    a = t;
                }

                a = this.safe_add(a, olda);
                b = this.safe_add(b, oldb);
                c = this.safe_add(c, oldc);
                d = this.safe_add(d, oldd);
                e = this.safe_add(e, olde);
            }
            return Array(a, b, c, d, e);
        },

        /*
        * Perform the appropriate triplet combination function for the current
        * iteration
        */
        sha1_ft: function(t, b, c, d)
        {
            if (t < 20) return (b & c) | ((~b) & d);
            if (t < 40) return b ^ c ^ d;
            if (t < 60) return (b & c) | (b & d) | (c & d);
            return b ^ c ^ d;
        },

        /*
        * Determine the appropriate additive constant for the current iteration
        */
        sha1_kt: function(t)
        {
            return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
			    (t < 60) ? -1894007588 : -899497514;
        },

        /*
        * Calculate the HMAC-SHA1 of a key and some data
        */
        core_hmac_sha1: function(key, data)
        {
            var bkey = this.str2binb(key);
            if (bkey.length > 16) bkey = this.core_sha1(bkey, key.length * this.chrsz);

            var ipad = Array(16), opad = Array(16);
            for (var i = 0; i < 16; i++)
            {
                ipad[i] = bkey[i] ^ 0x36363636;
                opad[i] = bkey[i] ^ 0x5C5C5C5C;
            }

            var hash = this.core_sha1(ipad.concat(this.str2binb(data)), 512 + data.length * this.chrsz);
            return this.core_sha1(opad.concat(hash), 512 + 160);
        },

        /*
        * Add integers, wrapping at 2^32. This uses 16-bit operations internally
        * to work around bugs in some JS interpreters.
        */
        safe_add: function(x, y)
        {
            var lsw = (x & 0xFFFF) + (y & 0xFFFF);
            var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
            return (msw << 16) | (lsw & 0xFFFF);
        },

        /*
        * Bitwise rotate a 32-bit number to the left.
        */
        rol: function(num, cnt)
        {
            return (num << cnt) | (num >>> (32 - cnt));
        },

        /*
        * Convert an 8-bit or 16-bit string to an array of big-endian words
        * In 8-bit function, characters >255 have their hi-byte silently ignored.
        */
        str2binb: function(str)
        {
            var bin = Array();
            var mask = (1 << this.chrsz) - 1;
            for (var i = 0; i < str.length * this.chrsz; i += this.chrsz)
                bin[i >> 5] |= (str.charCodeAt(i / this.chrsz) & mask) << (32 - this.chrsz - i % 32);
            return bin;
        },

        /*
        * Convert an array of big-endian words to a string
        */
        binb2str: function(bin)
        {
            var str = "";
            var mask = (1 << this.chrsz) - 1;
            for (var i = 0; i < bin.length * 32; i += this.chrsz)
                str += String.fromCharCode((bin[i >> 5] >>> (32 - this.chrsz - i % 32)) & mask);
            return str;
        },

        /*
        * Convert an array of big-endian words to a hex string.
        */
        binb2hex: function(binarray)
        {
            var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
            var str = "";
            for (var i = 0; i < binarray.length * 4; i++)
            {
                str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
			    hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
            }
            return str;
        },

        /*
        * Convert an array of big-endian words to a base-64 string
        */
        binb2b64: function(binarray)
        {
            var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
            var str = "";
            for (var i = 0; i < binarray.length * 4; i += 3)
            {
                var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16)
					    | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8)
					    | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
                for (var j = 0; j < 4; j++)
                {
                    if (i * 8 + j * 6 > binarray.length * 32) str += this.b64pad;
                    else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
                }
            }
            return str;
        }
    }
}).call(SoundCloud);

PNG transparency in Win IE 5.5 & 6

function correctPNG() // correctly handle PNG transparency in Win IE 5.5 & 6.
{
    var arVersion = navigator.appVersion.split("MSIE")
    var version = parseFloat(arVersion[1])
    if ((version >= 5.5) && (document.body.filters))
    {
       for(var j=0; j<document.images.length; j++)
       {
          var img = document.images[j]
          var imgName = img.src.toUpperCase()
          if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
          {
             var imgID = (img.id) ? "id='" + img.id + "' " : ""
             var imgClass = (img.className) ? "class='" + img.className + "' " : ""
             var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
             var imgStyle = "float:left;margin:0 10px;" + img.style.cssText 
             if (img.align == "left") imgStyle = "float:left;" + imgStyle
             if (img.align == "right") imgStyle = "float:right;" + imgStyle
             if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
             var strNewHTML = "<span " + imgID + imgClass + imgTitle
             + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
             + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
             + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
             img.outerHTML = strNewHTML
             j = j-1
          }
       }
    }    
}
if(!window.XMLHttpRequest){
window.attachEvent("onload", correctPNG);
}

Windows8 各种版本区别对比

功能特性 Windows RT Windows 8

(标准版)
Windows8 Pro

(专业版)
Windows 8 Enterprise

(企业版)
与现有Windows 兼容
购买渠道 在设备上预装 大多数渠道 大多数渠道 经过认证的客户
架构 ARM (32-bit) IA-32 (32-bit) or x86-64 (64-bit) IA-32 (32-bit) or x86-64 (64-bit) IA-32 (32-bit) or x86-64 (64-bit)
安全启动
图片密码
开始界面、动态磁帖以及相关效果
触摸键盘、拇指键盘
语言包
更新的资源管理器
标准程序
文件历史
系统的重置功能
Play To “播放至”功能
Connected standby保持网络连接的待机
Windows Update
Windows Defender
增强的多显示屏支持
新的任务管理器
ISO 镜像 and VHD 挂载
移动通信功能
Microsoft 账户
Internet Explorer 10
SmartScreen
Windows 商店
Xbox Live 程序 (包括 Xbox Live Arcade)
Exchange ActiveSync
快速睡眠(snap)
VPN连接
Device encryption
随系统预装的Microsoft Office
桌面 部分
储存空间管理(storage space)
Windows Media Player
Windows Media Center 需另行添加
远程桌面 只作客户端 只作客户端 客户端和服务端 客户端和服务端
从VHD启动
BitLocker and BitLocker To Go
文件系统加密
加入Windows 域
组策略
AppLocker
Hyper-V 仅64bit支持
Windows To Go
DirectAccess
分支缓存(BranchCache)
以RemoteFX提供视觉特效
Metro风格程序的部署

表中最后几行是企业版独有的几个功能(仅供参考):

  • Windows To Go:允许 Windows 8 从 U 盘或者外置硬盘启动,这里有视频教程
  • DirectAccess:远程直接登入,这是类似于 VPN 的一种连接方式,不同的是只要客户机一开机它就会连接上,而不需要初始化。
  • 分支缓存(BranchCache):分支缓存使分支办公室中的客户端能够安全地检索缓存在本地的文件,而无需从主办公室服务器检索文件。
  • 以RemoteFX提供视觉特效:这是远程桌面协议(RDP)功能的增强,使用服务器端的图形显卡来处理然后将高分辨率位图发送到客户端桌面。