特別板塊: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>
一、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:{"cityId":"110100","cityName":"北京市轄區"}
如上字符串所示,字符串1是在java後臺生成,經過structs2傳遞到前臺後,js中取得的字符串卻變成了字符串2的樣子,
其中的」變成了"使用的時候用StringEscapeUtils.unescapeHtml(字符串2)) 解下碼就行,即可取得原字符串1。
由以上能夠找到解決方案:
一、後臺傳前臺:[如json字符串].replaceAll("[\"']", """),先將字符串中的單引號和雙引號轉出""",
傳到前臺後瀏覽器會自動解析格式;
二、前臺傳後臺:都是本身寫的,這個就不要偷懶啦,注意下格式就好了。
三、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; }
方法二:使用字符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; }
五、比較完美的日期格式化
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>
輸出結果:/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); };
十一、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的方式巧妙地解決這個問題!
十二、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);
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 " "), // 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"); }; } }());
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>
效果:
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>
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>
會發現點擊按鈕時,先執行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); });