D29 - 走!去浏览器自己刻表单选 pizza 口味

前言

自己设计 pizza 材料表单!

认识 html input 标签

input 可以用在表单输入上,而内建的种类有很~多种,像是预设的文字输入或是数字输入、颜色点选甚至是日期视窗等...
MDN input type,今天要来玩的是 input type='radio',称为单选按钮,让使用者可以点选。

今天就设计一张 pizza 标单让客人选自己想要的配料!

请问您要什麽配料?

基本的 html 架构设定,在 form 表单下放置 label + input 作为选填项目。

html 基本设定

<form id="first-form">
    <p>How would you like your pizza?</p>
    <fieldset class="sauces option">
        <legend>Sauce:</legend>

        <label for="pesto">
            <input type="radio" name="sauce" id="pesto" value="pesto" />
            <span class="checkmark">pesto</span>
    </lable>
    </fieldset>
    ....
</form>

重点:

  • input 包在 label 内可以增加点击范围,或是用 label for='input 的 id 名称' 来绑定同一组的 inputlabel

  • 相同 name 属性名称的input 是单选效果,name 名称不同变为多选 -> 套用在第二种 ingredient 选择上。

  • inputvalue 属性设置跟材料称呼一样。

先刻出以下画面:

设定 JavaScript

需要监听的动作:

  1. 点选时取得材料名称,右框框展示对应图片。
  2. 点选提交时改变框框画面。

第一步:监听 change Event

radio typeinput 被点选状态变为 checked 时,change event 可以侦测的这个变化,启动相应的动作。
利用这个事件,侦测滑鼠点选到哪一个材料,右边框框 background-image 改为该材料图片。

// 先选好需要的元素
let get = (tag) => document.querySelector(tag); 
let display = get('.displayImg'); // 右边展示框

// 直接对 document 绑定 change event
document.addEventListener('change', function (event){
// event.target 会是点选的该材料标签,取该节点的 value 属性
let componentImg = event.target.value; // 将点选的 材料 value 存入变数中

// 改变右框框背景图片为点选的材料
display.style.backgroundImage = `var(--${componentImg})`;
});

绑定 document 的 change event,每次侦测到有框框被点击时,event.target 会指向该 input,在每个 input 上都有设定属性 value 值,event.target.value 可以取得设定的材料名称,放入变数中方便修改背景图使用。

tips:
利用 css 设定变数的方式,将材料的图片路径预先放入 css 变数中,而变数的命名须和属性 value 值设定一致,就可以依目前印出的 value 值换上该名称的 css 变数。

第二步:绑定 submit Event

注意:submit event 需绑定在 form 上才有效果,不是 input 也不是 button 唷!因为提交的是整个 form 才对。

formsubmit 事件有预设行为会传送到 server,但今天的实作不需要传到後端,因此要用 event.preventDefault() 取消预设行为。

let form = get('#first-form'); // form 表单

// submit 监听事件绑定在 form 表单上
form.addEventListener('submit', submitOrder);

function submitOrder() {
    event.preventDefault(); //必须取消预设行为
    let options = [...this.elements]; // form 表单下的所有物件存成阵列
    
    // 将背景图片清空
    display.style.backgroundImage = ''
    
    // 取出点选的元素
    let chosedTarget = options.filter((e) => e.checked);
    
    // 设定 3 秒後印出选择的材料名称
    setTimeout(()=>{
          for(let item of chosedTarget){
          display.textContent+= item.value+'';
        }
    },3000)
}

透过展开运算子将 form 表单下的所有元素 this.elements 存入阵列中,不然原本取出的会是 nodeList,使用 filter 取出状态是 checked = true 的元素,结果要将选择的材料名称印在画面上,用 for...of + display.textContent+= item.value+'' 的方式依序加入右框框的 textContent
内,外面包一层 setTimeout 选择延迟 3 秒後印出,这样可以先跑 preparing ... 的动画效果。

成果

Reference

MDN change event
PJCHENder - CSS Variables
换 input 按钮 Styling a radio button with only CSS
图片来源 - freePik
参考: https://codepen.io/gretema/pen/qzwzrG

结语

终~於~快~结~束~了~


<<:  Day29 自动合成物品的小乌龟与指令

>>:  用 Python 畅玩 Line bot - 10:File message, Location message

量化交易30天 Day28 - 投资组合概念(八) CAPM实际应用

量化交易30天 本系列文章是纪录一位量化交易新手的学习过程,除了基础的Python语法不说明,其他...

[Day30] -- 完赛

这次的铁人赛进入了最後一天,感谢夥伴们彼此的扶持,也感谢没有放弃的自己。这次的DRF系列文章希望能帮...

[day-5] 我与我的第一个程序,HelloWorld和背後的历史!

Hello World 的起源 通常我们在测试一个程序或是一个环境是否正常 会习惯使用 Hello ...

[Day25] Query Builder查询生产器

介绍 Laravel 的数据库查询构建器提供了一个方便、流畅的界面来创建和运行数据库查询。它可用於在...

c语言中exit的用法

纪录一下遇到错误时直接exit的写法 #include <stdio.h> #inclu...