js高級應用

特別板塊:js跨域請求Tomcat六、tomcat7 跨域設置(包含html5 的CORS)javascript

須要下載兩個jar文件,cors-filter-1.7.jar,Java-property-utils-1.9.jar這兩個庫文件,http://download.csdn.net/detail/csr0312/9280097 
放到tomcat lib目錄下面,不是項目的lib目錄,而後配置項目的web.xml,添加以下內容,注意filter位置,應該放在第一位css

<!-- 實現跨域 -->
    <filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
        <init-param><!-- 通常爲了安全考慮會指定具體幾個地址源 -->
            <param-name>cors.allowOrigin</param-name>
            <param-value>*</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportedMethods</param-name>
            <param-value>GET, POST, HEAD, PUT, DELETE</param-value>
        </init-param>
        <init-param><!-- 消息頭設置 -->
            <param-name>cors.supportedHeaders</param-name>
            <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified,Access-Control-Allow-Origin</param-value>
        </init-param>
        <init-param>
            <param-name>cors.exposedHeaders</param-name>
            <param-value>Set-Cookie</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportsCredentials</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 

 

0、js版本檢測html

<html>   
  <head>   
      <title>JavaScript版本測試</title>   
  </head>   
  <body>   
  <script   language="JavaScript">   
      //僅支持JavaScript   1.0的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.0<br>');   
  </script>   
  <script   language="JavaScript1.1">   
      //僅支持JavaScript   1.1的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.1<br>');   
  </script>   
  <script   language="JavaScript1.2">   
      //僅支持JavaScript   1.2的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.2<br>');   
  </script>   
  <script   language="JavaScript1.3">   
      //僅支持JavaScript   1.3的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.3<br>');   
  </script>   
  <script   language="JavaScript1.4">   
      //僅支持JavaScript   1.4的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.4<br>');   
  </script>   
  <script   language="JavaScript1.5">   
      //僅支持JavaScript   1.5的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.5<br>');   
  </script>
  <script   language="JavaScript1.6">   
      //僅支持JavaScript   1.6的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.6<br>');   
  </script> 
  <script   language="JavaScript1.7">   
      //僅支持JavaScript   1.7的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.7<br>');   
  </script> 
  <script   language="JavaScript1.8">   
      //僅支持JavaScript   1.8的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.8<br>');   
  </script> 
  <script   language="JavaScript1.9">   
      //僅支持JavaScript   1.9的瀏覽器纔讀該部分   
      document.write('瀏覽器支持JavaScript   1.9<br>');   
  </script> 
  </body>   
  </html>
View Code

一、triggerhtml5

  情景:在項目中,tab頁切換時,元素沒法正常顯示出來,拖動窗口大小時,又能正常顯示;java

  可在tab的切換點擊事件中加入該操做:node

  $(window).trigger("resize",$(window).width(),$(window).height()); 即重置窗口大小,實現拖動窗口效果。jquery

二、$.attr()問題:git

  情景:<input id="tt" clickEvent="sendInfo('info')"> ,github

       $("#tt").attr("clickEvent") 結果取出來的是「sendInfo(」,web

     由於該代碼通過瀏覽器解析後,變成<input id='tt' clickEvent='sendInfo('info')'>,故有此結果;

       若是屬性是經過後臺拼接,該問題更突出(如:java中的標籤)。

  處理方法:一、改寫成:<input id="tt" clickEvent='sendInfo("info")'>

       二、案例:

        字符串1:{"cityId":"110100","cityName":"北京市轄區"}

        字符串2:{&quot;cityId&quot;:&quot;110100&quot;,&quot;cityName&quot;:&quot;北京市轄區&quot;}

        如上字符串所示,字符串1是在java後臺生成,經過structs2傳遞到前臺後,js中取得的字符串卻變成了字符串2的樣子,

        其中的」變成了&quot;使用的時候用StringEscapeUtils.unescapeHtml(字符串2)) 解下碼就行,即可取得原字符串1。

 

        由以上能夠找到解決方案:

          一、後臺傳前臺:[如json字符串].replaceAll("[\"']", "&quot;"),先將字符串中的單引號和雙引號轉出"&quot;",

             傳到前臺後瀏覽器會自動解析格式;

          二、前臺傳後臺:都是本身寫的,這個就不要偷懶啦,注意下格式就好了。

三、jquery簡雅之美:

  1)、簡雅之美 - 高兼容事件綁定

    好比input的值改變事件,正常咱們可能都會想到onpropertychange事件,因而這樣操做:

    $(ob).bind("propertychange",function(){ ...... });

    可是問題又來了,onpropertychange事件是ie專有的,可惡的是還只是ie9一下的版本纔能有效;

    那ie9及以上版本咋整?不急還有oninput事件,因而寫下以下代碼:

    $(ob).bind("input",function(){ ...... });

    然這樣並無解決問題,這種照顧了ie9及以上版本卻照顧不了ie8等低版本,不急咱們能夠這樣寫:

    $(ob).bind("input propertychange",function(){ ...... });因而問題解決了。

    綁定事件如此寫,其實能夠當作是事件選擇器,既優雅又簡潔。

 

四、js判斷輸入字符串長度(漢字算兩個字符,字母數字算一個)

  漢字在數據庫中佔2個字符,若是輸入字符超過數據庫表字段長度,會出現錯誤,所以須要在前臺進行判斷。有兩種方法進行判斷:

方法一:使用正則表達式,代碼以下:

 

