這個需求,我估計很多時候都不會用到,但是,我們目前在做一個CMS的系統,在創建頁面的時候,需要控制頁面各個板塊顯示的內容來源,這個不是關鍵,關鍵是頁面內容配置完畢后,如何提交內容,也就是說如何和后台系統通信。這個時候,有兩種做法,一種是在頁面的控制區域內添加右鍵菜單,實現這個功能。另外一個做法,就是在頁面中添加按鈕區域來實現。
但是不管那種做法,控制區域的html頁面上的邏輯代碼片,都不可能在模板里面添加,這是不友好的,客戶也是不會考慮這個的,再說了,他也沒有辦法考慮。所以,需要CMS系統自動最近這個控制區域的html代碼片。於是,java操作html的插件就誕生了!有不少類似的插件,這里我選擇比較簡單的jsoup插件。下面的簡單實驗,用到的版本是1.9.2,就一個jar包,不需要額外的資源了。
我這里上代碼,分別說明右鍵實現,以及直接追加button的方式實現。
先說右鍵實現方案,這里,右鍵菜單是用bootstrap-contextmenu.js插件實現的,是基於bootstrap風格的。
1 /** 2 * @author "shihuc" 3 * @date 2016年5月21日 4 */ 5 package opc; 6 7 import java.io.File; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 import java.io.OutputStreamWriter; 11 12 import org.jsoup.Jsoup; 13 import org.jsoup.nodes.Document; 14 import org.jsoup.nodes.Element; 15 import org.jsoup.select.Elements; 16 17 /** 18 * @author "shihuc" 19 * 20 */ 21 public class Demo { 22 23 /** 24 * @param args 25 * @throws IOException 26 */ 27 public static void main(String[] args) throws IOException { 28 File input = new File("./example.html"); 29 Document doc = Jsoup.parse(input, "UTF-8"); 30 System.out.println(doc.html()); 31 Elements content = doc.getElementsByTag("body"); 32 //找到body的內容 33 String body = content.get(0).html(); 34 System.out.println(body); 35 36 //讀取控制頁面右鍵的代碼片段 37 File pice = new File("./pice.html"); 38 Document pdoc = Jsoup.parse(pice, "UTF-8"); 39 Element control_area = pdoc.getElementById("tk-cms-page-context-menu-control-area"); 40 41 //將業務相關的html代碼片添加到右鍵菜單控制區域中 42 control_area.append(body); 43 44 //將帶有業務相關代碼的html內容填寫到原來的example.html文件的body區域 45 content.get(0).html(pdoc.html()); 46 47 FileOutputStream fos = new FileOutputStream("./output.html", false); 48 OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); 49 osw.write(doc.html()); 50 osw.close(); 51 } 52 53 }
這里的example.html文件的內容如下:
1 <!DOCTYPE HTML> 2 <html> 3 4 <body> 5 6 <div> 7 <h1 style="text-align: center; font-size: 40px; color: #abcdef">This is a test page</h1> 8 </div> 9 10 11 </body> 12 </html> 13 14
那個pice.html的內容如下:
1 <style type="text/css"> 2 .vCenter 3 { 4 vertical-align:middle; 5 margin:0 auto; 6 } 7 </style> 8 9 <div id="context-menu" style="position: absolute; z-index: 9999; top: 746px; left: 474px;" class=""> 10 <ul class="dropdown-menu" role="menu"> 11 <li><a tabindex="-1">Cancel</a></li> 12 <li><a tabindex="-1">Action</a></li> 13 </ul> 14 </div> 15 <div id="tk-cms-page-context-menu-control-area" data-toggle="context" style="height:100%;width:100%;border:1px solid #ddd;" class="vCenter"> 16 17 </div> 18 19 <script src="js/jquery-2.1.1.min.js"></script> 20 <script src="js/bootstrap.min.js"></script> 21 <script src="js/bootstrap-contextmenu.js"></script> 22 <link href="css/bootstrap.min.css" rel="stylesheet"> 23 <script type="text/javascript"> 24 $(document).ready(function(){ 25 //屏蔽掉瀏覽器顯示的頁面中的右鍵菜單。 26 document.oncontextmenu = function(){return false;}; 27 //啟用自定義的右鍵菜單 28 $('#tk-cms-page-context-menu-control-area').contextmenu({ 29 target: '#context-menu', 30 onItem: function (context, e) { 31 alert($(e.target).text()); 32 } 33 }); 34 }) 35 </script>
最后生成的output.html的內容如下:
1 <!doctype html> 2 <html> 3 <head></head> 4 <body> 5 <style type="text/css"> 6 .vCenter 7 { 8 vertical-align:middle; 9 margin:0 auto; 10 } 11 </style> 12 <div id="context-menu" style="position: absolute; z-index: 9999; top: 746px; left: 474px;" class=""> 13 <ul class="dropdown-menu" role="menu"> 14 <li><a tabindex="-1">Cancel</a></li> 15 <li><a tabindex="-1">Action</a></li> 16 </ul> 17 </div> 18 <div id="tk-cms-page-context-menu-control-area" data-toggle="context" style="height:100%;width:100%;border:1px solid #ddd;" class="vCenter"> 19 <div> 20 <h1 style="text-align: center; font-size: 40px; color: #abcdef">This is a test page</h1> 21 </div> 22 </div> 23 <script src="js/jquery-2.1.1.min.js"></script> 24 <script src="js/bootstrap.min.js"></script> 25 <script src="js/bootstrap-contextmenu.js"></script> 26 <link href="css/bootstrap.min.css" rel="stylesheet"> 27 <script type="text/javascript"> 28 $(document).ready(function(){ 29 //屏蔽掉瀏覽器顯示的頁面中的右鍵菜單。 30 document.oncontextmenu = function(){return false;}; 31 //啟用自定義的右鍵菜單 32 $('#tk-cms-page-context-menu-control-area').contextmenu({ 33 target: '#context-menu', 34 onItem: function (context, e) { 35 alert($(e.target).text()); 36 } 37 }); 38 }) 39 </script> 40 </body> 41 </html>
效果如下圖所示,只有在灰色框區域內容點擊鼠標右鍵有反應,框外點擊鼠標右鍵是沒有菜單出來的,那個框,限定了菜單的有效控制范圍。
下面,再來看看,直接追加button在業務模板html頁面后面的實現方案。直接上代碼!
example.html的部分與上面一樣,不再列舉,下面先說java的部分:
1 /** 2 * @author "shihuc" 3 * @date 2016年5月21日 4 */ 5 package opc; 6 7 import java.io.File; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 import java.io.OutputStreamWriter; 11 12 import org.jsoup.Jsoup; 13 import org.jsoup.nodes.Document; 14 import org.jsoup.nodes.Element; 15 import org.jsoup.select.Elements; 16 17 /** 18 * @author "shihuc" 19 * 20 */ 21 public class Demo2 { 22 23 /** 24 * @param args 25 * @throws IOException 26 */ 27 public static void main(String[] args) throws IOException { 28 File input = new File("./example.html"); 29 Document doc = Jsoup.parse(input, "UTF-8"); 30 System.out.println(doc.html()); 31 Elements content = doc.getElementsByTag("body"); 32 //找到body的內容 33 Element body = content.get(0); 34 System.out.println(body.html()); 35 36 //讀取控制頁面右鍵的代碼片段 37 File pice = new File("./pice2.html"); 38 Document pdoc = Jsoup.parse(pice, "UTF-8"); 39 40 //將控制頁面相關邏輯代碼追加到業務頁面example.html的最后面。 41 body.append(pdoc.html()); 42 43 FileOutputStream fos = new FileOutputStream("./output2.html", false); 44 OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); 45 osw.write(doc.html()); 46 osw.close(); 47 } 48 49 }
再來列舉pice2.html的代碼部分:
1 <style type="text/css"> 2 .vCenter 3 { 4 vertical-align:middle; 5 margin:0 auto; 6 } 7 </style> 8 9 <div id="tk-cms-op-btn" style="border:1px solid #ddd; padding: 10px 10px" class="vCenter"> 10 <button type="button" onclick="cancel();">Cancel</button> 11 <button type="button" onclick="action();">Action</button> 12 </div> 13 14 <script src="js/jquery-2.1.1.min.js"></script> 15 <script type="text/javascript"> 16 function cancel(){ 17 alert("cancel"); 18 } 19 function action(){ 20 alert("action"); 21 } 22 $(document).ready(function(){ 23 24 }); 25 </script>
最后看看輸出部分output2.html的代碼片:
1 <!doctype html> 2 <html> 3 <head></head> 4 <body> 5 <div> 6 <h1 style="text-align: center; font-size: 40px; color: #abcdef">This is a test page</h1> 7 </div> 8 <style type="text/css"> 9 .vCenter 10 { 11 vertical-align:middle; 12 margin:0 auto; 13 } 14 </style> 15 <div id="tk-cms-op-btn" style="border:1px solid #ddd; padding: 10px 10px" class="vCenter"> 16 <button type="button" onclick="cancel();">Cancel</button> 17 <button type="button" onclick="action();">Action</button> 18 </div> 19 <script src="js/jquery-2.1.1.min.js"></script> 20 <script type="text/javascript"> 21 function cancel(){ 22 alert("cancel"); 23 } 24 function action(){ 25 alert("action"); 26 } 27 $(document).ready(function(){ 28 29 }); 30 </script> 31 </body> 32 </html>
看看example.html模板文件在追加了控制代碼片后的效果:
到此,兩種通過jsoup操作html添加頁面控制單元的實現方案都列舉出來,讀者是不是有疑問了,這兩者有啥區別,或者說到底那種要好點呢?
個人覺得,第一種右鍵菜單的那個,最終頁面的視覺效果會干凈點,但是,右鍵菜單是基於bootstrap的,引入了bootstrap.css以及bootstrap.js和bootstrap-contextmenu.js,所以,這個會對業務模板代碼可能會造成影響。也就是說有些side effect. 另外的一種方案,就是直接添加button的,這個雖然不是那么好看,但是他需要的而外的插件資源少,最多就是一個jQuery的插件。其實,右鍵方式,也需要jQuery插件。
不多說了,有需要的,自己選擇參考!測試的工程中引入了的資源文件等文件結構如下圖所示: