สร้างปฏิทินโดยคำนึงถึงการเข้าถึงและความเป็นสากล

สร้างปฏิทินโดยคำนึงถึงการเข้าถึงและความเป็นสากล

โหนดต้นทาง: 2009236

การค้นหาอย่างรวดเร็วที่นี่บน CSS-Tricks แสดงให้เห็นว่ามีหลายวิธีในการเข้าถึงปฏิทิน บางคนแสดงวิธีการ CSS Grid สามารถสร้าง Layout ได้อย่างมีประสิทธิภาพ. บางคนพยายามที่จะ นำข้อมูลจริงมาผสมผสาน. บาง พึ่งพากรอบ เพื่อช่วยในการจัดการของรัฐ

มีข้อควรพิจารณามากมายเมื่อสร้างส่วนประกอบปฏิทิน ซึ่งมากกว่าสิ่งที่กล่าวถึงในบทความที่ฉันเชื่อมโยงไว้ หากคุณลองคิดดู ปฏิทินนั้นเต็มไปด้วยความแตกต่าง ตั้งแต่การจัดการเขตเวลาและรูปแบบวันที่ ไปจนถึงการแปลเป็นภาษาท้องถิ่น และแม้แต่การตรวจสอบให้แน่ใจว่าวันที่เปลี่ยนจากเดือนหนึ่งไปยังอีกเดือนหนึ่ง ปรากฏขึ้นและอะไรก็ตาม

นักพัฒนาหลายคนกลัวว่า Date() วัตถุ และติดกับห้องสมุดเก่าเช่น moment.js. แต่ในขณะที่มี "gotchas" มากมายเมื่อพูดถึงวันที่และการจัดรูปแบบ JavaScript ก็มี API เจ๋งๆ มากมายและสิ่งต่างๆ ที่จะช่วยได้!

ตารางปฏิทินเดือนมกราคม 2023

ฉันไม่ต้องการสร้างวงล้อใหม่ที่นี่ แต่ฉันจะแสดงให้คุณเห็นว่าเราสามารถรับปฏิทินที่ดีด้วยวานิลลาจาวาสคริปต์ได้อย่างไร เราจะตรวจสอบ การเข้าถึงโดยใช้มาร์กอัปสื่อความหมายและเป็นมิตรกับโปรแกรมอ่านหน้าจอ <time> -tags — เช่นเดียวกับ สากล และ การจัดรูปแบบ, ใช้ Intl.Locale, Intl.DateTimeFormat และ Intl.NumberFormat-API

กล่าวอีกนัยหนึ่ง เรากำลังสร้างปฏิทิน... โดยปราศจากการพึ่งพาเพิ่มเติมซึ่งโดยปกติแล้วคุณอาจเห็นใช้ในบทช่วยสอนเช่นนี้ และด้วยความแตกต่างบางประการที่คุณอาจไม่เห็น และในขั้นตอนนี้ ฉันหวังว่าคุณจะได้รับความชื่นชมใหม่สำหรับสิ่งใหม่ๆ ที่ JavaScript สามารถทำได้ พร้อมๆ กับได้แนวคิดเกี่ยวกับสิ่งต่างๆ ที่อยู่ในใจของฉันเมื่อฉันรวบรวมสิ่งนี้เข้าด้วยกัน

ก่อนอื่นการตั้งชื่อ

เราควรเรียกองค์ประกอบปฏิทินว่าอะไร ในภาษาพื้นเมืองของฉัน จะเรียกว่า "องค์ประกอบปฏิทิน" ดังนั้นขอใช้สิ่งนั้นและย่อให้สั้นลงเป็น "คาล-เอล" หรือที่เรียกว่า ชื่อของซูเปอร์แมนบนดาวคริปทอน.

มาสร้างฟังก์ชั่นเพื่อดำเนินการต่อไป:

function kalEl(settings = {}) { ... }

วิธีนี้จะแสดงผล เดือนเดียว. ภายหลังเราจะเรียกวิธีนี้จาก [...Array(12).keys()] เพื่อแสดงผลตลอดทั้งปี

ข้อมูลเบื้องต้นและความเป็นสากล

สิ่งหนึ่งที่พบได้ทั่วไปในปฏิทินออนไลน์ทั่วไปคือการเน้นวันที่ปัจจุบัน ดังนั้นมาสร้างข้อมูลอ้างอิงสำหรับสิ่งนั้น:

const today = new Date();

ต่อไป เราจะสร้าง "วัตถุการกำหนดค่า" ที่เราจะรวมเข้ากับตัวเลือก settings วัตถุของวิธีการหลัก:

const config = Object.assign( { locale: (document.documentElement.getAttribute('lang') || 'en-US'), today: { day: today.getDate(), month: today.getMonth(), year: today.getFullYear() } }, settings
);

เราตรวจสอบว่าองค์ประกอบรูท (<html>) ประกอบด้วย lang-attribute กับ ในประเทศ ข้อมูล; มิฉะนั้นเราจะกลับไปใช้ en-US. นี่เป็นก้าวแรกสู่ การทำปฏิทินให้เป็นสากล.

เรายังจำเป็นต้องกำหนดเดือนที่จะแสดงเมื่อแสดงปฏิทิน นั่นเป็นเหตุผลที่เราขยาย config ค้านกับหลัก date. ด้วยวิธีนี้ หากไม่ได้ระบุวันที่ไว้ใน settings วัตถุ เราจะใช้ today อ้างอิงแทน:

const date = config.date ? new Date(config.date) : today;

เราต้องการข้อมูลเพิ่มเติมเล็กน้อยเพื่อจัดรูปแบบปฏิทินตามสถานที่ ตัวอย่างเช่น เราอาจไม่ทราบว่าวันแรกของสัปดาห์คือวันอาทิตย์หรือวันจันทร์ ขึ้นอยู่กับสถานที่ ถ้าเรามีข้อมูล เยี่ยมมาก! แต่ถ้าไม่ เราจะอัปเดตโดยใช้ Intl.Locale API. API มี weekInfo วัตถุ ที่ส่งคืน a firstDay พร็อพเพอร์ตี้ที่ให้สิ่งที่เรากำลังมองหาโดยไม่ยุ่งยาก เรายังสามารถกำหนดวันในสัปดาห์ได้อีกด้วย weekend:

if (!config.info) config.info = new Intl.Locale(config.locale).weekInfo || { firstDay: 7, weekend: [6, 7] };

อีกครั้ง เราสร้างทางเลือกสำรอง “วันแรก” ของสัปดาห์สำหรับ en-US เป็นวันอาทิตย์ ดังนั้นค่าเริ่มต้นจะเป็นค่า 7. สิ่งนี้ทำให้เกิดความสับสนเล็กน้อยเนื่องจาก getDay วิธี ใน JavaScript ส่งคืนวันที่เป็น [0-6]ที่นี่มี 0 เป็นวันอาทิตย์… อย่าถามฉันว่าทำไม วันหยุดสุดสัปดาห์คือวันเสาร์และวันอาทิตย์ [6, 7].

ก่อนที่เราจะมี Intl.Locale API และของมัน weekInfo วิธีการสร้างปฏิทินสากลโดยไม่มี **วัตถุและอาร์เรย์จำนวนมากที่มีข้อมูลเกี่ยวกับแต่ละสถานที่หรือภูมิภาคนั้นค่อนข้างยาก สมัยนี้มันง่ายแสนง่าย ถ้าเราผ่านเข้ามา en-GBวิธีการส่งคืน:

// en-GB
{ firstDay: 1, weekend: [6, 7], minimalDays: 4
}

ในประเทศเช่นบรูไน (ms-BN) วันหยุดสุดสัปดาห์คือวันศุกร์และวันอาทิตย์:

// ms-BN
{ firstDay: 7, weekend: [5, 7], minimalDays: 1
}

คุณอาจสงสัยว่าอะไร minimalDays คุณสมบัติคือ. เป็นเรื่องที่ จำนวนวันที่น้อยที่สุดในสัปดาห์แรกของเดือนจึงจะนับเป็นหนึ่งสัปดาห์เต็ม. ในบางภูมิภาคอาจใช้เวลาเพียงวันเดียว สำหรับคนอื่นอาจเป็นเจ็ดวันเต็ม

ต่อไปเราจะสร้าง render วิธีการภายในของเรา kalEl-วิธี:

const render = (date, locale) => { ... }

เรายังต้องการข้อมูลเพิ่มเติมเพื่อใช้งานก่อนที่เราจะแสดงผลอะไร:

const month = date.getMonth();
const year = date.getFullYear();
const numOfDays = new Date(year, month + 1, 0).getDate();
const renderToday = (year === config.today.year) && (month === config.today.month);

สุดท้ายคือก Boolean ที่ตรวจสอบว่า today อยู่ในเดือนที่เรากำลังจะแสดงผล

มาร์กอัปความหมาย

เราจะลงลึกในเรื่องการเรนเดอร์ในอีกสักครู่ แต่ก่อนอื่น ฉันต้องการตรวจสอบให้แน่ใจว่ารายละเอียดที่เราตั้งค่ามีแท็ก HTML เชิงความหมายที่เกี่ยวข้อง การตั้งค่าทันทีที่แกะกล่องทำให้เราได้รับประโยชน์ในการเข้าถึงตั้งแต่เริ่มต้น

กระดาษห่อปฏิทิน

อันดับแรก เรามี wrapper ที่ไม่ใช่ความหมาย: <kal-el>. ไม่เป็นไรเพราะไม่มีความหมาย <calendar> แท็กหรืออะไรทำนองนั้น หากเราไม่ได้สร้างองค์ประกอบที่กำหนดเอง <article> อาจเป็นองค์ประกอบที่เหมาะสมที่สุดเนื่องจากปฏิทินสามารถอยู่ในหน้าของตัวเองได้

ชื่อเดือน

พื้นที่ <time> องค์ประกอบจะเป็นเรื่องใหญ่สำหรับเราเพราะมันช่วยแปลวันที่เป็นรูปแบบที่โปรแกรมอ่านหน้าจอและเครื่องมือค้นหาสามารถแยกวิเคราะห์ได้อย่างถูกต้องและสม่ำเสมอมากขึ้น ตัวอย่างเช่น นี่คือวิธีที่เราสื่อถึง "มกราคม 2023" ในมาร์กอัปของเรา:

<time datetime="2023-01">January <i>2023</i></time>

ชื่อวัน

แถวเหนือวันที่ในปฏิทินที่มีชื่อวันในสัปดาห์อาจดูยุ่งยาก เป็นการดีหากเราสามารถเขียนชื่อเต็มของแต่ละวันได้ เช่น วันอาทิตย์ วันจันทร์ วันอังคาร ฯลฯ แต่อาจใช้พื้นที่มาก ดังนั้นขอย่อชื่อสำหรับตอนนี้ใน <ol> แต่ละวันคือก <li>:

<ol> <li><abbr title="Sunday">Sun</abbr></li> <li><abbr title="Monday">Mon</abbr></li> <!-- etc. -->
</ol>

เราอาจยุ่งยากกับ CSS เพื่อให้ได้ประโยชน์สูงสุดจากทั้งสองโลก ตัวอย่างเช่น หากเราแก้ไขมาร์กอัปเล็กน้อยดังนี้:

<ol> <li> <abbr title="S">Sunday</abbr> </li>
</ol>

…เราได้รับชื่อเต็มตามค่าเริ่มต้น จากนั้นเราสามารถ "ซ่อน" ชื่อเต็มเมื่อพื้นที่หมดและแสดง title คุณลักษณะแทน:

@media all and (max-width: 800px) { li abbr::after { content: attr(title); }
}

แต่เราจะไม่ไปทางนั้นเพราะ Intl.DateTimeFormat API สามารถช่วยได้ที่นี่เช่นกัน เราจะพูดถึงในส่วนถัดไปเมื่อเราพูดถึงการเรนเดอร์

หมายเลขวัน

แต่ละวันที่ในตารางปฏิทินจะได้รับตัวเลข แต่ละหมายเลขเป็นรายการ (<li>) ในรายการสั่งซื้อ (<ol>) และอินไลน์ <time> แท็กล้อมรอบจำนวนจริง