function getByteLen(val) {

            var len = 0;

            for (var i = 0; i < val.length; i++) {

                 var a = val.charAt(i);

                 if (a.match(/[^\x00-\xff]/ig) != null) {

                    len += 2;

                } else  {

                    len += 1;

                }

            }

            return len;

}
View Code

 

方法二:使用字符unicode判斷:方法以下:

 

function getByteLen(val) {

            var len = 0;

            for (var i = 0; i < val.length; i++) {

               var length = val.charCodeAt(i);

               if(length>=0&&length<=128)  {

                    len += 1;

                }  else {

                    len += 2;

                }

            }

            return len;

}
View Code

五、比較完美的日期格式化

  a、(如jsp)頭部引入標籤<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

  b、利用<fmt:formatDate value="${obj.date}" pattern="yyyy-M-d" />嵌套到要初始化的輸入域:

    <input type="text" value="<fmt:formatDate value="${obj.date}" pattern="yyyy-M-d" />"/>

  js之字符串轉日期:建議使用  'yyyy/MM/dd' 格式,'yyyy-MM-dd' 這種格式在ie9如下時容易出現NoN解析異常

  即:var date1 = new Date('2016/01/01'); (兼容性好)

    var date2 = new Date('2016-01-01'); (ie9如下易出問題)

  若是非要出入'yyyy-MM-dd' 格式,以下處理

    dateStr = '2016-01-01';

    var date2 = new Date(Date.parse(dateStr.replace(/-/g,   "/")));

六、調用iframe裏的js函數 
  如: document.getElementById('iframedemo').targetfunction(); 
  可是這段代碼在firefox下報錯,因而上google搜索,發現一個解決辦法,在ie和firefox 下均工做正常,代碼以下: 
  document.getElementById('iframedemo').contentWindow.demofunction(); 
  其中iframedemo是iframe的id

七、純js事件追加之window.addEventListener

  window.addEventListener('resize',method1);

  window.addEventListener('resize',method2);

  window.addEventListener('resize',method3);

  執行順序爲:method1 -> method2 -> method3

  例如圖表插件Echarts在setoption以後添加這段代碼:

window.addEventListener('resize', function () {

  myChart.resize();
   });

圖表就能隨着窗口大小,自動適應,且支持一頁多圖。

八、監測js加載

場景:項目中監測js或者css是否重複加載,避免冗餘請求,減輕後端壓力

<!-- Bootstrap core JavaScript -->
<script src="/js/jquery/jquery-1.8.3.min.js"></script>
<script src="/js/bootstrap/js/bootstrap.min.js"></script>
<script src="/js/framework/jquery.menu.js"></script>
<script src="/js/framework/jquery.menu.js"></script>
<script src="/portal/common/js/jquery-easyui/jquery.easyui.min.js"></script>
<script type="text/javascript">
var msg = [];
$("script").each(function(){
  var item = $(this);
  $("script").each(function(){
    var innerItem = $(this);
    if(item.attr("src")==innerItem.attr("src")){
      var count = $("script[src*='"+item.attr("src")+"']").size() || 0;
      if(count>1){
        var itemInfo = item.attr("src")+":"+count+"\n";
        if($.inArray(itemInfo,msg)<0){
          msg.push(itemInfo);
        }
      }
    }
  });
});
if(msg!=""){
  $.messager.alert("提示",msg);
}
</script>
View Code

輸出結果:/js/framework/jquery.menu.js:2

 

九、form表單提交巧技 -- post傳參方式打開新窗口

// 打開新窗口post方式提交,target是關鍵
function submitForm(url,param){
      var form = $("<form anction='"+url+"' method='post' target='_blank' style='width: 0px;height: 0px;'></form>").appendTo(document.body);
      for(var item in subParam){
        var input = $("<input type='hidden' name='"+item+"' value='"+param[item]+"'/>");
        form.append(input);
     }
      form.submit();
      form.remove();
}

這樣封裝以後,是否是超好用捏O(∩_∩)O

十、js函數類Math之最大值max和最小值min

var a=[1,2,3,5];
alert(Math.max.apply(null, a));//最大值
alert(Math.min.apply(null, a));//最小值

多維數組
var a=[1,2,3,[5,6],[1,4,8]];
var ta=a.join(",").split(",");//轉化爲一維數組
alert(Math.max.apply(null,ta));//最大值
alert(Math.min.apply(null,ta));//最小值

使用鏈式
Array.prototype.max = function() {
return Math.max.apply({},this)

}
Array.prototype.min = function() {
return Math.min.apply({},this)

}
[1, 2, 3].max()// => 3
[1, 2, 3].min()// => 1

使用方法[1,2,3].max()
Array.max = function(array) {
return Math.max.apply(Math, array);

};

Array.min = function(array) {
return Math.min.apply(Math, array);

};
View Code

十一、js之apply和call方法詳解

js apply和js call方法老是讓初學者困惑,下文就apply和call的區別,什麼狀況下用apply,什麼狀況下用call、apply的巧妙用法來闡述js apply和js call方法的詳細使用方法。

主要我是要解決一下幾個問題:

1.   apply和call的區別在哪裏

2.   什麼狀況下用apply,什麼狀況下用call

3.  apply的其餘巧妙用法(通常在什麼狀況下可使用apply)

apply:方法能劫持另一個對象的方法,繼承另一個對象的屬性.

Function.apply(obj,args)方法能接收兩個參數:

obj:這個對象將代替Function類裏this對象
args:這個是數組,它將做爲參數傳給Function(args-->arguments)

call:和apply的意思同樣,只不過是參數列表不同.

Function.call(obj,[param1[,param2[,…[,paramN]]]])

obj:這個對象將代替Function類裏this對象
params:這個是一個參數列表

1. apply示例:

js apply和js call方法詳解

分析: Person.apply(this,arguments);

this:在建立對象在這個時候表明的是student

arguments:是一個數組,也就是[「zhangsan」,」21」,」一年級」];

也就是通俗一點講就是:用student去執行Person這個類裏面的內容,在Person這個類裏面存在this.name等之類的語句,這樣就將屬性建立到了student對象裏面

2. call示例

在Studen函數裏面能夠將apply中修改爲以下:

Person.call(this,name,age);

這樣就ok了

3.什麼狀況下用apply,什麼狀況下用call

在給對象參數的狀況下,若是參數的形式是數組的時候,好比apply示例裏面傳遞了參數arguments,這個參數是數組類型,而且在調用Person的時候參數的列表是對應一致的(也就是Person和Student的參數列表前兩位是一致的) 就能夠採用 apply , 若是個人Person的參數列表是這樣的(age,name),而Student的參數列表是(name,age,grade),這樣就能夠用call來實現了,也就是直接指定參數列表對應值的位置(Person.call(this,age,name,grade));

4. apply的一些其餘巧妙用法

細心的人可能已經察覺到,在我調用apply方法的時候,第一個參數是對象(this), 第二個參數是一個數組集合, 在調用Person的時候,他須要的不是一個數組,可是爲何他給我一個數組我仍然能夠將數組解析爲一個一個的參數,這個就是apply的一個巧妙的用處,能夠將一個數組默認的轉換爲一個參數列表([param1,param2,param3] 轉換爲 param1,param2,param3) 這個若是讓咱們用程序來實現將數組的每個項,來裝換爲參數的列表,可能都得費一會功夫,藉助apply的這點特性,因此就有了如下高效率的方法:

 

a)  Math.max 能夠實現獲得數組中最大的一項

由於Math.max 參數裏面不支持Math.max([param1,param2]) 也就是數組

可是它支持Math.max(param1,param2,param3…),因此能夠根據剛纔apply的那個特色來解決 var max=Math.max.apply(null,array),這樣輕易的能夠獲得一個數組中最大的一項(apply會將一個數組裝換爲一個參數接一個參數的傳遞給方法)

這塊在調用的時候第一個參數給了一個null,這個是由於沒有對象去調用這個方法,我只須要用這個方法幫我運算,獲得返回的結果就行,.因此直接傳遞了一個null過去

b)  Math.min  能夠實現獲得數組中最小的一項

一樣和 max是一個思想 var min=Math.min.apply(null,array);

c)  Array.prototype.push 能夠實現兩個數組合並

一樣push方法沒有提供push一個數組,可是它提供了push(param1,param,…paramN) 因此一樣也能夠經過apply來裝換一下這個數組,即:

vararr1=new Array("1","2","3");  
vararr2=new Array("4","5","6");  
Array.prototype.push.apply(arr1,arr2);  
也能夠這樣理解,arr1調用了push方法,參數是經過apply將數組裝換爲參數列表的集合.

一般在什麼狀況下,可使用apply相似Math.min等之類的特殊用法:

通常在目標函數只須要n個參數列表,而不接收一個數組的形式([param1[,param2[,…[,paramN]]]]),能夠經過apply的方式巧妙地解決這個問題!
View Code

十二、Map擴展

 Map對象在ie下,是有兼容性問題的,ie9+纔好使,爲此只能擴展Map了

(function(win) {
    var Map = function() {
        this.count = 0;
        this.entrySet = {};
    };

    var proto = Map.prototype;

    proto.size = function() {
        return this.count;
    };

    proto.isEmpty = function() {
        return this.count == 0;
    };

    proto.containsKey = function(key) {
        if (this.isEmpty()) {
            return false;
        }
        for ( var prop in this.entrySet) {
            if (prop == key) {
                return true;
            }
        }

        return false;
    };

    proto.containsValue = function(value) {
        if (this.isEmpty()) {
            return false;
        }

        for ( var key in this.entrySet) {
            if (this.entrySet[key] == value) {
                return true;
            }
        }

        return false;
    };

    proto.get = function(key) {
        if (this.isEmpty()) {
            return null;
        }

        if (this.containsKey(key)) {
            return this.entrySet[key];
        }

        return null;
    };

    proto.put = function(key, value) {
        this.entrySet[key] = value;
        this.count++;
    };

    proto.remove = function(key) {
        if (this.containsKey(key)) {
            delete this.entrySet[key];
            this.count--;
        }
    };

    proto.putAll = function(map) {
     if(!map instanceof Map){
        return;
     }

        for ( var key in map.entrySet) {
            this.put(key, map.entrySet[key]);
        }
    };

    proto.clear = function() {
        for ( var key in this.entrySet) {
            this.remove(key);
        }
    };

    proto.values = function() {
        var result = [];

        for ( var key in this.entrySet) {
            result.push(this.entrySet[key]);
        }

        return result;
    };

    proto.keySet = function() {
        var result = [];

        for ( var key in this.entrySet) {
            result.push(key);
        }

        return result;
    };

    proto.toString = function() {
        var result = [];
        for ( var key in this.entrySet) {
            result.push(key + ":" + this.entrySet[key]);
        }

        return "{" + result.join() + "}";
    };

    proto.valueOf = function() {
        return this.toString();
    };

    win.Map = Map;
})(window);
View Code

