2021/04/25

網站 / 使用 JavaScript 開啟新視窗跟對話窗

很多網站會在文章內容設定某些關鍵字可以開啟新視窗,或者對話窗

我也想嘗試替網站增加這個功能

由於WordPress網站使用PHP語言,這主要是用在網站後端的程式語言

在前端頁面設定功能通常是用JavaScript前端程式語言

因此必須處理如何在WordPress網站使用JavaScript的問題

要在WordPress網站使用JavaScript的方式可以透過之前使用過的兩個外掛來達成

「PHP everywhere」跟「程式碼片段」

程式碼片段可以直接輸入程式碼,不需要額外用echo

而PHP everywhere 可以在文章中崁入JavaScript程式碼(例如:加在文章的最後面)

這次改用另一個外掛「Code Embed」 ,算是結合前面兩種的特色

1.可以決定在文章的哪個位置插入程式碼,這樣可以避免資料尚未載入,程式就已經執行而造成錯誤

2.不需要額外加 echo 串接程式碼

但是,仍然必須將代表jQuery的$符號改用文字-jQuery表示

以下是最終的成果

這個是對話窗的程式,將要呈現的內容包覆在<div id=”dialog2″></div>之內

並且在文章內選定的文字設定id為opener2的超連結

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<script>
	jQuery(function(){
		jQuery("#dialog2").dialog({
			position: {my: "left top", at: "right bottom", of: "#opener2"},
			width: 600,
			autoOpen: false,
			show: {effect: "blind",duration: 1000},
			hide: {effect: "blind",duration: 1000}}
		);
		jQuery("#opener2").on("click", function(event){
			jQuery("#dialog").dialog("open");
			event.preventDefault()
			}
		);
	});
</script>

 

需要注意的是定位的設定