<li> <time datetime="2023-01-01">1</time>
</li>

และในขณะที่ฉันยังไม่ได้วางแผนที่จะจัดรูปแบบใด ๆ ฉันรู้ว่าฉันต้องการวิธีจัดรูปแบบตัวเลขวันที่ เป็นไปได้ตามที่เป็นอยู่ แต่ฉันยังต้องการให้สามารถจัดรูปแบบหมายเลขวันธรรมดาให้แตกต่างจากหมายเลขวันหยุดสุดสัปดาห์ได้หากต้องการ ดังนั้นฉันจะรวม data-* แอตทริบิวต์ โดยเฉพาะสำหรับสิ่งนั้น: data-weekend และ data-today.

เลขประจำสัปดาห์

ในหนึ่งปีมี 52 สัปดาห์ บางครั้งอาจมี 53 สัปดาห์ แม้ว่าจะไม่ใช่เรื่องธรรมดา แต่การแสดงจำนวนสัปดาห์ในปฏิทินสำหรับบริบทเพิ่มเติมก็เป็นเรื่องดี ฉันชอบที่จะมีมันตอนนี้ แม้ว่าฉันจะไม่เลิกใช้มัน แต่เราจะใช้มันทั้งหมดในการกวดวิชานี้

เราจะใช้ a data-weeknumber แอตทริบิวต์เป็น hook สไตล์และรวมไว้ในมาร์กอัปสำหรับแต่ละวันที่ซึ่งเป็นวันแรกของสัปดาห์

<li data-day="7" data-weeknumber="1" data-weekend=""> <time datetime="2023-01-08">8</time>
</li>

การแสดงผล

รับปฏิทินบนหน้า! เรารู้อยู่แล้วว่า <kal-el> เป็นชื่อขององค์ประกอบที่กำหนดเองของเรา สิ่งแรกที่เราต้องกำหนดค่าคือการตั้งค่า firstDay อยู่บนนั้น ดังนั้นปฏิทินจึงรู้ว่าวันอาทิตย์หรือวันอื่นๆ เป็นวันแรกของสัปดาห์หรือไม่

<kal-el data-firstday="${ config.info.firstDay }">

เราจะใช้ แม่แบบตัวอักษร เพื่อแสดงมาร์กอัป ในการจัดรูปแบบวันที่สำหรับผู้ชมต่างประเทศ เราจะใช้ Intl.DateTimeFormat API อีกครั้งโดยใช้ไฟล์ locale เราระบุไว้ก่อนหน้านี้

เดือนและปี

เมื่อเราเรียก monthเราสามารถตั้งค่าได้ว่าต้องการใช้ long ชื่อ (เช่น กุมภาพันธ์) หรือ the short ชื่อ (เช่น ก.พ.). มาใช้กันเถอะ long ชื่อเนื่องจากเป็นชื่อเหนือปฏิทิน:

<time datetime="${year}-${(pad(month))}"> ${new Intl.DateTimeFormat( locale, { month:'long'}).format(date)} <i>${year}</i>
</time>

ชื่อวันธรรมดา

สำหรับวันธรรมดาที่แสดงเหนือตารางวันที่ เราต้องการทั้งสองอย่าง long (เช่น “วันอาทิตย์”) และ short (ตัวย่อเช่น "ดวงอาทิตย์") ชื่อ ด้วยวิธีนี้ เราสามารถใช้ชื่อ "ย่อ" เมื่อปฏิทินมีพื้นที่สั้น:

Intl.DateTimeFormat([locale], { weekday: 'long' })
Intl.DateTimeFormat([locale], { weekday: 'short' })

เรามาสร้างวิธีการช่วยเหลือเล็กๆ น้อยๆ ที่ทำให้เรียกแต่ละคนได้ง่ายขึ้น:

const weekdays = (firstDay, locale) => { const date = new Date(0); const arr = [...Array(7).keys()].map(i => { date.setDate(5 + i) return { long: new Intl.DateTimeFormat([locale], { weekday: 'long'}).format(date), short: new Intl.DateTimeFormat([locale], { weekday: 'short'}).format(date) } }) for (let i = 0; i < 8 - firstDay; i++) arr.splice(0, 0, arr.pop()); return arr;
}

นี่คือวิธีที่เราเรียกใช้ในเทมเพลต:

<ol> ${weekdays(config.info.firstDay,locale).map(name => ` <li> <abbr title="${name.long}">${name.short}</abbr> </li>`).join('') }
</ol>

หมายเลขวัน

และในที่สุดวันเวลาก็ถูกห่อหุ้มด้วย <ol> ธาตุ:

${[...Array(numOfDays).keys()].map(i => { const cur = new Date(year, month, i + 1); let day = cur.getDay(); if (day === 0) day = 7; const today = renderToday && (config.today.day === i + 1) ? ' data-today':''; return ` <li data-day="${day}"${today}${i === 0 || day === config.info.firstDay ? ` data-weeknumber="${new Intl.NumberFormat(locale).format(getWeek(cur))}"`:''}${config.info.weekend.includes(day) ? ` data-weekend`:''}> <time datetime="${year}-${(pad(month))}-${pad(i)}" tabindex="0"> ${new Intl.NumberFormat(locale).format(i + 1)} </time> </li>`
}).join('')}

มาทำลายมันกันเถอะ:

  1. เราสร้างอาร์เรย์ "จำลอง" ตามตัวแปร "จำนวนวัน" ซึ่งเราจะใช้ในการวนซ้ำ
  2. เราสร้างไฟล์ day ตัวแปรสำหรับวันปัจจุบันในการวนซ้ำ
  3. เราแก้ไขความแตกต่างระหว่าง Intl.Locale API และ getDay().
  4. ถ้า day เท่ากับ todayเราเพิ่ม data-* คุณลักษณะ
  5. ในที่สุดเราก็ส่งคืน <li> องค์ประกอบเป็นสตริงที่มีข้อมูลที่ผสาน
  6. tabindex="0" ทำให้องค์ประกอบสามารถโฟกัสได้ เมื่อใช้การนำทางด้วยแป้นพิมพ์ หลังจากค่า tabindex ที่เป็นบวก (หมายเหตุ: คุณควร ไม่เคย เพิ่ม บวก ค่า tabindex)

ไปยัง “แพด” ตัวเลข ใน datetime แอตทริบิวต์ เราใช้วิธีตัวช่วยเล็กน้อย:

const pad = (val) => (val + 1).toString().padStart(2, '0');

หมายเลขสัปดาห์

อีกครั้ง "หมายเลขสัปดาห์" คือตำแหน่งที่สัปดาห์อยู่ในปฏิทิน 52 สัปดาห์ เราใช้วิธีการช่วยเหลือเล็กน้อยสำหรับสิ่งนั้นเช่นกัน:

function getWeek(cur) { const date = new Date(cur.getTime()); date.setHours(0, 0, 0, 0); date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7); const week = new Date(date.getFullYear(), 0, 4); return 1 + Math.round(((date.getTime() - week.getTime()) / 86400000 - 3 + (week.getDay() + 6) % 7) / 7);
}

ฉันไม่ได้เขียนสิ่งนี้ getWeek-วิธี. มันเป็นรุ่นที่สะอาดขึ้นของ สคริปต์นี้.

และนั่นแหล่ะ! ขอขอบคุณที่ Intl.Locale, Intl.DateTimeFormat และ Intl.NumberFormat API ตอนนี้เราสามารถเปลี่ยน lang-แอตทริบิวต์ของ <html> องค์ประกอบเพื่อเปลี่ยนบริบทของปฏิทินตามภูมิภาคปัจจุบัน:

ตารางปฏิทินเดือนมกราคม 2023
de-DE
ตารางปฏิทินเดือนมกราคม 2023
fa-IR
ตารางปฏิทินเดือนมกราคม 2023
zh-Hans-CN-u-nu-hanidec

จัดรูปแบบปฏิทิน

คุณอาจจำได้ว่าวันทั้งหมดเป็นเพียงวันเดียว <ol> พร้อมรายการ. เพื่อจัดรูปแบบเหล่านี้ให้เป็นปฏิทินที่อ่านได้ เราดำดิ่งสู่โลกมหัศจรรย์ของ CSS Grid ในความเป็นจริง เราสามารถปรับเปลี่ยนกริดเดิมได้จาก เทมเพลตปฏิทินเริ่มต้นที่นี่บน CSS-Tricksแต่อัปเดตเล็กน้อยด้วย :is() หลอกเชิงสัมพันธ์เพื่อเพิ่มประสิทธิภาพโค้ด

ขอให้สังเกตว่าฉันกำลังกำหนดตัวแปร CSS ที่กำหนดค่าได้ระหว่างทาง (และขึ้นต้นด้วย ---kalel- เพื่อหลีกเลี่ยงความขัดแย้ง)

kal-el :is(ol, ul) { display: grid; font-size: var(--kalel-fz, small); grid-row-gap: var(--kalel-row-gap, .33em); grid-template-columns: var(--kalel-gtc, repeat(7, 1fr)); list-style: none; margin: unset; padding: unset; position: relative;
}
ตารางปฏิทินเจ็ดคอลัมน์พร้อมเส้นตารางแสดง

มาวาดเส้นขอบรอบๆ หมายเลขวันที่เพื่อช่วยแยกตัวเลขเหล่านี้ให้มองเห็นได้:

kal-el :is(ol, ul) li { border-color: var(--kalel-li-bdc, hsl(0, 0%, 80%)); border-style: var(--kalel-li-bds, solid); border-width: var(--kalel-li-bdw, 0 0 1px 0); grid-column: var(--kalel-li-gc, initial); text-align: var(--kalel-li-tal, end); }

ตารางเจ็ดคอลัมน์ทำงานได้ดีเมื่อถึงวันแรกของเดือน ด้วย วันแรกของสัปดาห์สำหรับสถานที่ที่เลือก) แต่นั่นเป็นข้อยกเว้นมากกว่ากฎ ส่วนใหญ่แล้ว เราจะต้องเปลี่ยนวันแรกของเดือนเป็นวันทำงานอื่น

แสดงวันแรกของเดือนตรงกับวันพฤหัสบดี

จดจำสิ่งพิเศษทั้งหมด data-* คุณลักษณะที่เรากำหนดไว้เมื่อเขียนมาร์กอัปของเรา? เราสามารถเชื่อมโยงสิ่งเหล่านั้นเพื่ออัปเดตคอลัมน์กริดใด (--kalel-li-gc) เลขวันที่แรกของเดือนอยู่บน:

[data-firstday="1"] [data-day="3"]:first-child { --kalel-li-gc: 1 / 4;
}

ในกรณีนี้ เรากำลังขยายจากคอลัมน์กริดแรกไปยังคอลัมน์กริดที่สี่ ซึ่งจะ "ดัน" รายการถัดไปโดยอัตโนมัติ (วันที่ 2) ไปยังคอลัมน์กริดที่ห้า และอื่นๆ

มาเพิ่มรูปแบบเล็กๆ น้อยๆ ให้กับวันที่ "ปัจจุบัน" เพื่อให้โดดเด่น นี่เป็นเพียงสไตล์ของฉัน คุณสามารถทำสิ่งที่คุณต้องการได้ที่นี่

[data-today] { --kalel-day-bdrs: 50%; --kalel-day-bg: hsl(0, 86%, 40%); --kalel-day-hover-bgc: hsl(0, 86%, 70%); --kalel-day-c: #fff;
}

ฉันชอบแนวคิดในการจัดรูปแบบวันที่สำหรับวันหยุดสุดสัปดาห์ให้แตกต่างจากวันธรรมดา ฉันจะใช้สีแดงเพื่อจัดสไตล์เหล่านั้น โปรดทราบว่าเราสามารถเข้าถึง :not() pseudo-class เพื่อเลือกในขณะที่ปล่อยวันที่ปัจจุบันเพียงอย่างเดียว:

[data-weekend]:not([data-today]) { --kalel-day-c: var(--kalel-weekend-c, hsl(0, 86%, 46%));
}