1三、JSON.stringify()兼容擴展

源碼:https://github.com/douglascrockford/JSON-js 

這個JS中的函數將JSON對象轉換成JSON字符串,解決 IE六、七、8不能使用 JSON.stringify 函數的問題!

<!--[if lt IE 9]>
    <script src="json2.js"></script>
<![endif]-->
//  json2.js
//  2016-05-01
//  Public Domain.
//  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
//  See http://www.JSON.org/js.html
//  This code should be minified before deployment.
//  See http://javascript.crockford.com/jsmin.html

//  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
//  NOT CONTROL.

//  This file creates a global JSON object containing two methods: stringify
//  and parse. This file is provides the ES5 JSON capability to ES3 systems.
//  If a project might run on IE8 or earlier, then this file should be included.
//  This file does nothing on ES5 systems.

//      JSON.stringify(value, replacer, space)
//          value       any JavaScript value, usually an object or array.
//          replacer    an optional parameter that determines how object
//                      values are stringified for objects. It can be a
//                      function or an array of strings.
//          space       an optional parameter that specifies the indentation
//                      of nested structures. If it is omitted, the text will
//                      be packed without extra whitespace. If it is a number,
//                      it will specify the number of spaces to indent at each
//                      level. If it is a string (such as "\t" or "&nbsp;"),
//                      it contains the characters used to indent at each level.
//          This method produces a JSON text from a JavaScript value.
//          When an object value is found, if the object contains a toJSON
//          method, its toJSON method will be called and the result will be
//          stringified. A toJSON method does not serialize: it returns the
//          value represented by the name/value pair that should be serialized,
//          or undefined if nothing should be serialized. The toJSON method
//          will be passed the key associated with the value, and this will be
//          bound to the value.

//          For example, this would serialize Dates as ISO strings.

//              Date.prototype.toJSON = function (key) {
//                  function f(n) {
//                      // Format integers to have at least two digits.
//                      return (n < 10)
//                          ? "0" + n
//                          : n;
//                  }
//                  return this.getUTCFullYear()   + "-" +
//                       f(this.getUTCMonth() + 1) + "-" +
//                       f(this.getUTCDate())      + "T" +
//                       f(this.getUTCHours())     + ":" +
//                       f(this.getUTCMinutes())   + ":" +
//                       f(this.getUTCSeconds())   + "Z";
//              };

//          You can provide an optional replacer method. It will be passed the
//          key and value of each member, with this bound to the containing
//          object. The value that is returned from your method will be
//          serialized. If your method returns undefined, then the member will
//          be excluded from the serialization.

//          If the replacer parameter is an array of strings, then it will be
//          used to select the members to be serialized. It filters the results
//          such that only members with keys listed in the replacer array are
//          stringified.

//          Values that do not have JSON representations, such as undefined or
//          functions, will not be serialized. Such values in objects will be
//          dropped; in arrays they will be replaced with null. You can use
//          a replacer function to replace those with JSON values.

//          JSON.stringify(undefined) returns undefined.

//          The optional space parameter produces a stringification of the
//          value that is filled with line breaks and indentation to make it
//          easier to read.

//          If the space parameter is a non-empty string, then that string will
//          be used for indentation. If the space parameter is a number, then
//          the indentation will be that many spaces.

//          Example:

//          text = JSON.stringify(["e", {pluribus: "unum"}]);
//          // text is '["e",{"pluribus":"unum"}]'

//          text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
//          // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'

//          text = JSON.stringify([new Date()], function (key, value) {
//              return this[key] instanceof Date
//                  ? "Date(" + this[key] + ")"
//                  : value;
//          });
//          // text is '["Date(---current time---)"]'

//      JSON.parse(text, reviver)
//          This method parses a JSON text to produce an object or array.
//          It can throw a SyntaxError exception.

//          The optional reviver parameter is a function that can filter and
//          transform the results. It receives each of the keys and values,
//          and its return value is used instead of the original value.
//          If it returns what it received, then the structure is not modified.
//          If it returns undefined then the member is deleted.

//          Example:

//          // Parse the text. Values that look like ISO date strings will
//          // be converted to Date objects.

//          myData = JSON.parse(text, function (key, value) {
//              var a;
//              if (typeof value === "string") {
//                  a =
//   /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
//                  if (a) {
//                      return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
//                          +a[5], +a[6]));
//                  }
//              }
//              return value;
//          });

//          myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
//              var d;
//              if (typeof value === "string" &&
//                      value.slice(0, 5) === "Date(" &&
//                      value.slice(-1) === ")") {
//                  d = new Date(value.slice(5, -1));
//                  if (d) {
//                      return d;
//                  }
//              }
//              return value;
//          });

//  This is a reference implementation. You are free to copy, modify, or
//  redistribute.

/*jslint
    eval, for, this
*/

/*property
    JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
    lastIndex, length, parse, prototype, push, replace, slice, stringify,
    test, toJSON, toString, valueOf
*/


// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.

if (typeof JSON !== "object") {
    JSON = {};
}

