html:
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta name="renderer" content="webkit"> <title></title> <link rel="stylesheet" href="assets/trumbowyg.css"> ...... <script type="text/javascript" src="js/jquery.js"></script> ...... <script type="text/javascript" src="assets/trumbowyg.js"></script> ...... <script type="text/javascript" src="assets/trumbowyg.upload.js"></script> </head> <body> <div id="odiv" style="display:none;position:absolute;z-index:100;"> <img src="assets/pic/sx.png" title="缩小" border="0" alt="缩小" onclick="sub(-1);"/> <img src="assets/pic/fd.png" title="放大" border="0" alt="放大" onclick="sub(1)"/> <img src="assets/pic/cz.png" title="重置" border="0" alt="重置" onclick="sub(0)"/> <img src="assets/pic/sc.png" title="删除" border="0" alt="删除" onclick="del();odiv.style.display=\'none\';"/> </div> <div onmousedown="show_element(event)" style="clear:both" id="customized-buttonpane" class="editor"></div> </body> </head>
trumbowyg.css
.trumbowyg-box,.editor{clear:both;display:block;position:relative;border:1px solid #DDD;width:100%;min-height:300px;margin:17px auto}.trumbowyg-box .editor{margin:0 auto;background:#FEFEFE}.trumbowyg-box.trumbowyg-fullscreen{background:#FEFEFE}.trumbowyg-editor,.trumbowyg-textarea{position:relative;padding:1% 2%;min-height:300px;width:96%;border-style:none;resize:none;outline:none}.trumbowyg-box-blur .trumbowyg-editor *{color:transparent !important;text-shadow:0 0 7px #333}.trumbowyg-box-blur .trumbowyg-editor img{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=20);opacity:0.2}.trumbowyg-textarea{position:relative;display:block;overflow:auto;border:none;white-space:normal}.trumbowyg-button-pane{position:relative;width:100%;background:#ecf0f1;border-bottom:1px solid #d7e0e2;margin:0;padding:0;list-style-type:none;line-height:10px}.trumbowyg-button-pane li{display:inline-block;text-align:center;overflow:hidden}.trumbowyg-button-pane li.trumbowyg-separator{width:1px;background:#d7e0e2;margin:0 5px;height:35px}.trumbowyg-button-pane.trumbowyg-disable li:not(.trumbowyg-not-disable) button{opacity:.2;cursor:default}.trumbowyg-button-pane.trumbowyg-disable li.trumbowyg-separator{background:#e3e9eb}.trumbowyg-button-pane:not(.trumbowyg-disable) li button:hover,.trumbowyg-button-pane:not(.trumbowyg-disable) li button:focus,.trumbowyg-button-pane li button.trumbowyg-active,.trumbowyg-button-pane li.trumbowyg-not-disable button:hover,.trumbowyg-button-pane li.trumbowyg-not-disable button:focus{outline:none}.trumbowyg-button-pane li .trumbowyg-open-dropdown:after{display:block;content:" ";position:absolute;top:25px;right:3px;height:0;width:0;border:3px solid transparent;border-top-color:#555}.trumbowyg-button-pane .trumbowyg-buttons-right{float:right;width:auto}.trumbowyg-button-pane .trumbowyg-buttons-right button{float:left}.trumbowyg-dropdown{width:200px;border:1px solid #ecf0f1;padding:5px 0;border-top:none;background:#FFF;margin-left:-1px;-moz-box-shadow:rgba(0,0,0,0.1) 0 2px 3px;-webkit-box-shadow:rgba(0,0,0,0.1) 0 2px 3px;box-shadow:rgba(0,0,0,0.1) 0 2px 3px}.trumbowyg-dropdown button{display:block;width:100%;height:35px;line-height:35px;text-decoration:none;background:#FFF;padding:0 14px;color:#333;border:none;cursor:pointer;text-align:left;font-size:15px;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s}.trumbowyg-dropdown button:hover,.trumbowyg-dropdown button:focus{background:#ecf0f1}.trumbowyg-modal{position:absolute;top:0;left:50%;margin-left:-260px;width:520px;height:290px;overflow:hidden}.trumbowyg-modal-box{position:absolute;top:0;left:50%;margin-left:-250px;width:400px;padding: 10px 10px 35px 30px;z-index:1;background-color:#FFF;text-align:center;-moz-box-shadow:rgba(0,0,0,0.2) 0 2px 3px;-webkit-box-shadow:rgba(0,0,0,0.2) 0 2px 3px;box-shadow:rgba(0,0,0,0.2) 0 2px 3px}.trumbowyg-modal-box .trumbowyg-modal-title{font-size:24px;font-weight:bold;margin:0 0 20px;padding:15px 0 13px;display:block;border-bottom:1px solid #EEE;color:#333;background:#fbfcfc}.trumbowyg-modal-box .trumbowyg-progress{width:80%;background:#F00;height:3px;position:absolute;top:58px}.trumbowyg-modal-box .trumbowyg-progress .trumbowyg-progress-bar{background:#2BC06A;height:100%;-moz-transition:width 0.15s linear;-o-transition:width 0.15s linear;-webkit-transition:width 0.15s linear;transition:width 0.15s linear}.trumbowyg-modal-box input,input[type=text]{width:100%;}.trumbowyg-modal-box label{display:block;position:relative;margin:15px 12px;height:27px;line-height:27px;overflow:hidden}.trumbowyg-modal-box label .trumbowyg-input-infos{display:block;text-align:left;height:25px;line-height:25px;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s}.trumbowyg-modal-box label .trumbowyg-input-infos span{display:block;color:#859fa5;background-color:#fbfcfc;border:1px solid #DEDEDE;padding:0 2%;width:19.5%}.trumbowyg-modal-box label .trumbowyg-input-infos span.trumbowyg-msg-error{color:#e74c3c}.trumbowyg-modal-box label.trumbowyg-input-error input,.trumbowyg-modal-box label.trumbowyg-input-error textarea{border:1px solid #e74c3c}.trumbowyg-modal-box label.trumbowyg-input-error .trumbowyg-input-infos{margin-top:-27px}.trumbowyg-modal-box label input{position:absolute;top:0;right:20px;height:25px;line-height:25px;border:1px solid #DEDEDE;background:transparent;width:72%;padding:0 2%;margin:0 0 0 23%;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s}.trumbowyg-modal-box label input:hover,.trumbowyg-modal-box label input:focus{outline:none;border:1px solid #95a5a6}.trumbowyg-modal-box label input:focus{background:rgba(230,230,255,0.1)}.trumbowyg-modal-box .error{margin-top:25px;display:block;color:red}.trumbowyg-modal-box .trumbowyg-modal-button{position:absolute;bottom:10px;right:0;text-decoration:none;color:#FFF;display:block;width:70px; height:35px;line-height:33px;margin:0 10px;background-color:#333;border:none;border-top:none;cursor:pointer;font-family:"Trebuchet MS", Helvetica, Verdana, sans-serif;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s;margin-right: 100px;}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit{right:110px;background:#2bc06a}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:hover,.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:focus{background:#40d47e;outline:none}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:active{background:#25a25a}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset{background:#b33528}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:hover,.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:focus{background:#d14233;outline:none}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:active{background:#962d22}.trumbowyg-overlay{position:absolute;background-color:rgba(255,255,255,0.5);width:100%;left:0;display:none}.trumbowyg-fullscreen.trumbowyg-box,.trumbowyg-fullscreen .editor{border:none}.trumbowyg-fullscreen .trumbowyg-overlay{height:100% !important}.trumbowyg-editor object,.trumbowyg-editor embed,.trumbowyg-editor video,.trumbowyg-editor img{max-width:100%}.trumbowyg-editor video,.trumbowyg-editor img{cursor:move}.trumbowyg-editor.trumbowyg-reset-css{background:#FEFEFE !important;font-family:"Trebuchet MS", Helvetica, Verdana, sans-serif !important;font-size:14px !important;line-height:1.45em !important;white-space:normal !important;color:#333}.trumbowyg-editor.trumbowyg-reset-css a{color:#15c !important;text-decoration:underline !important}.trumbowyg-editor.trumbowyg-reset-css div,.trumbowyg-editor.trumbowyg-reset-css p,.trumbowyg-editor.trumbowyg-reset-css ul,.trumbowyg-editor.trumbowyg-reset-css ol,.trumbowyg-editor.trumbowyg-reset-css blockquote{box-shadow:none !important;background:none !important;margin:0 !important;margin-bottom:15px !important;line-height:1.4em !important;font-family:"Trebuchet MS", Helvetica, Verdana, sans-serif !important;font-size:14px !important;border:none}.trumbowyg-editor.trumbowyg-reset-css iframe,.trumbowyg-editor.trumbowyg-reset-css object,.trumbowyg-editor.trumbowyg-reset-css hr{margin-bottom:15px !important}.trumbowyg-editor.trumbowyg-reset-css blockquote{margin-left:32px !important;font-style:italic !important;color:#555}.trumbowyg-editor.trumbowyg-reset-css ul,.trumbowyg-editor.trumbowyg-reset-css ol{padding-left:20px !important}.trumbowyg-editor.trumbowyg-reset-css ul ul,.trumbowyg-editor.trumbowyg-reset-css ol ol,.trumbowyg-editor.trumbowyg-reset-css ul ol,.trumbowyg-editor.trumbowyg-reset-css ol ul{border:none;margin:2px !important;padding:0 !important;padding-left:24px !important}.trumbowyg-editor.trumbowyg-reset-css hr{display:block;height:1px;border:none;border-top:1px solid #CCC}.trumbowyg-editor.trumbowyg-reset-css h1,.trumbowyg-editor.trumbowyg-reset-css h2,.trumbowyg-editor.trumbowyg-reset-css h3,.trumbowyg-editor.trumbowyg-reset-css h4{color:#111;background:none;margin:0 !important;padding:0 !important;font-weight:bold}.trumbowyg-editor.trumbowyg-reset-css h1{font-size:32px !important;line-height:38px !important;margin-bottom:20px !important}.trumbowyg-editor.trumbowyg-reset-css h2{font-size:26px !important;line-height:34px !important;margin-bottom:15px !important}.trumbowyg-editor.trumbowyg-reset-css h3{font-size:22px !important;line-height:28px !important;margin-bottom:7px !important}.trumbowyg-editor.trumbowyg-reset-css h4{font-size:16px !important;line-height:22px !important;margin-bottom:7px !important}.trumbowyg-button-pane li button{display:block;position:relative;text-indent:-9999px;width:35px;height:35px;overflow:hidden;background:transparent url(\'icons-sa75ce98b2b.png\') no-repeat;border:none;cursor:pointer;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s;transition:background-color .15s, background-image .15s, opacity .15s}.trumbowyg-button-pane li button.trumbowyg-viewHTML-button{background-position:5px -545px}.trumbowyg-button-pane li button.trumbowyg-formatting-button{background-position:5px -120px}.trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-button-pane li button.trumbowyg-strong-button{background-position:5px -45px}.trumbowyg-button-pane li button.trumbowyg-italic-button,.trumbowyg-button-pane li button.trumbowyg-em-button{background-position:5px -270px}.trumbowyg-button-pane li button.trumbowyg-underline-button{background-position:5px -470px}.trumbowyg-button-pane li button.trumbowyg-strikethrough-button,.trumbowyg-button-pane li button.trumbowyg-del-button{background-position:5px -445px}.trumbowyg-button-pane li button.trumbowyg-link-button{background-position:5px -345px}.trumbowyg-button-pane li button.trumbowyg-insertImage-button{background-position:5px -245px}.trumbowyg-button-pane li button.trumbowyg-justifyLeft-button{background-position:5px -320px}.trumbowyg-button-pane li button.trumbowyg-justifyCenter-button{background-position:5px -70px}.trumbowyg-button-pane li button.trumbowyg-justifyRight-button{background-position:5px -395px}.trumbowyg-button-pane li button.trumbowyg-justifyFull-button{background-position:5px -295px}.trumbowyg-button-pane li button.trumbowyg-unorderedList-button{background-position:5px -495px}.trumbowyg-button-pane li button.trumbowyg-orderedList-button{background-position:5px -370px}.trumbowyg-button-pane li button.trumbowyg-horizontalRule-button{background-position:5px -220px}.trumbowyg-button-pane li button.trumbowyg-fullscreen-button{background-position:5px -170px}.trumbowyg-button-pane li button.trumbowyg-close-button{background-position:5px -95px}.trumbowyg-fullscreen .trumbowyg-button-pane li button.trumbowyg-fullscreen-button{background-position:5px -145px}.trumbowyg-button-pane li:first-child button{margin-left:6px}.trumbowyg-button-pane li:last-child button{margin-right:6px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strong-button{background-position:5px -195px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-underline-button{background-position:5px -420px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strikethrough-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-del-button{background-position:5px -20px}@media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 4 / 3), only screen and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){.trumbowyg-button-pane li button{background-size:72%;background-image:url(\'../images/icons-2x-s9034954e6d.png\')}.trumbowyg-button-pane li button.trumbowyg-viewHTML-button{background-position:5px -545px}.trumbowyg-button-pane li button.trumbowyg-formatting-button{background-position:5px -120px}.trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-button-pane li button.trumbowyg-strong-button{background-position:5px -45px}.trumbowyg-button-pane li button.trumbowyg-italic-button,.trumbowyg-button-pane li button.trumbowyg-em-button{background-position:5px -270px}.trumbowyg-button-pane li button.trumbowyg-underline-button{background-position:5px -470px}.trumbowyg-button-pane li button.trumbowyg-strikethrough-button,.trumbowyg-button-pane li button.trumbowyg-del-button{background-position:5px -445px}.trumbowyg-button-pane li button.trumbowyg-link-button{background-position:5px -345px}.trumbowyg-button-pane li button.trumbowyg-insertImage-button{background-position:5px -245px}.trumbowyg-button-pane li button.trumbowyg-justifyLeft-button{background-position:5px -320px}.trumbowyg-button-pane li button.trumbowyg-justifyCenter-button{background-position:5px -70px}.trumbowyg-button-pane li button.trumbowyg-justifyRight-button{background-position:5px -395px}.trumbowyg-button-pane li button.trumbowyg-justifyFull-button{background-position:5px -295px}.trumbowyg-button-pane li button.trumbowyg-unorderedList-button{background-position:5px -495px}.trumbowyg-button-pane li button.trumbowyg-orderedList-button{background-position:5px -370px}.trumbowyg-button-pane li button.trumbowyg-horizontalRule-button{background-position:5px -220px}.trumbowyg-button-pane li button.trumbowyg-fullscreen-button{background-position:5px -170px}.trumbowyg-button-pane li button.trumbowyg-close-button{background-position:5px -95px}.trumbowyg-fullscreen .trumbowyg-button-pane li a.trumbowyg-fullscreen-button{background-position:5px -145px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strong-button{background-position:5px -195px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-underline-button{background-position:5px -420px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strikethrough-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-del-button{background-position:5px -20px}} html, body { margin: 0; padding: 0; } header { text-align: center; } #main { max-width: 960px; margin: 0 auto; }
trumbowyg.js
/* =========================================================== * trumbowyg.js v1.0 * Core code of Trumbowyg plugin * http://alex-d.github.com/Trumbowyg * =========================================================== * Author : Alexandre Demode (Alex-D) * Twitter : @AlexandreDemode * Website : alex-d.fr */ $.trumbowyg = { langs: { en: { viewHTML: "View HTML", formatting: "Formatting", p: "Paragraph", blockquote: "Quote", code: "Code", header: "Header", bold: "Bold", italic: "Italic", strikethrough: "Stroke", underline: "Underline", strong: "Strong", em: "Emphasis", del: "Deleted", unorderedList: "Unordered list", orderedList: "Ordered list", insertImage: "Insert Image", insertVideo: "Insert Video", link: "Link", createLink: "Insert link", unlink: "Remove link", justifyLeft: "Align Left", justifyCenter: "Align Center", justifyRight: "Align Right", justifyFull: "Align Justify", horizontalRule: "Insert horizontal rule", fullscreen: "fullscreen", close: "Close", submit: "Confirm", reset: "Cancel", invalidUrl: "Invalid URL", required: "Required", description: "Description", title: "Title", text: "Text" } }, // User default options opts: {}, btnsGrps: { design: [\'bold\', \'italic\', \'underline\', \'strikethrough\'], semantic: [\'strong\', \'em\', \'del\'], justify: [\'justifyLeft\', \'justifyCenter\', \'justifyRight\', \'justifyFull\'], lists: [\'unorderedList\', \'orderedList\'] } }; (function($){ $.fn.trumbowyg = function(opts, params){ if($.isObject(opts) || opts == null){ return this.each(function(){ if(!$(this).data(\'trumbowyg\')) $(this).data(\'trumbowyg\', new Trumbowyg(this, opts)); }); } else if(this.length == 1){ try { var t = $(this).data(\'trumbowyg\'); switch(opts){ // Modal box case \'openModal\': return t.openModal(params.title, params.content); case \'closeModal\': return t.closeModal(); case \'openModalInsert\': return t.openModalInsert(params.title, params.fields, params.callback); // Selection case \'saveSelection\': return t.saveSelection(); case \'getSelection\': return t.selection; case \'getSelectedText\': return t.selection+\'\'; case \'restoreSelection\': return t.restoreSelection(); // Destroy case \'destroy\': return t.destroy(); // Empty case \'empty\': return t.empty(); // Public options case \'lang\': return t.lang; case \'duration\': return t.o.duration; // HTML case \'html\': return t.html(params); } } catch(e){} } return false; }; var Trumbowyg = function(editorElem, opts){ // jQuery object of the editor this.$e = $(editorElem); this.$creator = $(editorElem); // Extend with options opts = $.extend(true, {}, opts, $.trumbowyg.opts); // Localization management if(typeof opts.lang === \'undefined\' || typeof $.trumbowyg.langs[opts.lang] === \'undefined\') this.lang = $.trumbowyg.langs[\'en\']; else this.lang = $.extend(true, {}, $.trumbowyg.langs[\'en\'], $.trumbowyg.langs[opts.lang]); // Defaults Options this.o = $.extend(true, { lang: \'en\', dir: \'ltr\', duration: 200, // Duration of modal box animations mobile: false, tablet: true, closable: false, fullscreenable: true, fixedBtnPane: false, fixedFullWidth: false, semantic: false, resetCss: false, autogrow: false, prefix: \'trumbowyg-\', convertLink: true, btns: [\'viewHTML\', \'|\', \'formatting\', \'|\', $.trumbowyg.btnsGrps.design, \'|\', \'link\', \'|\', \'insertImage\', \'|\', $.trumbowyg.btnsGrps.justify, \'|\', $.trumbowyg.btnsGrps.lists, \'|\', \'horizontalRule\'], btnsAdd: [], /** * When the button is associated to a empty object * func and title attributs are defined from the button key value * * For example * foo: {} * is equivalent to : * foo: { * func: \'foo\', * title: this.lang.foo * } */ btnsDef: { viewHTML: { func: \'toggle\' }, p: { func: \'formatBlock\' }, blockquote: { func: \'formatBlock\' }, h1: { func: \'formatBlock\', title: this.lang.header + \' 1\' }, h2: { func: \'formatBlock\', title: this.lang.header + \' 2\' }, h3: { func: \'formatBlock\', title: this.lang.header + \' 3\' }, h4: { func: \'formatBlock\', title: this.lang.header + \' 4\' }, bold: {}, italic: {}, underline: {}, strikethrough: {}, strong: { func: \'bold\' }, em: { func: \'italic\' }, del: { func: \'strikethrough\' }, createLink: {}, unlink: {}, insertImage: {}, justifyLeft: {}, justifyCenter: {}, justifyRight: {}, justifyFull: {}, unorderedList: { func: \'insertUnorderedList\' }, orderedList: { func: \'insertOrderedList\' }, horizontalRule: { func: \'insertHorizontalRule\' }, // Dropdowns formatting: { dropdown: [\'p\', \'blockquote\', \'h1\', \'h2\', \'h3\', \'h4\'] }, link: { dropdown: [\'createLink\', \'unlink\'] } } }, opts); if(this.o.semantic && !opts.btns) this.o.btns = [ \'viewHTML\', \'|\', \'formatting\', \'|\', $.trumbowyg.btnsGrps.semantic, \'|\', \'link\', \'|\', \'insertImage\', \'|\', $.trumbowyg.btnsGrps.justify, \'|\', $.trumbowyg.btnsGrps.lists, \'|\', \'horizontalRule\' ]; else if(opts && opts.btns) this.o.btns = opts.btns; this.init(); } Trumbowyg.prototype = { init: function(){ this.height = this.$e.css(\'height\'); if(this.isEnabled()){ this.buildEditor(true); return; } this.buildEditor(); this.buildBtnPane(); this.fixedBtnPaneEvents(); this.buildOverlay(); }, buildEditor: function(disable){ if(disable === true){ if(!this.$e.is(\'textarea\')){ var textarea = this.buildTextarea().val(this.$e.val()); this.$e.hide().after(textarea); } return; } this.$box = $(\'<div/>\', { \'class\': this.o.prefix + \'box \' + this.o.prefix + this.o.lang + \' trumbowyg\' }); this.isTextarea = true; if(this.$e.is(\'textarea\')) this.$editor = $(\'<div/>\'); else { this.$editor = this.$e; this.$e = this.buildTextarea().val(this.$e.val()); this.isTextarea = false; } this.$e.hide() .addClass(this.o.prefix + \'textarea\'); var html = \'\'; if(this.isTextarea){ html = this.$e.val(); this.$box.insertAfter(this.$e) .append(this.$editor) .append(this.$e); } else { html = this.$editor.html(); this.$box.insertAfter(this.$editor) .append(this.$e) .append(this.$editor); this.syncCode(); } this.$editor.addClass(this.o.prefix + \'editor\') .attr(\'contenteditable\', true) .attr(\'dir\', this.o.dir) .html(html); if(this.o.resetCss) this.$editor.addClass(this.o.prefix + \'reset-css\'); if(!this.o.autogrow){ $.each([this.$editor, this.$e], $.proxy(function(i, $el){ $el.css({ overflow: \'auto\' }); }, this)); } if(this.o.semantic){ this.$editor.html( this.$editor.html() .replace("<br>", "</p><p>") .replace("&nsbp;", "") ); this.semanticCode(); } var that = this; this.$editor .on(\'dblclick\', \'img\', function(){ var $img = $(this); that.openModalInsert(that.lang.insertImage, { url: { label: \'URL\', value: $img.attr(\'src\'), required: true }, alt: { label: \'description\', value: $img.attr(\'alt\') } }, function(values){ $img.attr(\'src\', values[\'url\']); $img.attr(\'alt\', values[\'alt\']); }); return false; }) .on(\'keyup\', function(e){ that.semanticCode(false, e.which === 13); }) .on(\'blur\', function(){ that.syncCode(); }); }, // Build the Textarea which contain HTML generated code buildTextarea: function(){ return $(\'<textarea/>\', { \'name\': this.$e.attr(\'id\'), \'height\': this.height }); }, // Build button pane, use o.btns and o.btnsAdd options buildBtnPane: function(){ var t = this; if(t.o.btns === false) return; var pfx = t.o.prefix; t.$btnPane = $(\'<ul/>\', { \'class\': pfx + \'button-pane\' }); $.each(t.o.btns.concat(t.o.btnsAdd), $.proxy(function(i, btn){ // Managment of group of buttons try { var b = btn.split(\'btnGrp-\'); if(b[1] != undefined) btn = $.trumbowyg.btnsGrps[b[1]]; } catch(e){} if(!$.isArray(btn)) btn = [btn]; $.each(btn, $.proxy(function(i, btn){ try { // Prevent buildBtn error var $li = $(\'<li/>\'); if(btn === \'|\') // It\'s a separator $li.addClass(pfx + \'separator\'); else if(t.isSupportedBtn(btn)){ // It\'s a supported button if(btn === \'viewHTML\') $li.addClass(pfx + \'not-disable\'); $li.append(t.buildBtn(btn)); } t.$btnPane.append($li); } catch(e){} }, t)); }, t)); // Build right li for fullscreen and close buttons var $liRight = $(\'<li/>\', { \'class\': pfx + \'not-disable \' + pfx + \'buttons-right\' }); // Add the fullscreen button if(t.o.fullscreenable) $liRight .append(t.buildRightBtn(\'fullscreen\') .on(\'click\', $.proxy(function(e){ var cssClass = pfx + \'fullscreen\'; t.$box.toggleClass(cssClass); if(t.$box.hasClass(cssClass)){ $(\'body\').css(\'overflow\', \'hidden\'); t.$box.css({ position: \'fixed\', top: 0, left: 0, width: \'100%\', margin: 0, padding: 0, zIndex: 99999 }); $([t.$editor, t.$e]).each(function(){ $(this).css({ overflow: \'auto\' }); }); t.$btnPane.css(\'width\', \'100%\'); $(".trumbowyg-fullscreen .editor").css("height",$(window).height()-65); } else { $(\'body\').css(\'overflow\', \'auto\'); t.$box.removeAttr(\'style\'); if(!t.o.autogrow){ h = t.height; $([t.$editor, t.$e]).each(function(i, $el){ $el.css(\'height\', h); }); } } $(window).trigger(\'scroll\'); }, t))); // Build and add close button if(t.o.closable) $liRight .append(t.buildRightBtn(\'close\') .on(\'click\', $.proxy(function(e){ var cssClass = pfx + \'fullscreen\'; if(t.$box.hasClass(cssClass)) $(\'body\').css(\'overflow\', \'auto\'); t.destroy(); }, t))); // Add right li only if isn\'t empty if($liRight.not(\':empty\')) t.$btnPane.append($liRight); t.$box.prepend(t.$btnPane); }, // Build a button and his action buildBtn: function(name){ var pfx = this.o.prefix, btnDef = this.o.btnsDef[name], t = this, textDef = this.lang[name] || name.charAt(0).toUpperCase() + name.slice(1); var $btn = $(\'<button/>\', { \'type\': \'button\', \'class\': pfx + name +\'-button\' + (btnDef.ico ? \' \'+ pfx + btnDef.ico +\'-button\' : \'\'), \'text\': btnDef.text || btnDef.title || textDef, \'title\': btnDef.title || btnDef.text || textDef, \'mousedown\': function(e){ if(!btnDef.dropdown || t.$box.find(\'.\'+name+\'-\'+pfx + \'dropdown\').is(\':hidden\')) $(\'body\').trigger(\'mousedown\'); if(t.$btnPane.hasClass(pfx + \'disable\') && !$(this).parent().hasClass(pfx + \'not-disable\')) return false; t.execCommand((btnDef.dropdown ? \'dropdown\' : false) || btnDef.func || name, btnDef.param || name); e.stopPropagation(); e.preventDefault(); return false; } }); if(btnDef.dropdown){ $btn.addClass(pfx + \'open-dropdown\'); var cssClass = pfx + \'dropdown\'; var dropdown = $(\'<div/>\', { \'class\': name + \'-\' + cssClass + \' \' + cssClass + \' \' + pfx + \'fixed-top\' }); for(var i = 0, c = btnDef.dropdown.length; i < c; i++){ if(t.o.btnsDef[btnDef.dropdown[i]] && t.isSupportedBtn(btnDef.dropdown[i])) dropdown.append(t.buildSubBtn(btnDef.dropdown[i])); } this.$box.append(dropdown.hide()); } return $btn; }, // Build a button for dropdown menu buildSubBtn: function(name){ var btnDef = this.o.btnsDef[name]; return $(\'<button/>\', { \'type\': \'button\', \'text\': btnDef.text || btnDef.title || this.lang[name] || name, \'mousedown\': $.proxy(function(e){ $(\'body\').trigger(\'mousedown\'); this.execCommand(btnDef.func || name, btnDef.param || name); e.stopPropagation(); e.preventDefault(); return false; }, this) }); }, // Build a button for right li buildRightBtn: function(name){ return $(\'<button/>\', { \'type\': \'button\', \'class\': this.o.prefix + name+\'-button\', \'title\': this.lang[name], \'text\': this.lang[name] }); }, // Check if button is supported isSupportedBtn: function(btn){ return typeof this.o.btnsDef[btn].isSupported !== \'function\' || this.o.btnsDef[btn].isSupported() }, // Build overlay for modal box buildOverlay: function(){ return this.$overlay = $(\'<div/>\', { \'class\': this.o.prefix + \'overlay\' }).css({ top: this.$btnPane.outerHeight(), height: (parseInt(this.$editor.outerHeight()) + 1) + \'px\' }).appendTo(this.$box); }, showOverlay: function(){ $(window).trigger(\'scroll\'); this.$overlay.fadeIn(this.o.duration); this.$box.addClass(this.o.prefix + \'box-blur\'); }, hideOverlay: function(){ this.$overlay.fadeOut(this.o.duration/4); this.$box.removeClass(this.o.prefix + \'box-blur\'); }, // Management of fixed button pane fixedBtnPaneEvents: function(){ if(!this.o.fixedBtnPane) return; this.isFixed = false; $(window).on(\'scroll\', $.proxy(function(e){ if(!this.$box) return; this.syncCode(); var wScroll = $(window).scrollTop(), offset = this.$box.offset().top + 1, toFixed = (wScroll - offset > 0) && ((wScroll - offset - parseInt(this.height)) < 0); if(toFixed){ if(!this.isFixed){ this.isFixed = true; this.$btnPane.css({ position: \'fixed\', top: 0, left: (this.o.fixedFullWidth) ? \'0\' : \'auto\', width: (this.o.fixedFullWidth) ? \'100%\' : ((parseInt(this.$box.css(\'width\'))-1) + \'px\'), zIndex: 7 }); this.$editor.css({ marginTop: this.$btnPane.css(\'height\') }); this.$e.css({ marginTop: this.$btnPane.css(\'height\') }); } $(\'.\' + this.o.prefix + \'fixed-top\', this.$box).css({ position: this.o.fixedFullWidth ? \'fixed\' : \'absolute\', top: this.o.fixedFullWidth ? this.$btnPane.outerHeight() : parseInt(this.$btnPane.outerHeight()) + (wScroll - offset) + \'px\', zIndex: 15 }); } else if(this.isFixed) { this.isFixed = false; this.$btnPane.css({ position: \'relative\' }); this.$editor.css({ marginTop: 0 }); this.$e.css({ marginTop: 0 }); $(\'.\' + this.o.prefix + \'fixed-top\', this.$box).css({ position: \'absolute\', top: this.$btnPane.outerHeight() }); } }, this)); }, // Destroy the editor destroy: function(){ var html = this.html(); if(this.isTextarea) this.$box.after(this.$e.css({height: this.height}) .val(html) .removeClass(this.o.prefix + \'textarea\') .show()); else this.$box.after(this.$editor.css({height: this.height}) .removeClass(this.o.prefix + \'editor\') .attr(\'contenteditable\', false) .html(html) .show()); this.$box.remove(); this.$creator.removeData(\'trumbowyg\'); }, // Empty the editor empty: function(){ this.$e.val(\'\'); this.syncCode(true); }, // Function call when click on viewHTML button toggle: function(){ this.semanticCode(false, true); this.$editor.toggle(); this.$e.toggle(); this.$btnPane.toggleClass(this.o.prefix + \'disable\'); this.$btnPane.find(\'.\'+this.o.prefix + \'viewHTML-button\').toggleClass(this.o.prefix + \'active\'); }, // Open dropdown when click on a button which open that dropdown: function(name){ var pfx = this.o.prefix; var $dropdown = this.$box.find(\'.\'+name+\'-\'+pfx + \'dropdown\'), $btn = this.$btnPane.find(\'.\'+pfx+name+\'-button\'); if($dropdown.is(\':hidden\')){ $btn.addClass(this.o.prefix + \'active\'); $dropdown.css({ position: \'absolute\', top: this.$btnPane.outerHeight(), left: (this.o.fixedFullWidth && this.isFixed) ? $btn.offset().left+\'px\' : ($btn.offset().left - this.$btnPane.offset().left)+\'px\' }).show(); $(window).trigger(\'scroll\'); $(\'body\').on(\'mousedown\', $.proxy(function(e){ $(\'.\' + pfx + \'dropdown\').hide(); $(\'.\' + pfx + \'active\').removeClass(pfx + \'active\'); $(\'body\').off(\'mousedown\'); }, this)); } else { $(\'body\').trigger(\'mousedown\'); } }, // HTML Code management html: function(html){ if(html){ this.$e.val(html); this.syncCode(true); return tbw; } else return this.$e.val(); }, syncCode: function(force){ if(!force && this.$editor.is(\':visible\')) this.$e.val(this.$editor.html()); else this.$editor.html(this.$e.val()); if(this.o.autogrow){ this.height = this.$editor.css(\'height\'); this.$e.css({ height: this.height }); } }, // Analyse and update to semantic code // @param force : force to sync code from textarea // @param full : wrap text nodes in <p> semanticCode: function(force, full){ this.syncCode(force); if(this.o.semantic){ this.semanticTag(\'b\', \'strong\'); this.semanticTag(\'i\', \'em\'); this.semanticTag(\'strike\', \'del\'); if(full){ // Wrap text nodes in p this.$editor.contents() .filter(function(){ // Only non-empty text nodes return this.nodeType === 3 && $.trim(this.nodeValue).length > 0; }).wrap(\'<p></p>\').end() // Remove all br .filter("br").remove(); this.saveSelection(); this.semanticTag(\'div\', \'p\'); this.restoreSelection(); } this.$e.val(this.$editor.html()); } }, semanticTag: function(oldTag, newTag){ $(oldTag, this.$editor).each(function(){ $(this).replaceWith(function(){ return \'<\'+newTag+\'>\' + $(this).html() + \'</\'+newTag+\'>\'; }); }); }, // Function call when user click on « Insert Link » createLink: function(){ var that = this; this.saveSelection(); this.openModalInsert(this.lang.createLink, { url: { label: \'URL\', value: \'http://\', required: true }, title: { label: this.lang.title, value: this.selection }, text: { label: this.lang.text, value: this.selection } }, function(values){ that.execCommand(\'createLink\', values[\'url\']); var link = $([\'a[href="\', values[\'url\'], \'"]:not([title])\'].join(\'\'), that.$box); if($.trim(values[\'text\']).length !== 0) link.text(values[\'text\']); if($.trim(values[\'title\']).length !== 0) link.attr(\'title\', values[\'title\']); return true; }); }, insertImage: function(){ //图片上传 var that = this; this.saveSelection(); this.openModalInsert(this.lang.insertImage, { url: { label: \'URL\', value: \'\', required: true }, alt: { label: \'description\', value: this.selection } }, function(values){ that.execCommand(\'insertImage\', values[\'url\']); $([\'img[src="\', values[\'url\'], \'"]:not([alt])\'].join(\'\'), that.$box).attr(\'alt\', values[\'alt\']); return true; }); }, /* * Call method of trumbowyg if exist * else try to call anonymous function * and finaly native execCommand */ execCommand: function(cmd, param){ if(cmd != \'dropdown\') this.$editor.focus(); try { this[cmd](param); } catch(e){ try { cmd(param, this); } catch(e){ this.$editor.focus(); if(cmd == \'insertHorizontalRule\') param = null; document.execCommand(cmd, false, param); } } this.syncCode(); }, formatBlock: function(param){ if($.browser.msie) param = \'<\' + param + \'>\'; document.execCommand(\'formatBlock\', false, param); }, // Open a modal box openModal: function(title, content){ var pfx = this.o.prefix; // No open a modal box when exist other modal box if($(\'.\' + pfx + \'modal-box\', this.$box).size() > 0) return false; this.saveSelection(); this.showOverlay(); // Disable all btnPane btns this.$btnPane.addClass(pfx + \'disable\'); $(\'.\' + pfx + \'not-disable\', this.$btnPane) .not(\'.\' + pfx + \'buttons-right\') .removeClass(pfx + \'not-disable\') .addClass(pfx + \'not-disable-old\'); // Build out of ModalBox, it\'s the mask for animations var $modal = $(\'<div/>\', { \'class\': pfx + \'modal \' + pfx + \'fixed-top\' }).css({ top: (parseInt(this.$btnPane.css(\'height\')) + 1) + \'px\' }).appendTo(this.$box); // Click on overflay close modal by cancelling them this.$overlay.one(\'click\', function(e){ e.preventDefault(); $modal.trigger(pfx + \'cancel\'); }); $e = this.$editor; // Build the form $form = $(\'<form/>\', { action: \'javascript:void(null);\', html: content }) .on(\'submit\', function(e){ e.preventDefault(); $modal.trigger(pfx + \'confirm\'); }) .on(\'reset\', function(e){ e.preventDefault(); $modal.trigger(pfx + \'cancel\'); }); // Build ModalBox and animate to show them var $modalBox = $(\'<div/>\', { \'class\': pfx + \'modal-box\', html: $form }) .css({ top: \'-\' + parseInt(this.$btnPane.outerHeight()) + \'px\', opacity: 0 }) .appendTo($modal) .animate({ top: 0, opacity: 1 }, this.o.duration / 2); // Append title $(\'<span/>\', { text: title, \'class\': pfx + \'modal-title\' }).prependTo($modalBox); // Focus in modal box $modalBox.find(\'input:first\').focus(); // Append Confirm and Cancel buttons this.buildModalBtn(\'submit\', $modalBox); this.buildModalBtn(\'reset\', $modalBox); $(\'body\').trigger(\'scroll\'); return $modal; }, buildModalBtn: function(name, modal){ return $(\'<button/>\', { \'class\': this.o.prefix + \'modal-button \' + this.o.prefix + \'modal-\' + name, \'type\': name, \'text\': this.lang[name] || name }).appendTo(modal.find(\'form\')); }, // close current modal box closeModal: function(){ var pfx = this.o.prefix; this.$btnPane.removeClass(pfx + \'disable\'); this.$overlay.off(); $(\'.\' + this.o.prefix + \'not-disable-old\', this.$btnPane) .removeClass(pfx + \'not-disable-old\') .addClass(pfx + \'not-disable\'); var that = this, $modalBox = $(\'.\' + pfx + \'modal-box\', this.$box); $modalBox.animate({ top: \'-\' + $modalBox.css(\'height\') }, this.o.duration/2, function(){ $(this).parent().remove(); that.hideOverlay(); }); }, // Preformated build and management modal openModalInsert: function(title, fields, cmd){ var html = \'\', pfx = this.o.prefix; for(f in fields){ var fd = fields[f]; label = (fd.label == undefined) ? (this.lang[f] ? this.lang[f] : f.charAt(0).toUpperCase() + f.slice(1)) : (this.lang[fd.label] ? this.lang[fd.label] : fd.label) ; if(fd.name == undefined) fd.name = f; if(!fd.pattern && f == \'url\'){ fd.pattern = /^(http|https):\/\/([\w~#!:.?+=&%@!\-\/]+)$/; fd.patternError = this.lang.invalidUrl; } html += \'<label><input type="\'+(fd.type || \'text\')+\'" name="\'+fd.name+\'" value="\'+(fd.value || \'\')+\'"><span class="\'+pfx+\'input-infos"><span>\'+label+\'</span></span></label>\'; } var modBox = this.openModal(title, html), that = this; modBox .on(pfx + \'confirm\', function(){ var $form = $(this).find(\'form\'), valid = true, values = {}; for(f in fields) { var $field = $(\'input[name="\'+f+\'"]\', $form); values[f] = $field.val(); // Validate value if(fields[f].required && (values[f] == null || values[f] == undefined || $.trim(values[f]) == "")) { valid = false; that.addErrorOnModalField($field, that.lang.required); } else if(fields[f].pattern && !fields[f].pattern.test(values[f])) { valid = false; that.addErrorOnModalField($field, fields[f].patternError); } } if(valid) { that.restoreSelection(); if(cmd(values, fields)) { that.syncCode(); that.closeModal(); modBox.off(pfx + \'confirm\'); } } }) .one(pfx + \'cancel\', function(){ modBox.off(pfx + \'confirm\'); that.closeModal(); that.restoreSelection(); }); return modBox; }, addErrorOnModalField: function($field, err){ var $label = $field.parent(), pfx = this.o.prefix; $label.addClass(pfx + \'input-error\'); $field.on(\'change keyup\', function(){ $label.removeClass(pfx + \'input-error\'); }); $label.find(\'input+span\').append(\'<span class="\'+ pfx +\'msg-error">\'+ err +\'</span>\'); }, // Selection management saveSelection: function(){ this.selection = null; if(window.getSelection){ var sel = window.getSelection(); if(sel.getRangeAt && sel.rangeCount) this.selection = sel.getRangeAt(0); } else if(document.selection && document.selection.createRange){ this.selection = document.selection.createRange(); } }, restoreSelection: function(){ range = this.selection; if(range){ if(window.getSelection){ var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if(document.selection && range.select){ range.select(); } } }, // Return true if must enable Trumbowyg on this mobile device isEnabled: function(){ var mobile = "iPhone|iPod|Android|BlackBerry|Windows\sPhone|ZuneWP7"; var exprTablet = new RegExp("(iPad|webOS)"); var exprMobile = new RegExp("("+mobile+")"); return (this.o.tablet === true && exprTablet.test(navigator.userAgent)) || (this.o.mobile === true && exprMobile.test(navigator.userAgent)); } }; /* isObject */ var toString = Object.prototype.toString, hasOwnProp = Object.prototype.hasOwnProperty; $.isObject = function(obj) { if(toString.call(obj) !== "[object Object]") return false; var key; for(key in obj){} return !key || hasOwnProp.call(obj, key); }; $.isString = function(str){ return typeof(str) === \'string\' }; })(jQuery); function del() { var element=document.getElementById("demoImage"); if(element) { element.parentNode.removeChild(element); } } function show_element(e) { if(!e) { var e = window.event; } //获取事件点击元素 var targ = e.target; //获取元素名称 var tname = targ.tagName; var oDiv=document.getElementById(\'odiv\'); if(tname=="IMG") { var scrollTop=Math.max(document.documentElement.scrollTop,document.body.scrollTop); oDiv.style.left=e.clientX+5+\'px\'; oDiv.style.top=e.clientY+5+scrollTop+\'px\'; oDiv.style.display="inline"; targ.width=targ.width; var s=document.getElementById(\'demoImage\'); if(s!=null) { s.id=""; } targ.id=\'demoImage\' }else{ var wait = setInterval(function(){ if (oDiv != 0 && oDiv != null && oDiv != undefined) { clearInterval(wait); oDiv.style.display="none"; } },50); } } function tim(m) { var s=document.getElementById(\'demoImage\'); s.width=s.width+m; s.width=s.width; } function sub(m) { var s=document.getElementById(\'demoImage\'); if(s!=null) { if(m!=0) { var t=s.width/10; while(t>0) { if(m==1) setTimeout(\'tim(1)\',\'50\'); else setTimeout(\'tim(-1);\',\'50\'); t=t-1; } } else s.width=-1; s.width=s.width; } } /* =========================================================== * zh_cn.js * Simplified Chinese translation for Trumbowyg * http://alex-d.github.com/Trumbowyg * =========================================================== * Author : Liu Kai (akai) * Twitter : @akai404 * Github : https://github.com/akai */ $.trumbowyg.langs.zh_cn = { viewHTML: "源代码", formatting: "格式", p: "段落", blockquote: "引用", code: "代码", header: "标题", bold: "加粗", italic: "斜体", strikethrough: "删除线", underline: "下划线", strong: "加粗", em: "斜体", del: "删除线", unorderedList: "无序列表", orderedList: "有序列表", image: "图片", insertImage: "网络图片", upload: "本地上传", uploadError: "上传失败", insertVideo: "插入视频", link: "超链接", createLink: "插入链接", unlink: "取消链接", align: "对齐方式", justifyLeft: "居左对齐", justifyCenter: "居中对齐", justifyRight: "居右对齐", justifyFull: "两端对齐", horizontalRule: "插入分隔线", fullscreen: "全屏", close: "关闭", submit: "确定", reset: "取消", invalidUrl: "无效的 URL", required: "必需的", description: "描述", title: "标题", text: "文字" } $(function(){ $.trumbowyg.btnsGrps.test = [\'bold\',\'italic\',\'underline\',\'link\']; $(\'#customized-buttonpane\').trumbowyg({ lang: \'zh_cn\', fixedBtnPane: true, btnsDef: { align: { dropdown: [\'justifyLeft\', \'justifyCenter\', \'justifyRight\', \'justifyFull\'], ico: \'justifyLeft\' }, image: { dropdown: [\'insertImage\', \'upload\'], ico: \'insertImage\' } }, btns: [\'viewHTML\', \'|\', \'formatting\', \'|\', \'btnGrp-test\', \'|\', \'align\', \'|\', \'btnGrp-lists\', \'|\', \'image\'] }); $(\'.editor\').on(\'dblclick\', function(e){ $(this).trumbowyg({ lang: \'zh_cn\', closable: false, fixedBtnPane: true }); }); });
trumbowyg.upload.js
/* =========================================================== * trumbowyg.upload.js v1.0 * Upload plugin for Trumbowyg * http://alex-d.github.com/Trumbowyg * =========================================================== * Author : Alexandre Demode (Alex-D) * Twitter : @AlexandreDemode * Website : alex-d.fr */ (function($){ addXhrProgressEvent(); $.extend(true, $.trumbowyg, { upload: { serverPath: urlcore + \'/file/upload/batch\' }, opts: { btnsDef: { upload: { func: function(params, tbw){ var file, pfx = tbw.o.prefix; var $modal = tbw.openModalInsert( // Title tbw.lang[\'upload\'], // Fields { file: { type: \'file\', required: true }, alt: { label: \'description\' } }, // Callback function(values, fields){ var data = new FormData(); data.append(\'files\', file); if($(\'.\' + pfx +\'progress\', $modal).length == 0) $(\'.\' + pfx + \'modal-title\', $modal) .after( $(\'<div/>\', { \'class\': pfx +\'progress\' }) .append( $(\'<div/>\', { \'class\': pfx +\'progress-bar\' }) ) ); $.ajax({ url: $.trumbowyg.upload.serverPath, type: \'POST\', data: data, cache: false, dataType: \'json\', processData: false, contentType: false, progressUpload: function(e){ $(\'.\' + pfx + \'progress\').html( \'<div class="trumbowyg-progress-bar" style="overflow: hidden; width: \'+e.loaded * 100 / e.total+\'%;"></div>\'+ parseInt(e.loaded * 100 / e.total) + \'%\' ); }, success: function(data){ if (data.success == true) { for(var i in data.data){ tbw.execCommand(\'insertImage\', data.data[i]); } setTimeout(function(){ tbw.closeModal(); }, 250); } else { tbw.addErrorOnModalField( $(\'input[type=file]\', $modal), tbw.lang[data.message] ); } }, error: function(data){ tbw.addErrorOnModalField( $(\'input[type=file]\', $modal), tbw.lang[\'uploadError\'] ); } }); } ); $(\'input[type=file]\').on(\'change\', function(e){ file = e.target.files[0]; }); } } } } }); function addXhrProgressEvent(){ var originalXhr = $.ajaxSettings.xhr; $.ajaxSetup({ xhr: function() { var req = originalXhr(), that = this; if(req && typeof req.upload == "object" && that.progressUpload !== undefined) req.upload.addEventListener("progress", function(e){ that.progressUpload(e); }, false); return req; } }); } })(jQuery);
附件下载地址(包含图标和js): https://files.cnblogs.com/files/007sx/assets.zip