position: {my: “left top”, at: “right bottom”, of: “#opener2”}→用自己(對話窗)的左上 對準 #opener2(超連結文字)的右下

my-被定位元素 對準 目標元素的地方
at-目標元素 被對準的地方
of-目標元素
方位:左中右 上中下

 
這個是開新視窗的程式,必須使用window.open(目標網址, 視窗標題, config)設定內容

同樣在選定的文字設定id為ad2的超連結

1
2
3
4
5
6
<script>
	var me2 = document.getElementById('ad2')
	me2.addEventListener('click',
		function(e){window.open('http://tw.yahoo.com','Yahoo',config='height=450,width=600,toolbar=no,location=no,menubar=no,status=no');e.preventDefault()}		
	)
</script>

 

兩者可以依據內容來選擇

對話窗可以用html來編輯內容,但是只能在JavaScript設定視窗大小跟相關的樣式

(因為對話窗是透過jQuery產生的,無法用其他方式修改CSS樣式)

新視窗可以開啟外部網頁,目前用超連結的方式來呈現

感覺會有點多此一舉,不過如果將id設在<Button>,這樣網頁的效果就會比較活潑一點

這兩個功能都是運用事件觸發/綁定/監聽功能,JavaScript 跟 jQuery的語法有點不同

由於是將 id設在超連結標籤,所以必須停止點選超連結之後的事件默認動作

也就是在事件的function的最後加上 preventDefault()

例如上面的event.preventDefault() 或 e.preventDefault()

(event  跟 e的功能一樣,都是function用來傳遞事件物件 (Event Object)的參數)

 

下面的連結是完成後的樣式

Open ad-開新視窗

Open Dialog-開對話窗

 
 

參考資料

jQuery UI API – 对话框部件(Dialog Widget)

JavaScript window.open() 開新視窗以及屬性設定

[筆記][JavaScript]所謂的「停止事件」到底是怎麼一回事?

重新認識 JavaScript: Day 15 隱藏在 “事件” 之中的秘密

JS函数function(event){}在括号内写个event的意思

javascript–事件对象e的来源、意义、应用及其属性的用法 function(e){}

2021/04/17

Gg / 透過LINE Notify推播Google行事曆的每日提醒

這個練習結合了之前的LINE Notify,以及Google Apps Script的Calendar功能

為了避免跟之前的文章推播混淆

申請了新的LINE Notify token

而Google Calendar的部分使用了getEventsForDay(date)

來取得特定日期的所有活動

因為是所有活動的資料,也就是陣列型態的資料,所以透過 For loop的方式逐一取出資料

補充說明註解掉的程式內容

//var twoHoursFromNow = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000); //日 時 分 秒 毫秒
//var events = cal.getEvents(now, twoHoursFromNow);

這原本是Google的範例,使用了getEvents(startTime, endTime)來取得特定時間範圍內的事件

而變數 twoHoursFromNow則是透過new Date()設定時間範圍

也就是當下時間的變數 now,利用getTime()取得毫秒數,再加上要間隔的時間毫秒數

另外,比較需要注意的是,Google Apps Script的時區不是台北時間

因此必須重新設定時間格式

 Utilities.formatDate(new Date(),"GMT+8","yyyy/MM/dd HH:mm")

透過變數now取得當下的台北時間,因為Utilities.formatDate()回傳的是字串型態

於是再透過new Date()將字串轉為日期時間型態

var now = Utilities.formatDate(new Date(),"GMT+8","yyyy/MM/dd HH:mm");
now=new Date(now);

整體的程式分為兩部分

myCalendar()處理Google Calendar的資料,再傳到sendMessage()執行推播功能

因為sendMessage()是直接取用之前的版本

如果不需要傳出圖片的話,在myCalendar()就可以不用傳出pictureURL

當然如果要傳插圖的話,也可以設定傳出的插圖參數

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
function myCalendar() {

var cal = CalendarApp.getCalendarById("************************");

var now = Utilities.formatDate(new Date(),"GMT+8","yyyy/MM/dd HH:mm");

now=new Date(now);

Logger.log(now);
//var twoHoursFromNow = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000); //日 時 分 秒 毫秒
//var events = cal.getEvents(now, twoHoursFromNow);

var events =cal.getEventsForDay(now);

//Logger.log(events.length);

for (var i = 0; i < events.length; i++) {
  Logger.log("Event: " + events[i].getTitle() + "\n"
            +"Event Start Time: " + Utilities.formatDate(events[i].getStartTime(),"GMT+8","yyyy/MM/dd HH:mm") + "\n" 
            +"Event End Time: " + Utilities.formatDate(events[i].getEndTime(),"GMT+8","yyyy/MM/dd HH:mm") + "\n"
            +"Event Location: " + events[i].getLocation()
    );
  var message = "\n" 
              +"Event: " + events[i].getTitle() + "\n" 
              +"Event Start Time: " + Utilities.formatDate(events[i].getStartTime(),"GMT+8","yyyy/MM/dd HH:mm") + "\n" 
              +"Event End Time: " + Utilities.formatDate(events[i].getEndTime(),"GMT+8","yyyy/MM/dd HH:mm") + "\n" 
              +"Event Location: " + events[i].getLocation();

  var pictureURL= "https://i2.kknews.cc/SIG=1hsq8os/ctp-vzntr/r3sn77r39o364q46nps4n57pop734q35.jpg";
  sendMessage(message, pictureURL);
  }
}

function sendMessage(message, pictureURL){
  var Token = "******************************************";
  var URL = "https://notify-api.line.me/api/notify";

  var payload = 
      {
        'message' : message,
        //'imageThumbnail': pictureURL,
        //'imageFullsize': pictureURL
      };
  
  var header =
      {
        'Content-Type':'application/x-www-form-urlencoded',
        'Authorization' : 'Bearer ' + Token        
      }
  
  var options =
      {
        'method'  : 'post',
        'payload' : payload,
        'headers' : header
      }; 

  var response = UrlFetchApp.fetch(URL, options);
  Logger.log(response);
}

 

因為要達成每日的推播提醒

所以在觸發條件是設定成時間型觸發條件類型的日計時器

這樣就可以在每天的特定時間內觸發程式