// leanote 通用方法 //-------------- // 命名空间 //-------------- // 最上级变量 var LEA = {}; // 命名空间 var Notebook = { cache: {}, // notebookId => {Title, Seq} } var Note = { cache: {}, // noteId => {Title, Tags, Content, Desc} }; // var UserInfo = {}; // 博客有问题, 会覆盖 var Tag = {}; var Notebook = {}; var Share = {}; var Mobile = {}; // 手机端处理 var LeaAce = {}; // markdown var Converter; var MarkdownEditor; var ScrollLink; var MD; //--------------------- // 公用方法 function trimLeft(str, substr) { if(!substr || substr == " ") { return $.trim(str); } while(str.indexOf(substr) == 0) { str = str.substring(substr.length); } return str; } function json(str) { return eval("(" + str + ")") } // '<div id="?" class="?" onclick="?">' function t() { var args = arguments; if(args.length <= 1) { return args[0]; } var text = args[0]; if(!text) { return text; } // 先把所有的?替换成, 很有可能替换的值有?会造成循环,没有替换想要的 var pattern = "LEAAEL" text = text.replace(/\?/g, pattern); // args[1] 替换第一个? for(var i = 1; i <= args.length; ++i) { text = text.replace(pattern, args[i]); } return text; } var tt = t; // 当slimscroll滑动时t被重新赋值了 // 判断数组是否相等 function arrayEqual(a, b) { a = a || []; b = b || []; return a.join(",") == b.join(","); } // 是否是数组 function isArray(obj) { return Object.prototype.toString.call(obj) === '[object Array]'; } /** * 是否为空 * 可判断任意类型,string array */ function isEmpty(obj) { if(!obj) { return true; } if(isArray(obj)) { if(obj.length == 0) { return true; } } return false; } //------------ //得到form的数据 //返回json function getFormJsonData(formId) { var data = formArrDataToJson($('#' + formId).serializeArray()); return data; } //$('#form').serializeArray()的数据[{name: a, value: b}, {name: "c[]", value: d}] //转成{a:b} function formArrDataToJson(arrData) { var datas = {}; var arrObj= {}; // {a:[1, 2], b:[2, 3]}; for(var i in arrData) { var attr = arrData[i].name; var value = arrData[i].value; // 判断是否是a[]形式 if(attr.substring(attr.length-2, attr.length) == '[]') { attr = attr.substring(0, attr.length-2); if(arrObj[attr] == undefined) { arrObj[attr] = [value]; } else { arrObj[attr].push(value); } continue; } datas[attr] = value; } return $.extend(datas, arrObj); } //将serialize的的form值转成json function formSerializeDataToJson(formSerializeData) { var arr = formSerializeData.split("&"); var datas = {}; var arrObj= {}; // {a:[1, 2], b:[2, 3]}; for(var i = 0; i < arr.length; ++i) { var each = arr[i].split("="); var attr = decodeURI(each[0]); var value = decodeURI(each[1]); // 判断是否是a[]形式 if(attr.substring(attr.length-2, attr.length) == '[]') { attr = attr.substring(0, attr.length-2); if(arrObj[attr] == undefined) { arrObj[attr] = [value]; } else { arrObj[attr].push(value); } continue; } datas[attr] = value; } return $.extend(datas, arrObj); } // ajax请求返回结果后的操作 // 用于ajaxGet(), ajaxPost() function _ajaxCallback(ret, successFunc, failureFunc) { // 总会执行 if(ret === true || ret == "true" || typeof ret == "object") { // 是否是NOTELOGIN if(ret && typeof ret == "object") { if(ret.Msg == "NOTLOGIN") { alert("你还没有登录, 请先登录!"); return; } } if(typeof successFunc == "function") { successFunc(ret); } } else { if(typeof failureFunc == "function") { failureFunc(ret); } else { alert("error!") } } } function _ajax(type, url, param, successFunc, failureFunc, async) { log("-------------------ajax:"); log(url); log(param); if(typeof async == "undefined") { async = true; } else { async = false; } return $.ajax({ type: type, url: url, data: param, async: async, // 是否异步 success: function(ret) { _ajaxCallback(ret, successFunc, failureFunc); }, error: function(ret) { _ajaxCallback(ret, successFunc, failureFunc); } }); } /** * 发送ajax get请求 * @param url * @param param * @param successFunc * @param failureFunc * @param hasProgress * @param async 是否异步 * @returns */ function ajaxGet(url, param, successFunc, failureFunc, async) { return _ajax("GET", url, param, successFunc, failureFunc, async); } /** * 发送post请求 * @param url * @param param * @param successFunc * @param failureFunc * @param hasProgress * @param async 是否异步, 默认为true * @returns */ function ajaxPost(url, param, successFunc, failureFunc, async) { _ajax("POST", url, param, successFunc, failureFunc, async); } function ajaxPostJson(url, param, successFunc, failureFunc, async) { log("-------------------ajaxPostJson:"); log(url); log(param); // 默认是异步的 if(typeof async == "undefined") { async = true; } else { async = false; } $.ajax({ url : url, type : "POST", contentType: "application/json; charset=utf-8", datatype: "json", async: async, data : JSON.stringify(param), success : function(ret, stats) { _ajaxCallback(ret, successFunc, failureFunc); }, error: function(ret) { _ajaxCallback(ret, successFunc, failureFunc); } }); } function findParents(target, selector) { if($(target).is(selector)) { return $(target); } var parents = $(target).parents(); for(var i = 0; i < parents.length; ++i) { log(parents.eq(i)) if(parents.eq(i).is(selector)) { return parents.seq(i); } } return null; } /* ajaxPostJson( "http://localhost:9000/notebook/index?i=100&name=life", {Title: "you can", UserId:"52a9e409f4ea49d6576fdbca", Subs:[{title: "xxxxx", Seq:11}, {title:"life..."}]}, function(e) { log(e); }); */ function getVendorPrefix() { // 使用body是为了避免在还需要传入元素 var body = document.body || document.documentElement, style = body.style, vendor = ['webkit', 'khtml', 'moz', 'ms', 'o'], i = 0; while (i < vendor.length) { // 此处进行判断是否有对应的内核前缀 if (typeof style[vendor[i] + 'Transition'] === 'string') { return vendor[i]; } i++; } } //----------------- // 切换编辑器时要修改tabIndex function editorIframeTabindex(index) { var $i = $("#editorContent"); // var $i = $("#editorContent_ifr"); // if($i.size() == 0) { $i.attr("tabindex", index); setTimeout(function() { $i.attr("tabindex", index); }, 500); setTimeout(function() { $i.attr("tabindex", index); }, 1000); // } else { // $i.attr("tabindex", index); // } } //切换编辑器 LEA.isM = false; LEA.isMarkdownEditor = function() { return LEA.isM; } function switchEditor(isMarkdown) { LEA.isM = isMarkdown; // 富文本永远是2 if(!isMarkdown) { $("#editor").show(); $("#mdEditor").css("z-index", 1).hide(); // 刚开始没有 editorIframeTabindex(2); $("#wmd-input").attr("tabindex", 3); $("#leanoteNav").show(); } else { $("#mdEditor").css("z-index", 3).show(); editorIframeTabindex(3); $("#wmd-input").attr("tabindex", 2); $("#leanoteNav").hide(); } } // editor 设置内容 // 可能是tinymce还没有渲染成功 var previewToken = "<div style='display: none'>FORTOKEN</div>" var clearIntervalForSetContent; function setEditorContent(content, isMarkdown, preview) { if(!content) { content = ""; } if(clearIntervalForSetContent) { clearInterval(clearIntervalForSetContent); } if(!isMarkdown) { // 先destroy之前的ace /* if(typeof tinymce != "undefined" && tinymce.activeEditor) { var editor = tinymce.activeEditor; var everContent = $(editor.getBody()); if(everContent) { LeaAce.destroyAceFromContent(everContent); } } */ $("#editorContent").html(content); if(typeof tinymce != "undefined" && tinymce.activeEditor) { var editor = tinymce.activeEditor; editor.setContent(content); /* if(LeaAce.canAce() && LeaAce.isAce) { try { LeaAce.initAceFromContent(editor); } catch(e) { log(e); } } else { // 为了在firefox下有正常的显示 $("#editorContent pre").removeClass("ace-tomorrow ace_editor"); } */ editor.undoManager.clear(); // 4-7修复BUG } else { // 等下再设置 clearIntervalForSetContent = setTimeout(function() { setEditorContent(content, false); }, 100); } } else { /* $("#wmd-input").val(content); $("#wmd-preview").html(""); // 防止先点有的, 再点tinymce再点没内容的 if(!content || preview) { // 没有内容就不要解析了 $("#wmd-preview").html(preview).css("height", "auto"); if(ScrollLink) { ScrollLink.onPreviewFinished(); // 告诉scroll preview结束了 } } else { // 还要清空preview if(MarkdownEditor) { $("#wmd-preview").html(previewToken + "<div style='text-align:center; padding: 10px 0;'><img src='http://leanote.com/images/loading-24.gif' /> 正在转换...</div>"); MarkdownEditor.refreshPreview(); } else { // 等下再设置 clearIntervalForSetContent = setTimeout(function() { setEditorContent(content, true, preview); }, 200); } } */ if(MD) { MD.setContent(content); } else { clearIntervalForSetContent = setTimeout(function() { setEditorContent(content, true); }, 100); } } } // preview是否为空 function previewIsEmpty(preview) { if(!preview || preview.substr(0, previewToken.length) == previewToken) { return true; } return false; } // 有tinymce得到的content有<html>包围 function getEditorContent(isMarkdown) { if(!isMarkdown) { var editor = tinymce.activeEditor; if(editor) { var content = $(editor.getBody()).clone(); // 删除toggle raw content.find('.toggle-raw').remove(); // 替换掉ace editor var pres = content.find('pre'); for(var i = 0 ; i < pres.length; ++i) { var pre = pres.eq(i); var id = pre.attr('id'); var aceEditor = LeaAce.getAce(id); if(aceEditor) { var val = aceEditor.getValue(); val = val.replace(/</g, '<').replace(/>/g, '>'); pre.removeAttr('style', '').removeAttr('contenteditable').removeClass('ace_editor'); pre.html(val); } } // 去掉恶心的花瓣注入 // <pinit></pinit> // 把最后的<script>..</script>全去掉 content.find("pinit").remove(); content.find(".thunderpin").remove(); content.find(".pin").parent().remove(); content = $(content).html(); if(content) { while(true) { var lastEndScriptPos = content.lastIndexOf("</script>"); if (lastEndScriptPos == -1) { return content; } var length = content.length; // 证明</script>在最后, 去除之 if(length - 9 == lastEndScriptPos) { var lastScriptPos = content.lastIndexOf("<script "); if(lastScriptPos == -1) { lastScriptPos = content.lastIndexOf("<script>"); } if(lastScriptPos != -1) { content = content.substring(0, lastScriptPos); } else { return content; } } else { // 不在最后, 返回 return content; } } } return content; } } else { // return [$("#wmd-input").val(), $("#wmd-preview").html()] return [MD.getContent(), '<div>' + $("#preview-contents").html() + '</div>'] } } // 禁用编辑 LEA.editorStatus = true; function disableEditor() { var editor = tinymce.activeEditor; if(editor) { editor.hide(); LEA.editorStatus = false; $("#mceTollbarMark").show().css("z-index", 1000); } // toolbar 来个遮着... } function enableEditor() { if(LEA.editorStatus) { return; } $("#mceTollbarMark").css("z-index", -1).hide(); var editor = tinymce.activeEditor; if(editor) { editor.show(); } } //----------- // dialog //----------- function showDialog(id, options) { $("#leanoteDialog #modalTitle").html(options.title); $("#leanoteDialog .modal-body").html($("#" + id + " .modal-body").html()); $("#leanoteDialog .modal-footer").html($("#" + id + " .modal-footer").html()); delete options.title; options.show = true; $("#leanoteDialog").modal(options); } function hideDialog(timeout) { if(!timeout) { timeout = 0; } setTimeout(function() { $("#leanoteDialog").modal('hide'); }, timeout); } // 更通用 function closeDialog() { $(".modal").modal('hide'); } // 原生的 function showDialog2(id, options) { options = options || {}; options.show = true; $(id).modal(options); } function hideDialog2(id, timeout) { if(!timeout) { timeout = 0; } setTimeout(function() { $(id).modal('hide'); }, timeout); } // 远程 function showDialogRemote(url, data) { data = data || {}; url += "?"; for(var i in data) { url += i + "=" + data[i] + "&"; } $("#leanoteDialogRemote").modal({remote: url}); } function hideDialogRemote(timeout) { if(timeout) { setTimeout(function() { $("#leanoteDialogRemote").modal('hide'); }, timeout); } else { $("#leanoteDialogRemote").modal('hide'); } } //--------------- // notify // 没用 $(function() { if($.pnotify) { $.pnotify.defaults.delay = 1000; } }) function notifyInfo(text) { $.pnotify({ title: '通知', text: text, type: 'info', styling: 'bootstrap' }); } function notifyError(text) { $.pnotify.defaults.delay = 2000 $.pnotify({ title: '通知', text: text, type: 'error', styling: 'bootstrap' }); } function notifySuccess(text) { $.pnotify({ title: '通知', text: text, type: 'success', styling: 'bootstrap' }); } // 对Date的扩展,将 Date 转化为指定格式的String //月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符, //年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) //例子: //(new Date()).format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 //(new Date()).format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18 Date.prototype.format = function(fmt) { //author: meizz var o = { "M+" : this.getMonth()+1, //月份 "d+" : this.getDate(), //日 "h+" : this.getHours(), //小时 "m+" : this.getMinutes(), //分 "s+" : this.getSeconds(), //秒 "q+" : Math.floor((this.getMonth()+3)/3), //季度 "S" : this.getMilliseconds() //毫秒 }; if(/(y+)/.test(fmt)) fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); for(var k in o) if(new RegExp("("+ k +")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); return fmt; } //2014-01-06T18:29:48.802+08:00 function goNowToDatetime(goNow) { if(!goNow) { return ""; } return goNow.substr(0, 10) + " " + goNow.substr(11, 8); } function getCurDate() { return (new Date()).format("yyyy-M-d"); } // 回车键的动作 function enter(parent, children, func) { if(!parent) { parent = "body"; } $(parent).on("keydown", children, function(e) { if (e.keyCode == 13) { func.call(this); } }); } // 回车则blue function enterBlur(parent, children) { if(!parent) { parent = "body"; } if(!children) { children = parent; parent = "body"; } $(parent).on("keydown", children, function(e) { if (e.keyCode == 13) { $(this).trigger("blur"); } }); } // 生成mongodb ObjectId function getObjectId() { return ObjectId(); } //----------------------------------------- function resizeEditor(second) { var ifrParent = $("#editorContent_ifr").parent(); ifrParent.css("overflow", "auto"); var height = $("#editorContent").height(); ifrParent.height(height); // log(height + '---------------------------------------') $("#editorContent_ifr").height(height); // life 12.9 // inline editor $("#editorContent").css("top", $("#mceToolbar").height()); /* // 第一次时可能会被改变 if(!second) { setTimeout(function() { resizeEditorHeight(true); }, 1000); } */ } //---------- // msg位置固定 function showMsg(msg, timeout) { $("#msg").html(msg); if(timeout) { setTimeout(function() { $("#msg").html(""); }, timeout) } } function showMsg2(id, msg, timeout) { $(id).html(msg); if(timeout) { setTimeout(function() { $(id).html(""); }, timeout) } } //-------------- // type == danger, success, warning function showAlert(id, msg, type, id2Focus) { $(id).html(msg).removeClass("alert-danger").removeClass("alert-success").removeClass("alert-warning").addClass("alert-" + type).show(); if(id2Focus) { $(id2Focus).focus(); } } function hideAlert(id, timeout) { if(timeout) { setTimeout(function() { $(id).hide(); }, timeout); } else { $(id).hide(); } } //------------------- // for leanote ajax // post // return {Ok, Msg, Data} // btnId 是按钮包括# function post(url, param, func, btnId) { var btnPreText; if(btnId) { $(btnId).button("loading"); // html("正在处理").addClass("disabled"); } ajaxPost(url, param, function(ret) { if(btnId) { $(btnId).button("reset"); } if (typeof ret == "object") { if(typeof func == "function") { func(ret); } } else { alert("leanote出现了错误!"); } }); } // 是否是正确的email function isEmail(email) { var myreg = /^([a-zA-Z0-9]+[_|\_|\.|\-]?)*[a-zA-Z0-9\-]+@([a-zA-Z0-9\-]+[_|\_|\.|\-]?)*[a-zA-Z0-9\-]+\.[0-9a-zA-Z]{2,3}$/; return myreg.test(email); } // 正确返回该email function isEmailFromInput(inputId, msgId, selfBlankMsg, selfInvalidMsg) { var val = $(inputId).val(); var msg = function() {}; if(msgId) { msg = function(msgId, msg) { showAlert(msgId, msg, "danger", inputId); } } if(!val) { msg(msgId, selfBlankMsg || getMsg("inputEmail")); } else if(!isEmail(val)) { msg(msgId, selfInvalidMsg || getMsg("errorEmail")); } else { return val; } } // 复制文本 function initCopy(aId, postFunc) { // 定义一个新的复制对象 var clip = new ZeroClipboard(document.getElementById(aId), { moviePath: "/js/ZeroClipboard/ZeroClipboard.swf" }); // 复制内容到剪贴板成功后的操作 clip.on('complete', function(client, args) { postFunc(args); }); } function showLoading() { $("#loading").css("visibility", "visible"); } function hideLoading() { $("#loading").css("visibility", "hidden"); } // 注销, 先清空cookie function setCookie(c_name, value, expiredays){ var exdate = new Date(); exdate.setDate(exdate.getDate() + expiredays); document.cookie = c_name+ "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString()); } function logout() { setCookie("LEANOTE_SESSION", '', -1); location.href = UrlPrefix + "/logout?id=1"; } // 得到图片width, height, callback(ret); ret = {width:11, height:33} function getImageSize(url, callback) { var img = document.createElement('img'); function done(width, height) { img.parentNode.removeChild(img); callback({width: width, height: height}); } img.onload = function() { done(img.clientWidth, img.clientHeight); }; img.onerror = function() { done(); }; img.src = url; var style = img.style; style.visibility = 'hidden'; style.position = 'fixed'; style.bottom = style.left = 0; style.width = style.height = 'auto'; document.body.appendChild(img); } // 插件中使用 function hiddenIframeBorder() { $('.mce-window iframe').attr("frameborder", "no").attr("scrolling", "no"); } var email2LoginAddress = { 'qq.com': 'http://mail.qq.com', 'gmail.com': 'http://mail.google.com', 'sina.com': 'http://mail.sina.com.cn', '163.com': 'http://mail.163.com', '126.com': 'http://mail.126.com', 'yeah.net': 'http://www.yeah.net/', 'sohu.com': 'http://mail.sohu.com/', 'tom.com': 'http://mail.tom.com/', 'sogou.com': 'http://mail.sogou.com/', '139.com': 'http://mail.10086.cn/', 'hotmail.com': 'http://www.hotmail.com', 'live.com': 'http://login.live.com/', 'live.cn': 'http://login.live.cn/', 'live.com.cn': 'http://login.live.com.cn', '189.com': 'http://webmail16.189.cn/webmail/', 'yahoo.com.cn': 'http://mail.cn.yahoo.com/', 'yahoo.cn': 'http://mail.cn.yahoo.com/', 'eyou.com': 'http://www.eyou.com/', '21cn.com': 'http://mail.21cn.com/', '188.com': 'http://www.188.com/', 'foxmail.coom': 'http://www.foxmail.com' }; function getEmailLoginAddress(email) { if(!email) { return; } var arr = email.split('@'); if(!arr || arr.length < 2) { return; } var addr = arr[1]; return email2LoginAddress[addr] || "http://mail." + addr; } // 返回是否是re.Ok == true function reIsOk(re) { return re && typeof re == "object" && re.Ok; } // marker // 下拉扩展工具栏用, 点击文档导航用, 切换编辑模式时用 LEA.bookmark = null; LEA.hasBookmark = false; function saveBookmark() { try { LEA.bookmark = tinymce.activeEditor.selection.getBookmark(); // 光标, 为了处理后重新定位到那个位置 // 如果之前没有focus, 则会在文档开头设置bookmark, 添加一行, 不行. // $p不是<p>, 很诡异 // 6-5 if(LEA.bookmark && LEA.bookmark.id) { var $ic = $($("#editorContent_ifr").contents()); var $body = $ic.find("body"); var $p = $body.children().eq(0); // 找到 if($p.is("span")) { var $children = $p; var $c = $children.eq(0); if($c.attr("id") == LEA.bookmark.id + "_start") { LEA.hasBookmark = false; $c.remove(); } else { LEA.hasBookmark = true; } } else if($p.is("p")) { var $children = $p.children(); if($children.length == 1 && $.trim($p.text()) == "") { var $c = $children.eq(0); if($c.attr("id") == LEA.bookmark.id + "_start") { LEA.hasBookmark = false; $p.remove(); } else { LEA.hasBookmark = true; } } else { LEA.hasBookmark = true; } } } } catch(e) { } } function restoreBookmark() { try { if(LEA.hasBookmark) { // 必须要focus()!!! var editor = tinymce.activeEditor; editor.focus(); editor.selection.moveToBookmark(LEA.bookmark); } } catch(e) { } } // 是否是手机浏览器 // var u = navigator.userAgent; // LEA.isMobile = /Mobile|Android|iPhone/i.test(u); // LEA.isMobile = u.indexOf('Android')>-1 || u.indexOf('Linux')>-1; // LEA.isMobile = false; //if($("body").width() < 600) { // location.href = "/mobile/index"; //} // 表单验证 var vd = { isInt: function(o) { var intPattern=/^0$|^[1-9]\d*$/; //整数的正则表达式 result=intPattern.test(o); return result; }, isNumeric: function(o) { return $.isNumeric(o); }, isFloat: function(floatValue){ var floatPattern=/^0(\.\d+)?$|^[1-9]\d*(\.\d+)?$/; //小数的正则表达式 result=floatPattern.test(floatValue); return result; }, isEmail: function(emailValue){ var emailPattern=/^([a-zA-Z0-9]+[_|\_|\.|\-]?)*[a-zA-Z0-9\-]+@([a-zA-Z0-9\-]+[_|\_|\.|\-]?)*[a-zA-Z0-9\-]+\.[0-9a-zA-Z]{2,3}$/; //邮箱的正则表达式 result=emailPattern.test(emailValue); return result; }, isBlank: function(o) { return !$.trim(o); }, has_special_chars: function(o) { return /['"#$%&\^<>\?*]/.test(o); }, // life // 动态验证 // rules = {max: function() {}}; // <input data-rules='[{rule: 'requried', msg:"请填写标题"}]' data-msg_target="#msg"/> init: function(form, rule_funcs) { var get_val = function(target) { if(target.is(":checkbox")) { var name = target.attr('name'); var val = $('input[name="' + name + '"]:checked').length; return val; } else if(target.is(":radio")) { } else { return target.val(); } } var default_rule_funcs = { // 必须输入 required: function(target) { return get_val(target); }, // 最少 min: function(target, rule) { var val = get_val(target); if(val === "" && !is_required(target)) { return true; } if(val < rule.data) { return false; } return true; }, minLength: function(target, rule) { var val = get_val(target); if(val === "" && !is_required(target)) { return true; } if(val.length < rule.data) { return false; } return true; }, email: function(target, rule) { var val = get_val(target); if(val === "" && !is_required(target)) { return true; } return vd.isEmail(val); }, noSpecialChars: function(target) { var val = get_val(target); if(!val) { return true; } if(/[^0-9a-zzA-Z_\-]/.test(val)) { return false; } return true; }, password: function(target, rule) { var val = get_val(target); if(val === "" && !is_required(target)) { return true; } return val.length >= 6 }, equalTo: function(target, rule) { var val = get_val(target); if(val === "" && !is_required(target)) { return true; } return $(rule.data).val() == val; } } rule_funcs = rule_funcs || {}; rule_funcs = $.extend(default_rule_funcs, rule_funcs); var rules = {}; // name对应的 var msg_targets = {}; // 是否是必须输入的 function is_required(target) { var name = get_name(target); var rules = get_rules(target, name); var required_rule = rules[0]; if(required_rule['rule'] == "required") { return true; } return false; } // 先根据msg_target_name, 再根据name function get_rules(target, name) { if(!rules[name]) { rules[name] = eval("(" + target.data("rules") + ")"); } return rules[name]; } // 以name为索引, 如果多个input name一样, 但希望有不同的msg怎么办? // 添加data-u_name="" function get_msg_target(target, name) { if(!msg_targets[name]) { var t = target.data("msg_target"); if(!t) { // 在其父下append一个 var msg_o = $('<div class="help-block alert alert-warning" style="display: block;"></div>'); target.parent().append(msg_o); msg_targets[name] = msg_o; } else { msg_targets[name] = $(t); } } return msg_targets[name]; } function hide_msg(target, name) { var msgT = get_msg_target(target, name); // 之前是正确信息, 那么不隐藏 if(!msgT.hasClass("alert-success")) { msgT.hide(); } } function show_msg(target, name, msg, msgData) { var t = get_msg_target(target, name); t.html(getMsg(msg, msgData)).removeClass("hide alert-success").addClass("alert-danger").show(); } // 验证前修改 function pre_fix(target) { var fix_name = target.data("pre_fix"); if(!fix_name) { return; } switch(fix_name) { case 'int': int_fix(target); break; case 'price': price_fix(target); break; case 'decimal': decimal_fix(target); break; } } // 验证各个rule // 正确返回true function apply_rules(target, name) { var rules = get_rules(target, name); // 是否有前置fix data-pre_fix pre_fix(target); if(!rules) { return true; } for(var i = 0; i < rules.length; ++i) { var rule = rules[i]; var rule_func_name = rule.rule; var msg = rule.msg; var msgData = rule.msgData; if(!rule_funcs[rule_func_name](target, rule)) { show_msg(target, name, msg, msgData); return false; } } hide_msg(target, name); // 这里, 如果都正确, 是否有sufix验证其它的 var post_rule = target.data('post_rule'); if(post_rule) { setTimeout(function() { var post_target = $(post_rule); apply_rules(post_target, get_name(post_target)); },0); } return true; } function focus_func(e) { var target = $(e.target); var name = get_name(target); // 验证如果有错误, 先隐藏 hide_msg(target, name); // key up的时候pre_fix pre_fix(target); } function unfocus_func(e) { var target = $(e.target); var name = get_name(target); // 验证各个rule apply_rules(target, name); } // u_name是唯一名, msg, rule的索引 function get_name(target) { return target.data('u_name') || target.attr("name") || target.attr("id"); } var $allElems = $(form).find('[data-rules]'); var $form = $(form); $form.on({ keyup: function(e) { if(e.keyCode != 13) { // 不是enter focus_func(e) } }, blur: unfocus_func, }, 'input[type="text"], input[type="password"]'); $form.on({ change: function(e) { if($(this).val()) { focus_func(e); } else { unfocus_func(e); } } }, 'select'); $form.on({ change: function(e) { unfocus_func(e); } }, 'input[type="checkbox"]'); // 验证所有的 this.valid = function() { var $ts = $allElems; var is_valid = true; for(var i = 0; i < $ts.length; ++i) { var target = $ts.eq(i); var name = get_name(target); // 验证各个rule if(!apply_rules(target, name)) { is_valid = false; target.focus(); return false } else { } } return is_valid; } // 验证某一元素(s) // .num-in, #life this.validElement = function(targets) { var targets = $(targets); var ok = true; for(var i = 0; i < targets.length; ++i) { var target = targets.eq(i); var name = get_name(target); // 验证各个rule if(!apply_rules(target, name)) { ok = false; } } return ok; } } }; // 返回hash的#a=1&b=3 返回{a:1, b:3} function getHashObject() { var hash = location.hash; // #life if(!hash) { return {}; } var hashKV = hash.substr(1); var kvs = hashKV.split("&"); var kvsObj = {}; for(var i = 0; i < kvs.length; ++i) { var kv = kvs[i].split('='); if(kv.length == 2) { kvsObj[kv[0]] = kv[1]; } } return kvsObj; } function getHash(key, value) { var kvs = getHashObject(); return kvs[key]; } function setHash(key, value) { var hash = location.hash; // #life if(!hash) { location.href = "#" + key + "=" + value; return; } var kvs = getHashObject(); kvs[key] = value; var str = ""; for(var i in kvs) { if(kvs[i]) { if(str) { str += "&"; } str += i + '=' + kvs[i]; } } location.href = "#" + str; } // 防止js注入 function trimTitle(title) { return title.replace(/<.*?script.*?>/g, ''); }; function toHtmlEntity(html) { return (html + '').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); };