javascript高效简洁代码的编写及优化技巧

前言

随着互联网前端技术的革新,javascript越来越重要,并且js的轻便,非严格的写法,使越来越多的人掌握了js,可是谈到js的写法,很多人都觉得自己很熟悉,很了解,但是笔者在实践中发现js并非大家想象的那么简单,就像同事一句话:php会的很多,一抓一大把,而真正会js的却不多。仔细想想,原因很简单,js的加载到客户端运行的,不像php可以一个include就可以搞定,而且引入的文件中不用的函数可以放着不动,而js不同,如果加入很多很多无用的函数会大大的占有带宽,不利于用户体验。下面结合笔者实际开发过程中遇到的问题,以及自己收集的技巧,谈谈js高效简洁代码的编写及其优化的技巧。当然网上也有很多类似的文章,不过建议大家还是不要人云亦云,真正适合自己的技巧跟编写习惯才是最好的!

真假的判断

Javascript中有null、undefined、string、number、boolean五种基本的类型,一般判断真假或者为空的时候大家会使用下面的代码:


if(a==true){
    //doSomeTing();
}```但是这种方法很不简洁,我们完全可以使用1,0来判断,比如我们设定一个a,如果a为假,我们就改成真,而a在程序后面可能用于判断,最简单也是最好理解的方法就是下面的写法
```javascript

var a=false;
if(a==false){
    a=true;
}
```既然提到了0,1,肯定有人想到了第二种写法:
```javascript

var a=0;
if(!a){
    a=1;
}
```这个代码还可以进一步简写优化,就是使用js的三元运算符,也就是三目运算符:
```javascript

var a=0;
!a?a=1?null;

还有一点,对于空字符串的判断,往往采用if(a==””),其实对于空字符本身就是false,下面我总结了下Javascript中的真假值,希望对大家有用

CSS 3.0 参考手册 (中文版)下载

原文来自:腾讯webteam

CSS 是 Cascading Style Sheet 的缩写。译作「层叠样式表」。是用于(增强)控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

手册难点

  1. 中文资料少,对英文翻译功底要求较高;
  2. 基础语法要求字斟句酌,避免产生歧义;
  3. 兼容性列表涉及浏览器及版本众多;
  4. 草案中的Grid布局被业界同仁普遍认为比“天书”还难…

CSS3 还是草案,中文资料少之又少,基本上都是一篇内容转来转去,而我们的手册从基础语法到示例制作,都是根据W3C工作草案进行翻译,并结合自身的沉淀制作示例。

备受期待的 CSS 3 新功能

圆角、多背景、@font-face 用户自定义字体、动画与渐变、渐变色、盒阴影、RGBa - 加入透明色、文字阴影等等
CSS3 的出现,让代码更简洁、页面结构更合理,性能和效果得到兼顾。

php、js两种不同方式根据关键词返回经纬度接口【基于Google map API】

P.S:在本文章中您将找到根据城市关键词获取经纬度的方法,即就是通过google map API的逆经纬度查询接口获得经纬度。
google map api是一个强大的地图API,很多知名的网站都是用了google地图API,曾经我也写过一个根据来访者甚至域名来查询经纬度的程序(http://js8.in/mywork/ipsearch)。文章链接地址为:根据IP返回地理位置地址以及地理经纬度的方法,关于经纬度的其他文章可以参考全国各省市,县级城市经纬度SQL数据以及js数组
其中使用的是纯真IP数据库,已经google地图的逆经纬度查询~
而本例中我们实现的主要方式是php如何获得关键字的经纬度。
使用过Google map API的人都知道google有一个逆经纬度查询的接口,例如:

geocoder = new GClientGeocoder();geocoder.getLocations(
          '山东青岛',
        function($){
var lalton = $.Placemark[0].Point.coordinates;
alert(latlon[0]+","+latlon[1]);
});```可是对于php应该怎样获取**经纬度**呢?
今天在无意的时候看到一个wp的插件,其中找到了方法,就是通过google map API的逆经纬度查询接口获得经纬度~
首先你需要去http://code.google.com/intl/zh-CN/apis/maps/signup.html申请一个google map api的授权域名**key**,
google的map api逆经纬度接口为:
http://maps.google.com/maps/geo?q=关键词(如山东青岛)&key=刚刚申请的API KEY&sensor=false&output=xml&oe=utf8
请求下来的数据时kml的数据格式,怎样解析呢?
<!--more-->我们可以使用**xml**的方式来进行解析,这里我提供一个解析的**php**代码,代码来自于wp的一个插件
第一个函数是xml2array(),这个函数的作用就是把xml转换为数组便于操作
参数$url为请求的xml地址,返回的是一个xml转换成的数组

```php
//from http://us3.php.net/manual/en/function.xml-parse.php
function xml2array($url, $get_attributes = 1, $priority = 'tag')
{
    $contents = "";
    if (!function_exists('xml_parser_create'))
    {
        return array ();
    }
    $parser = xml_parser_create('');
    if (!($fp = @ fopen($url, 'rb')))
    {
        return array ();
    }
    while (!feof($fp))
    {
        $contents .= fread($fp, 8192);
    }
    fclose($fp);
    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($parser, trim($contents), $xml_values);
    xml_parser_free($parser);
    if (!$xml_values)
        return; //Hmm...
    $xml_array = array ();
    $parents = array ();
    $opened_tags = array ();
    $arr = array ();
    $current = & $xml_array;
    $repeated_tag_index = array ();
    foreach ($xml_values as $data)
    {
        unset ($attributes, $value);
        extract($data);
        $result = array ();
        $attributes_data = array ();
        if (isset ($value))
        {
            if ($priority == 'tag')
                $result = $value;
            else
                $result['value'] = $value;
        }
        if (isset ($attributes) and $get_attributes)
        {
            foreach ($attributes as $attr => $val)
            {
                if ($priority == 'tag')
                    $attributes_data[$attr] = $val;
                else
                    $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
            }
        }
        if ($type == "open")
        {
            $parent[$level -1] = & $current;
            if (!is_array($current) or (!in_array($tag, array_keys($current))))
            {
                $current[$tag] = $result;
                if ($attributes_data)
                    $current[$tag . '_attr'] = $attributes_data;
                $repeated_tag_index[$tag . '_' . $level] = 1;
                $current = & $current[$tag];
            }
            else
            {
                if (isset ($current[$tag][0]))
                {
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
                    $repeated_tag_index[$tag . '_' . $level]++;
                }
                else
                {
                    $current[$tag] = array (
                        $current[$tag],
                        $result
                    );
                    $repeated_tag_index[$tag . '_' . $level] = 2;
                    if (isset ($current[$tag . '_attr']))
                    {
                        $current[$tag]['0_attr'] = $current[$tag . '_attr'];
                        unset ($current[$tag . '_attr']);
                    }
                }
                $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
                $current = & $current[$tag][$last_item_index];
            }
        }
        elseif ($type == "complete")
        {
            if (!isset ($current[$tag]))
            {
                $current[$tag] = $result;
                $repeated_tag_index[$tag . '_' . $level] = 1;
                if ($priority == 'tag' and $attributes_data)
                    $current[$tag . '_attr'] = $attributes_data;
            }
            else
            {
                if (isset ($current[$tag][0]) and is_array($current[$tag]))
                {
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
                    if ($priority == 'tag' and $get_attributes and $attributes_data)
                    {
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
                    }
                    $repeated_tag_index[$tag . '_' . $level]++;
                }
                else
                {
                    $current[$tag] = array (
                        $current[$tag],
                        $result
                    );
                    $repeated_tag_index[$tag . '_' . $level] = 1;
                    if ($priority == 'tag' and $get_attributes)
                    {
                        if (isset ($current[$tag . '_attr']))
                        {
                            $current[$tag]['0_attr'] = $current[$tag . '_attr'];
                            unset ($current[$tag . '_attr']);
                        }
                        if ($attributes_data)
                        {
                            $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
                        }
                    }
                    $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
                }
            }
        }
        elseif ($type == 'close')
        {
            $current = & $parent[$level -1];
        }
    }
    return ($xml_array);
}

第二个函数getPoiAndAdd($address,$mapkey):
$address为查询的关键词,地址就可以啦,$mapkey为你申请的google map api key,
返回的是一个数组,其中包括了经纬度以及详细地址哦~

function gmshc_point ($address,$apikey){
    $find = array("\n","\r"," ");
    $replace = array("","","+");                    
    $address = str_replace( $find,$replace, $address);
    $url = 'http://maps.google.com/maps/geo?q='.$address.'&key='.$apikey.
         '&sensor=false&output=xml&oe=utf8';    
    $response = xml2array($url);    //此处调用都一个函数进行解析
    $coordinates = $response['kml']['Response']['Placemark']['Point']['coordinates'];
    $address = $response['kml']['Response']['Placemark']['address'];    
    if (!empty($coordinates)) {    
    $point_array = split(",",$coordinates);    
    $point = $point_array[1].",".$point_array[0];
    $response = array('point'=>$point,'address'=>$address);    
    return  $response;    
    }
}

jQuery浏览器判断一个bug,以及修改建议

前几天在使用jQuery(1.3.2)的时候,想使用下浏览器判断$.browser,可是我在使用$.browser.safari的时候,发现一个问题:
就是chrome浏览器也走$.browser.safari的判断,查看了jQuery的源代码:

var userAgent = navigator.userAgent.toLowerCase();
jQuery.browser = {
    version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
    safari: /webkit/.test( userAgent ),
    opera: /opera/.test( userAgent ),
    msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
    mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};```<!--more-->
经过同事**修改**后的代码是:
```javascript
var browserName = navigator.userAgent.toLowerCase();
mybrowser = {
    version: (browserName.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, '0'])[1],
    safari: /webkit/i.test(browserName) && !this.chrome,
    opera: /opera/i.test(browserName),
        firefox:/firefox/i.test(browserName),
    msie: /msie/i.test(browserName) && !/opera/.test(browserName),
    mozilla: /mozilla/i.test(browserName) && !/(compatible|webkit)/.test(browserName) && !this.chrome,
        chrome: /chrome/i.test(browserName) && /webkit/i.test(browserName) && /mozilla/i.test(browserName)
}