(function () {
    "use strict";

    var rx_one = /^[\],:{}\s]*$/;
    var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
    var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
    var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
    var rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
    var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;

    function f(n) {
        // Format integers to have at least two digits.
        return n < 10
            ? "0" + n
            : n;
    }

    function this_value() {
        return this.valueOf();
    }

    if (typeof Date.prototype.toJSON !== "function") {

        Date.prototype.toJSON = function () {

            return isFinite(this.valueOf())
                ? this.getUTCFullYear() + "-" +
                        f(this.getUTCMonth() + 1) + "-" +
                        f(this.getUTCDate()) + "T" +
                        f(this.getUTCHours()) + ":" +
                        f(this.getUTCMinutes()) + ":" +
                        f(this.getUTCSeconds()) + "Z"
                : null;
        };

        Boolean.prototype.toJSON = this_value;
        Number.prototype.toJSON = this_value;
        String.prototype.toJSON = this_value;
    }

    var gap;
    var indent;
    var meta;
    var rep;


    function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

        rx_escapable.lastIndex = 0;
        return rx_escapable.test(string)
            ? "\"" + string.replace(rx_escapable, function (a) {
                var c = meta[a];
                return typeof c === "string"
                    ? c
                    : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
            }) + "\""
            : "\"" + string + "\"";
    }


    function str(key, holder) {

// Produce a string from holder[key].

        var i;          // The loop counter.
        var k;          // The member key.
        var v;          // The member value.
        var length;
        var mind = gap;
        var partial;
        var value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

        if (value && typeof value === "object" &&
                typeof value.toJSON === "function") {
            value = value.toJSON(key);
        }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

        if (typeof rep === "function") {
            value = rep.call(holder, key, value);
        }

// What happens next depends on the value's type.

        switch (typeof value) {
        case "string":
            return quote(value);

        case "number":

// JSON numbers must be finite. Encode non-finite numbers as null.

            return isFinite(value)
                ? String(value)
                : "null";

        case "boolean":
        case "null":

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce "null". The case is included here in
// the remote chance that this gets fixed someday.

            return String(value);

// If the type is "object", we might be dealing with an object or an array or
// null.

        case "object":

// Due to a specification blunder in ECMAScript, typeof null is "object",
// so watch out for that case.

            if (!value) {
                return "null";
            }

// Make an array to hold the partial results of stringifying this object value.

            gap += indent;
            partial = [];

// Is the value an array?

            if (Object.prototype.toString.apply(value) === "[object Array]") {

// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || "null";
                }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

                v = partial.length === 0
                    ? "[]"
                    : gap
                        ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
                        : "[" + partial.join(",") + "]";
                gap = mind;
                return v;
            }

// If the replacer is an array, use it to select the members to be stringified.

            if (rep && typeof rep === "object") {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    if (typeof rep[i] === "string") {
                        k = rep[i];
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (
                                gap
                                    ? ": "
                                    : ":"
                            ) + v);
                        }
                    }
                }
            } else {

// Otherwise, iterate through all of the keys in the object.

                for (k in value) {
                    if (Object.prototype.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (
                                gap
                                    ? ": "
                                    : ":"
                            ) + v);
                        }
                    }
                }
            }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

            v = partial.length === 0
                ? "{}"
                : gap
                    ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
                    : "{" + partial.join(",") + "}";
            gap = mind;
            return v;
        }
    }

// If the JSON object does not yet have a stringify method, give it one.

    if (typeof JSON.stringify !== "function") {
        meta = {    // table of character substitutions
            "\b": "\\b",
            "\t": "\\t",
            "\n": "\\n",
            "\f": "\\f",
            "\r": "\\r",
            "\"": "\\\"",
            "\\": "\\\\"
        };
        JSON.stringify = function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

            var i;
            gap = "";
            indent = "";

// If the space parameter is a number, make an indent string containing that
// many spaces.

            if (typeof space === "number") {
                for (i = 0; i < space; i += 1) {
                    indent += " ";
                }

// If the space parameter is a string, it will be used as the indent string.

            } else if (typeof space === "string") {
                indent = space;
            }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

            rep = replacer;
            if (replacer && typeof replacer !== "function" &&
                    (typeof replacer !== "object" ||
                    typeof replacer.length !== "number")) {
                throw new Error("JSON.stringify");
            }

// Make a fake root object containing our value under the key of "".
// Return the result of stringifying the value.

            return str("", {"": value});
        };
    }


// If the JSON object does not yet have a parse method, give it one.

    if (typeof JSON.parse !== "function") {
        JSON.parse = function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

            var j;

            function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

                var k;
                var v;
                var value = holder[key];
                if (value && typeof value === "object") {
                    for (k in value) {
                        if (Object.prototype.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }


// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

            text = String(text);
            rx_dangerous.lastIndex = 0;
            if (rx_dangerous.test(text)) {
                text = text.replace(rx_dangerous, function (a) {
                    return "\\u" +
                            ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with "()" and "new"
// because they can cause invocation, and "=" because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
// replace all simple value tokens with "]" characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or "]" or
// "," or ":" or "{" or "}". If that is so, then the text is safe for eval.

            if (
                rx_one.test(
                    text
                        .replace(rx_two, "@")
                        .replace(rx_three, "]")
                        .replace(rx_four, "")
                )
            ) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The "{" operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval("(" + text + ")");

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

                return (typeof reviver === "function")
                    ? walk({"": j}, "")
                    : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError("JSON.parse");
        };
    }
}());
View Code

1四、javascript 變量加var 和 不加var區別 

1、外部的爲全局,內部的爲局部變量;

2、加var爲局部變量(在方法內),不加var爲全局變量(當方法內有一次使用後)。

在寫jquery plugin的時候,不當心沒加var 聲明變量(好比option),致使成爲全局變量,多個容器同時初始化組件的時候,

全部容器的option都變成了最後渲染的容器的option,因而各類蛋疼詭異的事情就發生了。

1五、datagrid數據和json定製數據合併

場景:easyui-datagrid組件獲取到原始數據,根據datagrid中的幾個field屬性的值做爲定位某行的索引,根據這個索引去json定製數據中取值合併。

核心算法:

function combineDataGrid(dataJson,paramJson,indexKeys){// indexKeys 索引fields,數組:['field1','field2'...]
    var rows = dataJson.rows;
    $.each(rows,function(index,item){
        var keyIndex = '';
        $.each(indexKeys,function(index,value){
            if(index == 0) keyIndex += item[value];
            else keyIndex += ','+item[value];
        });
        if(paramJson[keyIndex] && typeof paramJson[keyIndex] =="object")
            item = $.extend(item,paramJson[keyIndex]);
    });
    return dataJson;
}

demo【jsp】:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
    
        <!-- Bootstrap core CSS -->
        <link href="<%=request.getContextPath() %>/js/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    
</head>
<body>
    <div class="contener">
        <div class="row">
            <div class="col-sm-6">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        dataGrid 數據
                    </div>
                    <div class="panel-body">
                        var dataJson = {"total":28,"rows":[ <br>
                            {"productid":"FI-SW-01","productname":"Koi"},<br>
                            {"productid":"K9-DL-01","productname":"Dalmation"},<br>
                            {"productid":"RP-SN-01","productname":"Rattlesnake"},<br>
                            {"productid":"RP-SN-01","productname":"Rattlesnake"},<br>
                            {"productid":"RP-LI-02","productname":"Iguana"}<br>
                        ]}
                    </div>
                </div>
            </div>
            
            <div class="col-sm-6">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        要合併的屬性
                    </div>
                    <div class="panel-body">
                        var  paramJson = {<br>
                             'FI-SW-01,Koi':{name:'tomy',address:'北京海淀'},<br>
                             'RP-SN-01,Rattlesnake':{age: 21},<br>
                             'RP-LI-02,Iguana':{sex:'男'}<br>
                        };
                    </div>
                </div>
            </div>
        </div>
        
        <div class="row">
            <div class="col-sm-12">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        合併後結果
                    </div>
                    <div class="panel-body">
                        <p id="result"></p>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
</body>
<script src="<%=request.getContextPath()%>/js/jquery/jquery-1.8.3.js"></script>
<script src="<%=request.getContextPath() %>/js/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript">
    var dataJson = {"total":28,"rows":[
        {"productid":"FI-SW-01","productname":"Koi"},
        {"productid":"K9-DL-01","productname":"Dalmation"},
        {"productid":"RP-SN-01","productname":"Rattlesnake"},
        {"productid":"RP-SN-01","productname":"Rattlesn"},
        {"productid":"RP-LI-02","productname":"Iguana"}
    ]};
    var  paramJson = {'FI-SW-01,Koi':{productname:'tomy',address:'北京海淀'},
                      'RP-SN-01,Rattlesnake':{age: 21},
                      'RP-LI-02,Iguana':{sex:''}};
    var indexKeys = ['productid','productname'];
    function combineDataGrid(dataJson,paramJson,indexKeys){
        var rows = dataJson.rows;
        $.each(rows,function(index,item){
            var keyIndex = '';
            $.each(indexKeys,function(index,value){
                if(index == 0) keyIndex += item[value];
                else keyIndex += ','+item[value];
            });
            if(paramJson[keyIndex] && typeof paramJson[keyIndex] =="object")
                item = $.extend(item,paramJson[keyIndex]);
        });
        return dataJson;
    }
    combineDataGrid(dataJson,paramJson,indexKeys);
    
    $("#result").append('var dataJson = {"total":28,"rows":[');
    $.each(dataJson.rows,function(index,item){
        $("#result").append('<br>' +JSON.stringify(item));
    });
    $("#result").append('<br>]}');
    
</script>
</html>
View Code

效果:

1六、頁面多級嵌套iframe超時登出,總體登出處理

不正常狀況:(正確應該是整個首頁都應該跳到登錄界面)

處理方法:(在登錄頁面加入以下腳本)

<script type="text/JavaScript">
    var b = window.top!=window.self; // 是否和頂級窗口同級 if(b) window.top.logoutSys();    // 調用頂級窗口的登出方法 </script>

1七、js實現文件下載

// url方式
function
downloadFile(url) { try{ var elemIF = document.createElement("iframe"); elemIF.src = url; elemIF.style.display = "none"; document.body.appendChild(elemIF); }catch(e){ } }
// 表單提交返回數據方式
function
downloadFile(url, paramsInput) { var formStr = null,hideIfm=null; $("body").find("form[target='hideIframe']").remove(); $("body").find("iframe[name='hideIframe']").remove(); formStr = $('<form style="visibility:hidden;" target="hideIframe" method="POST" action="' + url + '">'
        + '<input type="hidden" name="op" value="' + paramsInput.op + '" />'
        + '<input type="hidden" name="name" value="' + paramsInput.name + '" />' + '<input type="hidden" name="params" value="' + paramsInput.params + '" />'
       + '</form>'); hideIfm = $("<iframe name='hideIframe'></iframe>").hide(); $("body").append(hideIfm); $("body").append(formStr); formStr.get(0).submit(); }

 

1八、js監測系統信息(32位、64位)及監測瀏覽器版本

function getCPU(){
       var agent=navigator.userAgent.toLowerCase();
       if(agent.indexOf("win64")>=0||agent.indexOf("wow64")>=0) return "x64";
       return navigator.cpuClass;
}
<script type="text/javascript">  
var userAgent = navigator.userAgent,     
rMsie = /(msie\s|trident.*rv:)([\w.]+)/,     
rFirefox = /(firefox)\/([\w.]+)/,     
rOpera = /(opera).+version\/([\w.]+)/,     
rChrome = /(chrome)\/([\w.]+)/,     
rSafari = /version\/([\w.]+).*(safari)/;    
var browser;    
var version;    
var ua = userAgent.toLowerCase();    
function uaMatch(ua){    
  var match = rMsie.exec(ua);    
  if(match != null){    
    return { browser : "IE", version : match[2] || "0" };    
  }    
  var match = rFirefox.exec(ua);    
  if (match != null) {    
    return { browser : match[1] || "", version : match[2] || "0" };    
  }    
  var match = rOpera.exec(ua);    
  if (match != null) {    
    return { browser : match[1] || "", version : match[2] || "0" };    
  }    
  var match = rChrome.exec(ua);    
  if (match != null) {    
    return { browser : match[1] || "", version : match[2] || "0" };    
  }    
  var match = rSafari.exec(ua);    
  if (match != null) {    
    return { browser : match[2] || "", version : match[1] || "0" };    
  }    
  if (match != null) {    
    return { browser : "", version : "0" };    
  }    
}    
var browserMatch = uaMatch(userAgent.toLowerCase());    
if (browserMatch.browser){    
  browser = browserMatch.browser;    
  version = browserMatch.version;    
}    
document.write(browser+version);            
</script> 
View Code

1九、jquery html方法失效問題(ie8 及如下)

今天遇到jquery中的html方法使用不了,只能用完最基本的innerHTML把內容展現出來。具體緣由還沒找到,確定跟內容有關

$("#content").html(data.content); // ie8及如下狀況下異常
$("#content")[0].innerHTML = data.content;

下面是其它網友的補充:

jQuery通常來講仍是很好用的,但有時候它也會有些問題的,好比jQuery的html()方法設置html代碼,在一種狀況下,ie六、ie七、ie8 下是不能設置html代碼的。本文說的問題只針對ie8(包括ie8)如下的瀏覽器。

  1.什麼狀況下IE六、IE七、IE8 jQuery.html("xxx")方法會設置不上html代碼?

  答:當被加載的的html代碼裏面出現如下狀況,ie8(包括ie8)如下是設置不上html代碼的:

    a) 被設置的html代碼中包含引用其餘js的,如:<script src="Stone.js" type="text/javascript"></script> 這種狀況下,設置html代碼無效。
    b) 被設置的html代碼中包含js 方法的,如:function Stone(){ alert("我叫MT"); },設置html代碼無效。
    c) 被設置的html代碼中有css 樣式的,如:.Stone ul li{ list-style:none;float:left; }等,設置的html代碼無效。[附加:被設置的html代碼中若是包含引用其餘外部

      樣式的,好比:<link href="../Css/style.css" rel="stylesheet" type="text/css" />,雖然不會影響html設置,可是被引用的css是無效的,是沒有樣式的。]

  2.緣由分析:

  答:被設置的html,jQuery只是單純的解析爲html,不會去理會其餘的因素和代碼,全部致使上述問題的出現。

  3.解決方案:

  答:去掉被設置的js引用css引用和代碼便可解決。

