我的另一博客地址:https://segmentfault.com/u/lyrfighting/articles
前段時間,一直在開發考勤系統,當時為滿足設計的需求,選了好幾個插件,最后決定采用Fullcanlendar的插件。感覺這個插件可以滿足現階段的功能開發需求
需求圖
一、使用方式
1、依賴的文件引入
2、頁面使用--具體的各項屬性和方法可以參照中文手冊https://blog.csdn.net/ymnets/article/details/78661247
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title>Fullcanlendar代碼示例</title> <link rel="stylesheet" type="text/css" href="css/fullcalendar.min.css"/> <link rel="stylesheet" type="text/css" href="css/fullcalendar.print.css"/> </head> <body>
<div class="canlendar" id="calendar"></div>
<script type="text/javascript" src="js/moment.min.js" ></script> <script type="text/javascript" src="js/jquery.min.js" ></script> <script type="text/javascript" src="js/jquery-ui.min.js" ></script> <script type="text/javascript" src="js/fullcalendar.min.js" ></script> <script> $('#calendar').fullCalendar({ /*設置日歷頭部信息,如果設置為false,則不顯示頭部信息。 * 包括left,center,right左中右三個位置都可以對應一下配置 * title:顯示當前月份/周、日信息 * prev:用於切換到上一月/周/日視圖的按鈕 * next:用於切換到下一月/周/日視圖的按鈕 * prevYear:用於切換到上一年視圖的按鈕 * nextYear:用於切換到下一年視圖的按鈕 * */ header:{ left: '', center: 'Fullcanlendar示例demo', right: 'today prev,next' }, theme:false,//如果設置為true,則需要加載jquery ui相關css和js文件,默認值為false firstDay:1,//設置一周中顯示的第一天是哪天,周日是0,周一是1,類推 isRTL:false,//設置為ture時則日歷從右往左顯示 weekends:true,//是否顯示周末,設為false則不顯示周六和周日。默認值為true hiddenDays:[],//隱藏一周中的某一天或某幾天,數組形式,如隱藏周二和周五:[2,5],默認不隱藏,除非weekends設置為false。 weekMode:'fixed',//在月視圖里顯示周的模式,因為每月周數可能不同,所以月視圖高度不一定。fixed:固定顯示6周高,日歷高度保持不變liquid:不固定周數,高度隨周數變化variable:不固定周數,但高度固定 weekNumbers:false,//是否在日歷中顯示周次(一年中的第幾周),如果設置為true,則會在月視圖的左側、周視圖和日視圖的左上角顯示周數。 weekNumberCalculation:'iso',//周次的顯示格式。 //height:600,//設置日歷的高度,包括header日歷頭部,默認未設置,高度根據aspectRatio值自適應。 //contentHeight://設置日歷主體內容的高度,不包括header部分,默認未設置,高度根據aspectRatio值自適應。 aspectRatio:1.35,//設置日歷單元格寬度與高度的比例。 handleWindowResize:true,//是否隨瀏覽器窗口大小變化而自動變化。 render:function(view){ console.log('render',view) },//method,綁定日歷到id上。$('#id').fullCalendar('render'); destroy:function(){ }, weekNumbers : false, //是否在視圖左邊顯示這是第多少周,默認false eventLimit: true, //數據條數太多時,限制各自里顯示的數據條數(多余的以“+2more”格式顯示),默認false不限制,支持輸入數字設定固定的顯示條數 viewRender : function(view,element){//在視圖被渲染時觸發(切換視圖也觸發) 參數view為視圖對象,參數element為Jquery的視圖Dom }, dayRender : function(date, cell){//日期格式Render鈎子函數(我沒理解清楚) console.log("↓↓↓dayRender↓↓↓"); console.log(date); console.log(cell); }, windowResize : function(){//瀏覽器窗體變化時觸發 console.log("---windowResize---"); }, allDayText : "全天", //自定義全天視圖的名稱 slotDuration : "01:00:00", //一格時間槽代表多長時間,默認00:30:00(30分鍾) slotLabelFormat : "H(:mm)a", //日期視圖左邊那一列顯示的每一格日期時間格式 slotLabelInterval : "02:00:00", //日期視圖左邊那一列多長間隔顯示一條日期文字(默認跟着slotDuration走的,可自定義) snapDuration : "05:00:00", //其實就是動態創建一個日程時,默認創建多長的時間塊 slotEventOverlap : false, //相同時間段的多個日程視覺上是否允許重疊,默認true允許 noEventsMessage : "L沒數據啊", //listview視圖下,無數據時顯示提示 defaultDate : '2018-09-10', //默認顯示那一天的日期視圖getDates(true) nowIndicator : true, //周/日視圖中顯示今天當前時間點(以紅線標記),默認false不顯示 monthNames : ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], //月份自定義命名 monthNamesShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], //月份縮略命名(英語比較實用:全稱January可設置縮略為Jan) dayNames: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"], //同理monthNames dayNamesShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"], //同理monthNamesShort weekNumberTitle : "周", //周的國際化,默認為"W" eventLimitText : "更多", //當一塊區域內容太多以"+2 more"格式顯示時,這個more的名稱自定義(應該與eventLimit: true一並用) dayPopoverFormat : "YYYY年M月d日", //點開"+2 more"彈出的小窗口標題,與eventLimitClick可以結合用 navLinks : true, // “xx周”是否可以被點擊,默認false,如果為true則周視圖“周幾”被點擊之后進入日視圖。本地測試:沒什么效果 dayClick: function(date, jsEvent, view) {//空白的日期區,單擊時觸發 console.log("↓↓↓dayClick↓↓↓"); console.log('Clicked on: ' + date.format()); console.log('Coordinates: ' + jsEvent.pageX + ',' + jsEvent.pageY); console.log('Current view: ' + view.name); //$(this).css('background-color', 'red'); }, eventClick: function(calEvent, jsEvent, view) {//日程區塊,單擊時觸發 console.log(jsEvent.target) alert(jsEvent.target.innerHTML) console.log("↓↓↓eventClick↓↓↓"); console.log('Event: ' + calEvent.title); console.log('Coordinates: ' + jsEvent.pageX + ',' + jsEvent.pageY); console.log('Current view: ' + view.name); return false; //return false可以阻止點擊后續事件發生(比如event中的url跳轉事件) }, eventMouseover: function(calEvent, jsEvent, view){//鼠標在日程區塊上時觸發 console.log(jsEvent) console.log(calEvent.start._i) $('.hover-dateStr').html(calEvent.start._i) console.log(jsEvent.pageY,jsEvent.pageX) $('.hover-container').removeClass('none').animate({'top':jsEvent.pageY,'left':jsEvent.pageX}) if(!canRun){ // 判斷是否已空閑,如果在執行中,則直接return return; } }, eventMouseout: function(calEvent, jsEvent, view){//鼠標從日程區塊離開時觸發 $('.hover-container').addClass('none') }, selectable: false, //允許用戶可以長按鼠標選擇多個區域(比如月視圖,可以選中多天;日視圖可以選中多個小時),默認false不能選擇多區域的 selectHelper: true, //接selectable,周/日視圖在選擇時是否預先畫出“日程區塊”的樣式出來 unselectAuto : true, //是否點擊頁面上的其他地方會導致當前的選擇被清除,默認true unselectCancel : "", //一種方法來指定元素,會忽略unselectauto選項,默認'' selectOverlap : true, //確定用戶是否被允許選擇被事件占用的時間段,默認true可占用時間段 selectAllow : function(selectInfo){ //精確的編程控制用戶可以選擇的地方,返回true則表示可選擇,false表示不可選擇 console.log("↓↓↓selectConstraint↓↓↓"); console.log("start:"+selectInfo.start+"|end:"+selectInfo.end+"|resourceId:"+selectInfo.resourceId); return true; }, select: function(start, end,jsEvent,view) { //點擊空白區域/選擇區域內容觸發 }, unselect : function(view, jsEvent){//選擇操作取消時觸發 console.log("↓↓↓unselect↓↓↓"); console.log("view:"+view); }, lazyFetching : true, //是否啟用懶加載技術--即只取當前條件下的視圖數據,其它數據在切換時觸發,默認true只取當前視圖的,false是取全視圖的 defaultTimedEventDuration : "02:00:00", //在Event Object中如果沒有end參數時使用,如start=7:00pm,則該日程對象時間范圍就是7:00~9:00 defaultAllDayEventDuration : { days: 1 }, //默認1天是多長,(有的是采用工作時間模式,所以支持自定義) loading : function(isLoading, view){ //視圖數據加載中、加載完成觸發 console.log("↓↓↓loading↓↓↓"); if(isLoading == true){ console.log("view:"+view+",開始加載"); }else if(isLoading == false){ console.log("view:"+view+",加載完成"); }else{ console.log("view:"+view+",除非天塌下來否則不會進這個分支"); } }, eventOrder : "title", //多個相同的日程數據排序方式,String / Array / Function, 默認值: "title" eventRender : function(event, element, view) { //當Event對象開始渲染時觸發 console.log("eventRender():"+event.title); }, eventAfterAllRender : function(view){console.log("eventAfterAllRender();");}, //當所有Event對象渲染完成時觸發 editable: true, //支持Event日程拖動修改,默認false eventStartEditable : true, //Event日程開始時間可以改變,默認true,如果是false其實就是指日程塊不能隨意拖動,只能上下拉伸改變他的endTime eventDurationEditable : false, //Event日程的開始結束時間距離是否可以改變,默認true,如果是false則表示開始結束時間范圍不能拉伸,只能拖拽 dragOpacity:0.2, //拖拽時不透明度,0.0~1.0之間,數字越小越透明 dragScroll : true, //是否在拖拽時自動移動容器,默認true eventOverlap : true, //拖拽時是否重疊 eventConstraint : { //限制拖拽拖放的位置(即限制有些地方拖不進去):an event ID, "businessHours", object start: '10:00', // a start time (10am in this example) end: '18:00', // an end time (6pm in this example) dow: [ 1, 2, 3, 4 ] // days of week. an array of zero-based day of week integers (0=Sunday) (Monday-Thursday in this example) }, longPressDelay : 1000, //面向可touch設備(如移動設備),長按多少毫秒即可拖動,默認1000毫秒(1S) eventDragStart : function(event, jsEvent, ui, view){ //日程開始拖拽時觸發 console.log("eventDragStart():"+event.title); }, eventDragStop : function(event, jsEvent, ui, view){ //日程拖拽停止時觸發 console.log("eventDragStop():"+event.title); }, eventDrop : function(event, delta, revertFunc, jsEvent, ui, view){ //日程拖拽停止並且已經拖拽到其它位置了 console.log("eventDrop():"+event.title); }, eventResizeStart : function( event, jsEvent, ui, view ) { //日程大小調整開始時觸發 console.log("eventResizeStart():"+event.title); }, eventResizeStop : function(event, jsEvent, ui, view){ //日程大小調整停止時觸發 console.log("eventResizeStop():"+event.title); }, eventResize : function(event, delta, revertFunc, jsEvent, ui, view){ //日程大小調整完成並已經執行更新時觸發 console.log("eventResize():"+event.title); }, events:[ { "time": "9:20--18:20", "antualTime":"9:40--18:40", "start": "2018-09-01" }, { "time": "9:40--18:40", "antualTime":"9:40--18:40", "start": "2018-09-02" } ] }); </script> </body> </html>
三、獲取數據:
整個的插件使用的難點就在於獲取數據,如果依賴events函數直接獲得數據源的話,將后台傳過來的當月數據整理好放入回調函數中,也是可行的,但是在獲取上一個月或者下一個月的時候數據不會再次獲取數據;
使用eventSources也是同樣的道理,具體可以查看博客https://www.helloweba.net/javascript/454.html;
使用ajax請求,向后台請求該月份的數據的話,最好的方式就是在切換月份的時候,請求接口,獲取數據;而不是一次獲取大量的數據渲染,這樣會導致渲染速度太慢,網頁響應速度慢,影響用戶的體驗。
//初始化日程表 events:function(start, end, timezone,callback){ var date = this.getDate().format('YYYY-MM'); var arr=date.split("-"); var events = loopMonthDay(arr[0],arr[1]); //loopMonthDay(arr[0],arr[1]); 是自己封裝的函數
callback(events);//將整理好格式的數組放在回調中執行,這樣在切換月份的時候就會自動掉接口獲取
}
四、說明
因為默認的Fullcanlendar的樣式比較簡單直接,所以一般情況下是需要改寫樣式的。