完全可以使用,并且防止了safari跟chrome混淆的

14条JS代码编写时最佳规范

写任何编程代码,不同的开发者都会有不同的见解。但参考一下总是好的,下面是来自Javascript Toolbox发布的14条最佳JS代码编写技巧,Sofish翻译(1,2)。

1. 总是使用 ‘var’

在JavaScript中,变量不是全局范围的就是函数范围的,使用”var”关键词将是保持变量简洁明了的关键。当声明一个或者是全局或者是函数级(function-level)的变量,需总是前置”var”关键词,下面的例子将强调不这样做潜在的问题。

不使用 Var 造成的问题

var i=0; // This is good - creates a global variable
function test() {
   for (i=0; i&lt;10; i++) {
      alert("Hello World!");
   }
}
test();
alert(i); // The global variable i is now 10!

因为变量函数中变量 i 并没有使用 var 使其成为函数级的变量,在这个例子中它引用了全局变量。总是使用 var 来声明全局变量是一个很多的做法,但至关重要的一点是使用 var 定义一个函数范围的变量。下面这两个方法在功能上是相同的:

正确的函数

function test() {
   var i=0;
   for (i=0; i&lt;10; i++) {
      alert("Hello World!");
   }
}
正确的函数

function test() {
   for (var i=0; i&lt;10; i++) {
      alert("Hello World!");
   }
}

2. 特性检测而非浏览器检测

一些代码是写来发现浏览器版本并基于用户正使用的客户端的对其执行不同行为。这个,总的来说,是一个非常糟的实践。更好的方法是使用特性检测,在使 用一个老浏览器可能不支持的高级的特性之前,首先检测(浏览器的)是否有这个功能或特性,然后使用它。这单独检测浏览器版本来得更好,即使你知道它的性 能。你可以在 http://www.jibbering.com/faq/faq_notes/not_browser_detect.html找到一个深入讨论这个问题的文章。

例子:

根据IP返回地理位置地址以及地理经纬度的方法

今天做了一个基于Google地图的根据IP返回地理位置的接口,效果演示地址:http://js8.in/mywork/ipsearch/

可以输入域名,如:js8.in,既可以返回地理位置,并且把地理位置定位到Google地图上,并且在地图上打开气泡显示经纬度。

效果图:
根据IP返回地理位置接口

关于这个IP查询接口的调用方法:http://js8.in/mywork/ipsearch/ipsearch.php?ip=你要查询的IP地址或者域名(如js8.in)

程序说明:

1、IP数据库采用了纯真IP数据库10.25日最新版,可能有时间就更新一下数据库内容。
2、获取的经纬度是根据Google的地图接口,返回的数据~对于国内的经纬度应该有一定的偏移(国家法律规定的),但是在Google上使用应该是可以的~

jQuery+google weather API轻松实现天气地图(二)

原理:通过来输入的关键词查询出城市的经纬度,然后调用google的weather接口,查出城市的天气情况,根据xml解析出来的结果返货json格式,便于代码的传输~!

这里我使用的是MapBar的地图免费API,其他的如:Google 就不做说明了~方法类似~截图如下:

现在把Mysql.php的全部代码,使用了simpleXML对Google返回的数据进行解析:
PS:关于各个城市的经纬度数据,请阅览:全国各省市,县级城市经纬度SQL数据以及js数组

<?php
  include("conn.php");
$strsql="select * from latlon where name=’".$_GET['city']."’";
    $result=mysql_db_query($mysql_database, $strsql, $conn);
    // u83b7u53d6u67e5u8be2u7ed3u679c,1 = name 2= latlon 3=weidu 4 = jingdu
    $row=mysql_fetch_row($result);
    mysql_data_seek($result, 0);
    $row=mysql_fetch_row($result);
    if(empty($row[1])){
        $re =array(        "noCity"=>"no data",
        "yes"=>0,
    );
        echo "";
    }else{
    $nlatlon= $row[4].’,’.$row[3];
    $back=$row[3]*1000000
.$row[4]*1000000;
$url=’http://www.google.com/ig/api?weather=,,,’.$back;
$xml =  simplexml_load_file($url);
$re=array(
    "yes"=>1,
"today" =>(string)($xml->weather->forecast_conditions[0]->condition['data']),
"ssd"=>(string)($xml->weather->current_conditions->temp_c['data']),
"sd"=>(string)($xml->weather->current_conditions->humidity['data']),
"fx"=>(string)($xml->weather->current_conditions->wind_condition['data']),
"icon"=>’http://www.google.com’.($xml->weather->forecast_conditions[0]->icon['data']),
"week1" =>(string)($xml->weather->forecast_conditions[1]->day_of_week['data']),
"week1zuidi" =>(int)((int)((string)($xml->weather->forecast_conditions[1]->low['data'])-32)/1.8+1),
"week1zuigao" =>(int) ((int)((string)($xml->weather->forecast_conditions[1]->high['data'])-32)/1.8+1),
"week1tianqi" =>(string)($xml->weather->forecast_conditions[1]->condition['data']),
"week1icon" =>’http://www.google.com’.($xml->weather->forecast_conditions[1]->icon['data']),
"week2" =>(string)($xml->weather->forecast_conditions[2]->day_of_week['data']),
"week2zuidi" =>(int) ((int)((string)($xml->weather->forecast_conditions[2]->low['data'])-32)/1.8+1),
"week2zuigao" =>(int) ((int)((string)($xml->weather->forecast_conditions[2]->high['data'])-32)/1.8+1),
"week2tianqi" =>(string)($xml->weather->forecast_conditions[2]->condition['data']),
"week2icon" =>’http://www.google.com’.($xml->weather->forecast_conditions[2]->icon['data']),
"week3" =>(string)($xml->weather->forecast_conditions[3]->day_of_week['data']),
"week3zuidi" =>(int) ((int)((string)($xml->weather->forecast_conditions[3]->low['data'])-32)/1.8+1),
"week3zuigao" =>(int) ((int)((string)($xml->weather->forecast_conditions[3]->high['data'])-32)/1.8+1),
"week3tianqi" =>(string)($xml->weather->forecast_conditions[3]->condition['data']),
"week3icon" =>’http://www.google.com’.($xml->weather->forecast_conditions[3]->icon['data']),
"nlatlon" =>$nlatlon,
"googleurl"=>$url,
);
}
echo json_encode($re);
    mysql_free_result($result);
mysql_close($conn);

?>

真正的jQuery的radio与checkbox取值

今天闲着没事想把爱墙做成好友飞信通知的功能,遇到一个checkbox的选择问题,由于自己喜欢使用jQuery来开发~所以对于jQuery对checkbox的取值很想搞清楚~

我试着使用网上比较多的版本,比如:$(“input[name=’fetion’]”).attr(“checked”),

下面代码是网上的

多选框checkbox

 $("#chk1").attr("checked",'');//不打勾
$("#chk2").attr("checked",true);//打勾
if($("#chk1").attr('checked')==undefined) //判断是否已经打勾

jQuery插件pager修改版-更加智能

我的新版爱墙使用了jQuery的pager插件,可是对于老外的插件我实在是不敢恭维,比较难用,并且只能设置显示页面字数为奇数,如果为偶数则比设定的页数多一!并且不能自己设置每页显示多少页码,二是默认的9个页码,很不方便~

研究了一下,自己修改了下Pager插件,本次修改添加了“上下页”、“首页”、“最后一页”自己定义样式,比如:使用“上一页”“>>”“next”之类的字符,并且自动设置显示不显示上下页,首页,最后一页。
demo1 demo2

比如代码

var show2={per:6,index:{n:”首页”,m:”first”},pre:{n:”prev”,m:”prev”},next:{n:”next”,m:”next”},last:{n:”最后一页”,m:”last”}};
$(“#pager2”).pager({ pagenumber: 1, pagecount: 15, buttonClickCallback: PageClick2,show:show2 });