20、Ajax中window.location.href沒法跳轉的解決辦法

$.ajax({  
                //async:false, //設置ajax的同步  
                type: "get", //get方式  
                url: "../handler/QueryQuestionnaire.ashx",  
  
                //返回數據成功,將返回的json數據解析,顯示在課程信息列表中  
                success: function (strJson) {  
                     
                    //檢查後臺返回的數據   
                    var dataArray = eval(strJson);  
                      
                    window.location.href = url;//要訪問的網址  
                },  
                //返回數據失敗,彈出錯誤顯示  
                error: function (XmlHttpRequest, textStatus, errorThrown) {  
                    alert(XmlHttpRequest.responseText);  
                }  
}); 
return false;  

通常狀況下要加上:return false

2一、事件綁定匿名函數變量傳參問題

 

  function uploadFile(ob,cnt) {
        var url = getUrl(ob);
      if(ob.files){
          for(var i=0;i<ob.files.length;i++){
              var uidRan = Math.round(Math.random()*10000000000);//改爲const uiRan申明方式(常量)var fd = new FormData();  
              fd.append("fileInput", ob.files[i]);
            var xhr = new XMLHttpRequest();  
            xhr.upload.addEventListener("progress", function(){
                console.info("傳入的值:"+uidRan);
                //uploadProgress(event,cnt,{uid:uidRan});
            }, false); 
            console.info(uidRan);
            xhr.addEventListener("load", uploadComplete, false);   
            xhr.addEventListener("error", function(){uploadFailed(event,cnt);}, false);   
            xhr.addEventListener("abort", uploadCanceled, false);               
            xhr.open("POST", url);//修改成本身服務器接口地址    
            xhr.send(fd);
          }
      }   
  }

 

改爲const uidRan = Math.round(Math.random()*10000000000);申明後正常

2二、複製文本到剪切板