อ้อ และอย่าลืมหมายเลขสัปดาห์ที่อยู่ก่อนหมายเลขวันแรกของแต่ละสัปดาห์ เราใช้ data-weeknumber แอตทริบิวต์ในมาร์กอัปสำหรับสิ่งนั้น แต่ตัวเลขจะไม่แสดงจริงเว้นแต่เราจะเปิดเผยด้วย CSS ซึ่งเราสามารถทำได้ใน ::before องค์ประกอบหลอก:

[data-weeknumber]::before { display: var(--kalel-weeknumber-d, inline-block); content: attr(data-weeknumber); position: absolute; inset-inline-start: 0; /* additional styles */
}

เราเสร็จสิ้นทางเทคนิค ณ จุดนี้! เราสามารถแสดงตารางปฏิทินที่แสดงวันที่สำหรับเดือนปัจจุบัน พร้อมข้อควรพิจารณาในการแปลข้อมูลตามโลแคล และตรวจสอบให้แน่ใจว่าปฏิทินใช้ความหมายที่เหมาะสม และทั้งหมดที่เราใช้คือวานิลลา JavaScript และ CSS!

แต่เอาเถอะ อีกหนึ่งขั้นตอน...

แสดงผลตลอดทั้งปี

บางทีคุณอาจต้องแสดงวันที่ทั้งปี! ดังนั้น แทนที่จะแสดงเดือนปัจจุบัน คุณอาจต้องการแสดงตารางเดือนทั้งหมดสำหรับปีปัจจุบัน

สิ่งที่ดีเกี่ยวกับวิธีที่เราใช้คือ เราสามารถเรียก render วิธีการหลาย ๆ ครั้งตามที่เราต้องการและเพียงแค่เปลี่ยนจำนวนเต็มที่ระบุเดือนในแต่ละอินสแตนซ์ เรียกมันว่า 12 ครั้งตามปีปัจจุบัน

ง่ายเหมือนการโทร renderวิธีการ 12 ครั้งและเพียงแค่เปลี่ยนจำนวนเต็มสำหรับ month - i:

[...Array(12).keys()].map(i => render( new Date(date.getFullYear(), i, date.getDate()), config.locale, date.getMonth() )
).join('')

อาจเป็นความคิดที่ดีที่จะสร้าง parent wrapper ใหม่สำหรับปีที่แสดง ตารางปฏิทินแต่ละตารางคือ <kal-el> องค์ประกอบ. มาเรียกพาเรนต์แรปเปอร์ใหม่กัน <jor-el>ที่นี่มี Jor-El เป็นชื่อของพ่อของ Kal-El.

<jor-el id="app" data-year="true"> <kal-el data-firstday="7"> <!-- etc. --> </kal-el> <!-- other months -->
</jor-el>

เราสามารถใช้ <jor-el> เพื่อสร้างกริดให้กับกริดของเรา เมตาดังนั้น!

jor-el { background: var(--jorel-bg, none); display: var(--jorel-d, grid); gap: var(--jorel-gap, 2.5rem); grid-template-columns: var(--jorel-gtc, repeat(auto-fill, minmax(320px, 1fr))); padding: var(--jorel-p, 0);
}

สาธิตขั้นสุดท้าย

โบนัส: ปฏิทิน Confetti

ฉันอ่านหนังสือที่ยอดเยี่ยมชื่อ สร้างและทำลายตาราง วันก่อนและสะดุดกับ "โปสเตอร์ปีใหม่" ที่สวยงามนี้:

ที่มา: การสร้างและทำลายตาราง (พิมพ์ครั้งที่ 2) โดย ทิโมธี ซามารา

ฉันคิดว่าเราสามารถทำสิ่งที่คล้ายกันได้โดยไม่ต้องเปลี่ยนแปลงอะไรใน HTML หรือ JavaScript ฉันใช้เสรีภาพในการรวมชื่อเต็มของเดือนและตัวเลขแทนชื่อวัน เพื่อให้อ่านง่ายขึ้น สนุก!

ประทับเวลา:

เพิ่มเติมจาก เคล็ดลับ CSS