iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

雖然在JSXGraph中可以輕易建立button、chebox、label…等元件,但是這些元件會在畫板內,因此排版並不方便,也會干擾幾何元素的呈現。今天我們將昨天的按鈕從JSXGraph的容器獨立出來,另外建立這些按鈕的容器。因此今天我們會學習Html的基本觀念、DOM的操作和CSS選擇器的語法。

HTML和簡報軟體

我個人比較傾向將網頁的功能類比於Powerpoint、Keynote、Impress...這類簡報軟體,它可以容納各式各樣媒體,像是文字、圖片、影片、音樂…等,可以幫這些媒體進行排版工作,也可以製作動畫。

當然簡報軟體具備WYSIWYG(what you see is what you get)的所見即所得特性,又有大量的圖形介面,可以利用滑鼠選擇屬性的設定值,對一般人學習比較容易理解,大大的降低了軟體的學習難度。而網頁則需要將HTML、CSS和Javascript三個元素交由網頁瀏覽器解析後,再將畫面呈現出來,學習門檻高了很多。在可程式化的部份,簡報軟體大多可由VBA來操控簡報軟體的物件,來進行一些自動化的工作;而網頁則依賴Javascript這個程式語言和HTML的DOM來進行自動化的工作。無論是簡報軟體或網頁對一般使用者的學習難度都相當的高。

就目前這樣分析,簡報系統在使用上是優於網頁,目前現況也是如此,但是簡報軟體還是有一些潛在性的缺點。

  • 封閉性:簡報軟體之間並不完全相容,尤其是巨集的部分,彼此的檔案格式都無法完全相容,容易產生跑版的情形和巨集無法執行的情形。反觀網頁已經成為媒體呈現的主流,W3C也製定網頁標準,同一份文件,在不同的瀏覽器都能得到一致的呈現。
  • 第三方套件:網頁有非常多Javascript開源套件供開發者使用,只要是想得到的需求,幾乎都可以找到相對應的套件,更有一些專業人士(像數學、物理、音樂、...)開發出專業等級的套件供網頁開發者使用,這些專業套件的使用難度也只比具圖形介面的套裝軟體難一些些,像這系列介紹的JSXGraph就是一個很好的例子。而簡報軟體就無法具備這麼多套件,即便開源軟體LibreOffice的Impress也無法執行JSXGraph這類型套件,更別說Powerpoint和Keynote這兩個商用軟體。

基於這個原因,筆者才借鐵人賽這個機會介紹JSXGraph這個套件,希望具有簡單程式設計的數學老師,在簡略的學習網頁後,能設計出可在上課中實用的教學網頁。接下來會以完成範例為目標,用最精簡的方式介紹Html、DOM和Css選擇器。

HTML配置和DOM淺談

    <h2 class="title">尤拉線定理</h1>
    <div class="container">
      <div id="box" class="jxgbox" style="width: 500px;height: 500px;"></div>
      <div class="btnContainer">
        <div class="btns">
          <button type="button" class="btn medians">顯示中線</button>
          <button type="button" class="btn centroid">顯示重心</button>
          <button type="button" class="btn biperpendiculars">顯示中垂線</button>
          <button type="button" class="btn circumcentre">顯示外心</button>
          <button type="button" class="btn altitudes">顯示高</button>
          <button type="button" class="btn orthocentre">顯示垂心</button>
          <button type="button" class="btn Eulerline">顯示尤拉線</button>
        </div>
      </div>
   </div>

一個class可以有多個值,瀏覽器會存在陣列中。

HTML(HyperText Markup Language),也就是超文本標記語言,是可延伸標記語言XML(Extensible Markup Language)的一種,因此我們可以將它的文件建立成一個樹狀結構圖,如上例的HTML碼就可以建成下圖:
image
這個樹狀結構就稱為DOM,DOM是Document Object Model的縮寫,上下的節點關係是父子節點,同屬一個父節點,即為兄弟節點。DOM中每個節點(node)都有各自的屬性,像id、class、style、src…等等,每個屬性也有各自的功能。其中id屬性不可重複,可以唯一識別節點;而class通常作為CSS選擇器選擇節點用,可以在style.css中撰寫css用,許多編輯器中也提供CSS選擇快捷寫出html檔,也可以提供javascript操作DOM。javascript的document下有很多操作DOM的方法,為了簡單化,這邊就介紹querySelector和querySelectorAll兩個方法,這兩個方法都必須使用CSS選擇器,所以我們先說明CSS選擇器。

CSS選擇器

CSS的基本語法非常簡單,就是標籤[屬性="屬性值"],標籤和屬性值有些時候可省略,接下來介紹常用的選擇器。

  • id選擇器[id="id值"]:因為id是獨一無二,只需要屬性值,可以簡寫成#id值,例如#box可選擇下面節點。
<div id="box" class="jxgbox" style="width: 500px;height: 500px;"></div>
  • 類別選擇器[class="類別值"]:可以選擇具有此類別值的節點,可以簡寫成.類別值,例如.btn可選擇下列節點。
<button type="button" class="btn medians">顯示中線</button>
<button type="button" class="btn centroid">顯示重心</button>
<button type="button" class="btn biperpendiculars">顯示中垂線</button>
<button type="button" class="btn circumcentre">顯示外心</button>
<button type="button" class="btn altitudes">顯示高</button>
<button type="button" class="btn orthocentre">顯示垂心</button>
<button type="button" class="btn Eulerline">顯示尤拉線</button>
  • 後代選擇器: A B,選擇符合A條件的後代節點中,符合B條件的節點。例如.container .btns
  • 直屬選擇器: A>B,選擇符合A條件的子節點中,符合B條件的節點。例如.container .btnContainer

DOM和事件操作

我們會用的函式有下面幾個

  • querySelector('CSS選擇器'): 會選擇滿足選擇器的第一個節點回傳。
  • querySelectorAll('CSS選擇器'): 會選擇滿足選擇器的所有節點,回傳值是一個陣列。
  • addEventLister('事件名稱', 回呼函式):當事件發生時,會執行回呼函式。

常用的事件有clickdblclickkeyupkeydownmouseover…等等

下面這段程式碼製作了可以切換三中線的顯示和顯藏的按鈕。

const btnMedians = document.querySelector('.medians')
btnMedians.addEventListener('click', () => {
  showMedians = !showMedians
  board.update()
  if (showMedians) {
    btnMedians.innerHTML = '隱藏中線'
  } else {
    btnMedians.innerHTML = '顯示中線'
  }
})

箭頭函式不能使用this

程式的結構和昨天使用JSXGraph內建的按鈕大同小異,因為這是在畫板外的按鈕,回呼函數要記得使用board.update()更新畫面。this指得是觸發事件的節點,在這裏就是代表btnMedians。我們可以用同樣的結構寫下其它七個按鈕的程式,程式碼連結在後面。

同樣的結構寫了七次,感覺有些冗長,我們將html的部分重新配置,像顯示中線的按鈕改成

<button class="btn" data-element="medians">顯示中線</button>

我們設置了data-element的屬性,在javascript中可以用this.dataset.element存取其中的內容。javascript中,我們刪去了showMedians…等變數,設置了elements的物件,並利用querySelectorAll('.btn')選取了所有包含btn class的button節點佇列(nodesList),forEach方法寫成簡潔的程式碼。

const elements = {
  medians: {
    title: '中線',
    show: false,
  },
  biperpendiculars: {
    title: '中垂線',
    show: false,
  },
  altitudes: {
    title: '高',
    show: false,
  },
  centroid: {
    title: '重心',
    show: false,
  },
  circumcentre: {
    title: '外心',
    show: false,
  },
  orthocentre: {
    title: '垂心',
    show: false,
  },
  Eulerline: {
    title: '尤拉線',
    show: false
  }
}

const medianAB = board.create('segment', [pointC, midpointAB], { visible: () => elements.medians.show })
// 替每個節點加入事件監聽
const btns = document.querySelectorAll('.btn')
btns.forEach(btn => {
  btn.addEventListener('click', handleToggle)
})

// 監聽事件使用同一個監聽函數
function handleToggle(e) {
  let ele = this.dataset.element
  elements[ele].show = !elements[ele].show
  board.update()
  if (elements[ele].show) {
    this.innerHTML = '隱藏' + elements[ele].title
    this.style.background = '#37613C'
    this.style.color = 'white'
    this.style.borderColor = '#f0f0f0'
  } else {
    this.innerHTML = '顯示' + elements[ele].title
    this.style.background = '#F0F0F0'
    this.style.color = '#37613C'
    this.style.borderColor = '#37613C'
  }
}

因為所有的監聽都使用同一個監聽函數,我們沒有使用箭頭函式,因此可以使用this這個關鍵字,這裏this也可以用e.currentTarget或e.target代替,這兩個略有不同,牽涉到DOM的Event Propagation,這邊就不多談了。

今日程式碼連結

(https://replit.com/@yegc22/iThomeIronman2022Day7-1?v=1 )

今日小結

程式碼將一些按鈕,滑桿獨立出來,可以讓版面更清爽,也寫了簡單的CSS做了按鈕的排版,也具備一些簡單的RWD效果。利用CSS可以做出美觀的UI介面,因應手機使用的趨勢,製作響應式設計(RWD:Responsive Web Design)的網頁畫面。接下來的幾天,我們就會介紹一些CSS排版的重要概念,並利用它們美化我們的介面。


上一篇
Euler線和Button元素
下一篇
CSS基本觀念
系列文
30天數學老師作互動式教學網頁30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言