核心js:(親測ie google兼容,其餘沒有測試)

function copyText(text){
        var textCtner = document.createElement("div");
        textCtner.innerHTML = text;
        var txt = textCtner.innerText;//之因此中間轉換,防止text中有dom格式的文本,會致使textarea.innerHTML設置失效 var textarea = document.createElement("textarea");
        textarea.innerHTML = txt; 
        document.body.appendChild(textarea); 
        textarea.select(); // 選擇對象
        document.execCommand("Copy"); // 執行瀏覽器複製命令
        document.body.removeChild(textarea);
}

2三、radio之trgger觸發事件問題

dom容器:

<div class="inputRadio" data-option="{changeInput:'changeEvt()'}"></div>
<button onclick="clickEvt()">trgger</button>

 

腳本:

<script type="text/javascript">
    function changeEvt(){
        alert(1);
    }
    function clickEvt(){
        $("input[name='age'][value='0']").attr("checked",true);
        $("input[name='age'][value='0']").trigger("click");
    }
    (function ($) {
        $.fn.inputRadio = function (op) {
            return this.each(function(){
                var changeInput = eval("(" + $(this).attr("data-option") + ")").changeInput;
                var id = $(this).attr("id");
                var txt = $(this),
                    strHtml = '<input type="radio" name="age" value="1" "/>是'+
                    '<input type="radio" name="age" value="0" "/>否';
                txt.after(strHtml);
                txt.remove();
                $('input[name="age"]').bind("click", function(){
                    var nameA = $(this).attr("name");
                    if(changeInput){
                        eval(changeInput);
                    }
                });
            });
        };
    })(jQuery);
    
    $(".inputRadio").inputRadio();
</script>
View Code

會發現點擊按鈕時,先執行changeEvt()方法,而後才選中目標,這樣就會形成沒法及時獲取選中的值。

改進changeEvt():

function clickEvt(){
    $("input[name='age'][value='0']").attr("checked",true);
    setTimeout(function(){
        $("input[name='age'][value='0']").trigger("click");
    },0);
}

如此便能及時獲取到選中的值

2四、js文件中使用EL表達式方案

  若是js非要放入單獨文件中,能夠把js文件命名爲.jsp文件就能夠了,這樣裏面el就能運行,也就是服務器能夠執行這個文件了。無非頁面引用的時候引用jsp就能夠了。
<script src="myjs.jsp" type="text/javascript> </script>

2五、計算容器剩餘高度

  在開發table組件時,實現表格高度依據父容器動態計算,須要將可見元素的高度都減除掉,代碼邏輯以下:

<script>
      const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
      const MOZ_HACK_REGEXP = /^moz([A-Z])/;function _usableHeight(node){
        let parentNode = node.parentNode,
            firstNode = parentNode.firstElementChild,
            lastNode = parentNode.lastElementChild,
            nextNode = node.nextElementSibling,
            usableHeight = parentNode.clientHeight;//parseInt(getStyle(parentNode, 'height'));
        //let tbHeight = usableHeight*(this.height.replace('%','')-0)/100;
        /* reduce height of other visible doms */
        let fistMarginTop = parseInt(getStyle(firstNode, 'margin-top'))||0,
            fistTop = parseInt(getStyle(firstNode, 'top'))||0;
        usableHeight -= node.offsetTop - firstNode.offsetTop + fistMarginTop + fistTop;
        if(lastNode != node){
          let nextMarginTop = parseInt(getStyle(nextNode, 'margin-top'))||0,
              nextTop = parseInt(getStyle(nextNode, 'top'))||0,
              lastMarginBottom = parseInt(getStyle(lastNode, 'margin-bottom'))||0,
              lastBottom = parseInt(getStyle(lastNode, 'bottom'))||0;
          var lastBth = lastNode.offsetTop - nextNode.offsetTop + lastNode.offsetHeight + nextMarginTop + nextTop + lastMarginBottom + lastBottom;
          usableHeight -= lastBth;
        }
        let nodeMarginBottom = parseInt(getStyle(node, 'margin-bottom')) ||0,
            nodeBottom = parseInt(getStyle(node, 'margin-bottom'))||0;
        usableHeight -= node.offsetHeight + nodeMarginBottom + nodeBottom;//parseInt(getStyle(node, 'height'));return usableHeight;
      }
      function camelCase(name) {
        return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter,
          offset) {
          return offset ? letter.toUpperCase() : letter;
        }).replace(MOZ_HACK_REGEXP, 'Moz$1');
      }
      function getStyle(element, styleName) {
        if (!element || !styleName) return null;
        styleName = camelCase(styleName);
        if (styleName === 'float') {
          styleName = 'cssFloat';
        }
        try {
          const computed = document.defaultView.getComputedStyle(element, '');
          return element.style[styleName] || computed ? computed[styleName] : null;
        } catch (e) {
          return element.style[styleName];
        }
      }
    </script>

 

注意: nextSibling、lastChild,IE將跳過在節點之間產生的空格文檔節點(如:換行字符),而Mozilla不會這樣——FF會把諸如空格換行之類的排版元素視做節點讀取,所以,在ie 中用nextSibling即可讀取到的下一個節點元素,在FF中就須要這樣寫:nextElementSibling了。

 

2六、禁用瀏覽器回退 

// 禁止瀏覽器回退
history.pushState(null, null, document.URL); window.addEventListener('popstate', function () { history.pushState(null, null, document.URL); });
相關文章
相關標籤/搜索