रिस्पॉन्सिव और ऐक्सेस किए जा सकने वाले स्विच कॉम्पोनेंट बनाने के तरीके के बारे में खास जानकारी.
इस पोस्ट में, हम आपको बताना चाहते हैं कि स्विच कॉम्पोनेंट को कैसे तैयार किया जाता है. डेमो देखें.
अगर आपको वीडियो देखना है, तो इस पोस्ट का YouTube वर्शन यहां देखें:
खास जानकारी
चेकबॉक्स की तरह ही स्विच भी काम करता है लेकिन यह साफ़ तौर पर बूलियन ऑन और ऑफ़ स्टेट को दिखाता है.
यह डेमो, अपने ज़्यादातर वीडियो के लिए <input type="checkbox" role="switch">
का इस्तेमाल करता है
इसके लिए, सीएसएस या JavaScript की ज़रूरत नहीं होती
वे पूरी तरह से काम कर रहे हों और आसानी से ऐक्सेस कर सकें. सीएसएस को लोड करने से, दाईं से बाईं ओर के लिए सहायता मिलती है
भाषाएं, वर्टिकलिटी, ऐनिमेशन वगैरह. JavaScript लोड होने से साइट पर
खींचने और छोड़ने लायक हों.
कस्टम प्रॉपर्टी
नीचे दिए गए वैरिएबल, स्विच के अलग-अलग हिस्सों और उनके
के विकल्प. टॉप-लेवल क्लास के तौर पर, .gui-switch
में इस्तेमाल की गई कस्टम प्रॉपर्टी शामिल हैं
कॉम्पोनेंट चिल्ड्रेन और एक ही जगह से सब मैनेज करने के लिए एंट्री पॉइंट
पसंद के मुताबिक बनाने की सुविधा मिलती है.
ट्रैक
लंबाई (--track-size
), पैडिंग, और दो रंग:
.gui-switch {
--track-size: calc(var(--thumb-size) * 2);
--track-padding: 2px;
--track-inactive: hsl(80 0% 80%);
--track-active: hsl(80 60% 45%);
--track-color-inactive: var(--track-inactive);
--track-color-active: var(--track-active);
@media (prefers-color-scheme: dark) {
--track-inactive: hsl(80 0% 35%);
--track-active: hsl(80 60% 60%);
}
}
थंब
साइज़, बैकग्राउंड का रंग, और इंटरैक्शन को हाइलाइट करने वाले रंग:
.gui-switch {
--thumb-size: 2rem;
--thumb: hsl(0 0% 100%);
--thumb-highlight: hsl(0 0% 0% / 25%);
--thumb-color: var(--thumb);
--thumb-color-highlight: var(--thumb-highlight);
@media (prefers-color-scheme: dark) {
--thumb: hsl(0 0% 5%);
--thumb-highlight: hsl(0 0% 100% / 25%);
}
}
कम मोशन
साफ़ उपनाम जोड़ने और दोहराव को कम करने के लिए, कम मोशन प्राथमिकता वाला उपयोगकर्ता मीडिया क्वेरी को पोस्टसीएसएस की मदद से कस्टम प्रॉपर्टी में रखा जा सकता है इस ड्राफ़्ट पर आधारित प्लगिन मीडिया क्वेरी में खास जानकारी 5:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
मार्कअप
मैंने अपने <input type="checkbox" role="switch">
एलिमेंट को
<label>
, चेकबॉक्स और लेबल को असोसिएट होने से रोकने के लिए, अपने संबंधों को बंडल कर रहा है
साफ़ तौर पर जानकारी देता है. साथ ही, इससे उपयोगकर्ता को लेबल से इंटरैक्ट करने की अनुमति मिलती है,
इनपुट को टॉगल करें.
<label for="switch" class="gui-switch">
Label text
<input type="checkbox" role="switch" id="switch">
</label>
<input type="checkbox">
में, पहले से ही
एपीआई
और राज्य दिखेगा. कॉन्टेंट बनाने
ब्राउज़र, आपकी
checked
प्रॉपर्टी और इनपुट
इवेंट
जैसे कि oninput
और onchanged
.
लेआउट
फ़्लेक्सबॉक्स, ग्रिड और कस्टम प्रॉपर्टी ज़रूरी हैं, इस कॉम्पोनेंट की स्टाइल को बनाए रखने के लिए किया जा सकता है. वे एक ही जगह पर मानों को रखते हैं, और नामों को और छोटे कस्टम प्रॉपर्टी को चालू कर सकते हैं. घटक को आसानी से कस्टमाइज़ करने के लिए API.
.gui-switch
स्विच के लिए टॉप-लेवल लेआउट फ़्लेक्सबॉक्स है. क्लास .gui-switch
में यह शामिल है
वे निजी और सार्वजनिक कस्टम प्रॉपर्टी जिनका इस्तेमाल करके बच्चा अपनी प्रॉपर्टी का हिसाब लगाता है
लेआउट.
.gui-switch {
display: flex;
align-items: center;
gap: 2ch;
justify-content: space-between;
}
फ़्लेक्सबॉक्स लेआउट को बढ़ाना और उसमें बदलाव करना, किसी फ़्लेक्सबॉक्स लेआउट को बदलने जैसा है.
उदाहरण के लिए, लेबल को किसी स्विच के ऊपर या नीचे रखने के लिए,
flex-direction
:
<label for="light-switch" class="gui-switch" style="flex-direction: column">
Default
<input type="checkbox" role="switch" id="light-switch">
</label>
ट्रैक
चेकबॉक्स इनपुट को स्विच ट्रैक के तौर पर सेट किया गया है. इसके लिए, इसे सामान्य बटन से हटा दिया गया है
appearance: checkbox
और इसके बजाय इसका खुद का साइज़ सप्लाई कर रहा है:
.gui-switch > input {
appearance: none;
inline-size: var(--track-size);
block-size: var(--thumb-size);
padding: var(--track-padding);
flex-shrink: 0;
display: grid;
align-items: center;
grid: [track] 1fr / [track] 1fr;
}
ट्रैक, अंगूठे के लिए एक-एक करके सिंगल सेल ग्रिड ट्रैक एरिया भी बनाता है दावा.
थंब
यह शैली appearance: none
से दिए गए विज़ुअल सही के निशान को भी हटा देती है
ब्राउज़र खोलें. यह कॉम्पोनेंट किसी
pseudo-element और :checked
इसके इनपुट पर pseudo-class
इस विज़ुअल इंडिकेटर को बदलें.
अंगूठा एक स्यूडो-एलिमेंट चाइल्ड है, जो input[type="checkbox"]
से जुड़ा हुआ है और
ग्रिड एरिया पर दावा करके, ट्रैक के नीचे की जगह पर स्टैक
track
:
.gui-switch > input::before {
content: "";
grid-area: track;
inline-size: var(--thumb-size);
block-size: var(--thumb-size);
}
स्टाइल
कस्टम प्रॉपर्टी से, कई तरह के काम करने वाले स्विच कॉम्पोनेंट चालू होते हैं. ये कॉम्पोनेंट, रंग के हिसाब से अपने-आप बदल जाते हैं स्कीम, दाएं से बाएं लिखी जाने वाली भाषाएं, और मोशन की प्राथमिकताएं.
टच इंटरैक्शन स्टाइल
मोबाइल पर, ब्राउज़र लेबल और टेक्स्ट में, टैप हाइलाइट और टेक्स्ट चुनने की सुविधाएं जोड़ते हैं
इनपुट. इससे स्टाइल और विज़ुअल इंटरैक्शन के बारे में मिले सुझावों पर बुरा असर पड़ा
इस स्विच की ज़रूरत है. सीएसएस की कुछ लाइनों की मदद से, उन इफ़ेक्ट को हटाया जा सकता है और
मेरी अपनी cursor: pointer
शैली:
.gui-switch {
cursor: pointer;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
इन स्टाइल को हमेशा हटाना सही नहीं होता, क्योंकि ऐसा करने से विज़ुअल के अहम एलिमेंट का इस्तेमाल किया जा सकता है. इंटरैक्शन फ़ीडबैक. अगर आप इन्हें हटाते हैं, तो अपनी पसंद के मुताबिक विकल्प देना न भूलें.
ट्रैक
इस एलिमेंट की स्टाइल, ज़्यादातर इसके आकार और रंग पर आधारित होती है. इससे एलिमेंट को ऐक्सेस किया जा सकता है
इसके ज़रिए, पैरंट .gui-switch
से
कैस्केड.
.gui-switch > input {
appearance: none;
border: none;
outline-offset: 5px;
box-sizing: content-box;
padding: var(--track-padding);
background: var(--track-color-inactive);
inline-size: var(--track-size);
block-size: var(--thumb-size);
border-radius: var(--track-size);
}
स्विच ट्रैक को मनमुताबिक बनाने के लिए, चार तरह के विकल्प उपलब्ध हैं
कस्टम प्रॉपर्टी. border: none
जोड़ा गया है, क्योंकि appearance: none
यह नहीं करता
सभी ब्राउज़र पर चेकबॉक्स से बॉर्डर निकाल दें.
थंब
अंगूठे का एलिमेंट पहले से ही दाईं ओर मौजूद है track
, लेकिन इसके लिए सर्कल स्टाइल की ज़रूरत है:
.gui-switch > input::before {
background: var(--thumb-color);
border-radius: 50%;
}
बातचीत
कस्टम प्रॉपर्टी का इस्तेमाल ऐसे इंटरैक्शन के लिए करना जिनमें कर्सर घुमाना शामिल है हाइलाइट और अंगूठे की स्थिति में बदलाव. उपयोगकर्ता की प्राथमिकता यह भी है को बदलने से पहले चेक किया हाइलाइट शैलियां हैं या उन्हें मोशन या होवर किया जा सकता है.
.gui-switch > input::before {
box-shadow: 0 0 0 var(--highlight-size) var(--thumb-color-highlight);
@media (--motionOK) { & {
transition:
transform var(--thumb-transition-duration) ease,
box-shadow .25s ease;
}}
}
पसंद की जगह
कस्टम प्रॉपर्टी में, अंगूठे को सही जगह पर रखने के लिए एक ही सोर्स मैकेनिज़्म होता है
ट्रैक करें. हमारे लिए यहां ट्रैक और थंब साइज़ दिए गए हैं, जिनका इस्तेमाल हम
अंगूठे को ट्रैक के अंदर और बीच में ठीक तरह से ऑफ़सेट रखने के लिए कैलकुलेशन:
0%
और 100%
.
input
एलिमेंट के पास पोज़िशन वैरिएबल --thumb-position
और अंगूठे का मालिकाना हक है
pseudo एलिमेंट इसका इस्तेमाल translateX
पोज़िशन के तौर पर करता है:
.gui-switch > input {
--thumb-position: 0%;
}
.gui-switch > input::before {
transform: translateX(var(--thumb-position));
}
अब हम --thumb-position
को सीएसएस और pseudo-classes से बदल सकते हैं
यह सुविधा, चेकबॉक्स एलिमेंट पर दी गई है. हमने इस एलिमेंट पर, शर्तों के साथ transition: transform
var(--thumb-transition-duration) ease
को पहले सेट किया था. इसलिए, ये बदलाव हुए हैं
बदलाव किए जाने पर ऐनिमेट हो सकता है:
/* positioned at the end of the track: track length - 100% (thumb width) */
.gui-switch > input:checked {
--thumb-position: calc(var(--track-size) - 100%);
}
/* positioned in the center of the track: half the track - half the thumb */
.gui-switch > input:indeterminate {
--thumb-position: calc(
(var(--track-size) / 2) - (var(--thumb-size) / 2)
);
}
मुझे लगा कि अलग-अलग ऑर्केस्ट्रा का यह कलेक्शन काफ़ी कारगर साबित हुआ. अंगूठा तत्व है
सिर्फ़ एक शैली, translateX
स्थिति से संबंधित है. इनपुट से सभी को मैनेज किया जा सकता है
और कैलकुलेशन की ज़रूरत होती है.
वर्टिकल
सपोर्ट करने की सुविधा, कार्रवाई बदलने वाली क्लास -vertical
की मदद से दी गई. इससे, कार्रवाई के साथ एक रोटेशन जुड़ जाता है
सीएसएस, input
एलिमेंट में बदल जाता है.
हालांकि, 3D घुमाए गए एलिमेंट से कॉम्पोनेंट की कुल ऊंचाई में कोई बदलाव नहीं होता,
जो ब्लॉक लेआउट को बंद कर सकते हैं. --track-size
और
--track-padding
वैरिएबल. इसके लिए आवश्यक कम से कम स्थान की गणना करें
लेआउट में फ़्लो करने के लिए वर्टिकल बटन:
.gui-switch.-vertical {
min-block-size: calc(var(--track-size) + calc(var(--track-padding) * 2));
& > input {
transform: rotate(-90deg);
}
}
(RTL) दाएं से बाएं
एक सीएसएस दोस्त, इलाड शेक्टर और मैंने प्रोटोटाइप किया साथ ही, सीएसएस ट्रांसफ़ॉर्म की मदद से, साइड मेन्यू को स्लाइड करें जो दाएं से बाएं हैंडल करता है. भाषाओं को फ़्लिप करें. वैरिएबल. हमने ऐसा इसलिए किया, क्योंकि सीएसएस में कोई लॉजिकल प्रॉपर्टी ट्रांसफ़ॉर्म नहीं होती है, और ऐसा कभी नहीं होगा. एलाद को कस्टम प्रॉपर्टी वैल्यू का इस्तेमाल करने का शानदार आइडिया था प्रतिशत को उलटने के लिए, ताकि हमारी अपनी कस्टम जगह को एक ही जगह से मैनेज किया जा सके लॉजिकल ट्रांसफ़ॉर्म के लिए लॉजिक. मैंने इस स्विच में इसी तकनीक का इस्तेमाल किया है और मैंने हमें लगता है कि इससे बहुत मदद मिली:
.gui-switch {
--isLTR: 1;
&:dir(rtl) {
--isLTR: -1;
}
}
--isLTR
नाम की कस्टम प्रॉपर्टी में शुरू में 1
का मान होता है, जिसका मतलब यह है
true
क्योंकि हमारा लेआउट डिफ़ॉल्ट रूप से बाएं-से-दाएं होता है. इसके बाद, सीएसएस का इस्तेमाल करके
सूडो क्लास :dir()
,
कॉम्पोनेंट के दाएं से बाएं लेआउट में होने पर, वैल्यू -1
पर सेट होती है.
किसी ट्रांसफ़ॉर्म के अंदर calc()
में --isLTR
का इस्तेमाल करके, इसे चालू करें:
.gui-switch.-vertical > input {
transform: rotate(-90deg);
transform: rotate(calc(90deg * var(--isLTR) * -1));
}
अब वर्टिकल स्विच को दूसरी तरफ़ की स्थिति के हिसाब से घुमाया जाता है दाईं से बाईं ओर के लेआउट के लिए ज़रूरी है.
थंब स्यूडो-एलिमेंट में translateX
में होने वाले बदलाव को भी अपडेट करना ज़रूरी है
सेवा की शर्तों को पूरा करें:
.gui-switch > input:checked {
--thumb-position: calc(var(--track-size) - 100%);
--thumb-position: calc((var(--track-size) - 100%) * var(--isLTR));
}
.gui-switch > input:indeterminate {
--thumb-position: calc(
(var(--track-size) / 2) - (var(--thumb-size) / 2)
);
--thumb-position: calc(
((var(--track-size) / 2) - (var(--thumb-size) / 2))
* var(--isLTR)
);
}
हालांकि, इस तरीके से लॉजिकल सीएसएस जैसे कॉन्सेप्ट की सभी ज़रूरतों को पूरा नहीं किया जा सकता पूरी तरह से बदल देता है, लेकिन यह कुछ कई लोगों के लिए, DRY के सिद्धांत इस्तेमाल के उदाहरण.
राज्य
बिल्ट-इन input[type="checkbox"]
का इस्तेमाल इसके बिना पूरा नहीं होगा
यह उन अलग-अलग राज्यों को हैंडल करता है जहां यह हो सकता है: :checked
, :disabled
,
:indeterminate
और :hover
. :focus
को जान-बूझकर अकेला छोड़ा गया था. इसमें
जो सिर्फ़ अपने ऑफ़सेट पर किए गए हैं; फ़ोकस रिंग, Firefox पर बहुत बढ़िया लग रही थी और
सफ़ारी:
सही का निशान लगाया गया
<label for="switch-checked" class="gui-switch">
Default
<input type="checkbox" role="switch" id="switch-checked" checked="true">
</label>
यह राज्य, on
राज्य को दिखाता है. इस स्थिति में, इनपुट "track"
बैकग्राउंड चालू रंग पर और अंगूठे की पोज़िशन "
एंड".
.gui-switch > input:checked {
background: var(--track-color-active);
--thumb-position: calc((var(--track-size) - 100%) * var(--isLTR));
}
बंद है
<label for="switch-disabled" class="gui-switch">
Default
<input type="checkbox" role="switch" id="switch-disabled" disabled="true">
</label>
:disabled
बटन सिर्फ़ देखने में अलग नहीं दिखता, बल्कि
एलिमेंट को नहीं बदला जा सकता.ब्राउज़र में इंटरैक्शन नहीं करने की सुविधा मुफ़्त है, लेकिन
appearance: none
के इस्तेमाल की वजह से विज़ुअल स्थितियों को स्टाइल की ज़रूरत है.
.gui-switch > input:disabled {
cursor: not-allowed;
--thumb-color: transparent;
&::before {
cursor: not-allowed;
box-shadow: inset 0 0 0 2px hsl(0 0% 100% / 50%);
@media (prefers-color-scheme: dark) { & {
box-shadow: inset 0 0 0 2px hsl(0 0% 0% / 50%);
}}
}
}
यह मुश्किल है, क्योंकि इसमें गहरे और हल्के रंग वाली थीम बंद हैं. साथ ही, राज्यों को चुना गया है. मैंने इन राज्यों को आसान बनाने के लिए, स्टाइल के हिसाब से कम से कम स्टाइल चुनी अलग-अलग स्टाइल के कॉम्बिनेशन के रखरखाव का खर्च उठाता है.
तय नहीं किया जा सका
अक्सर भूलने वाली स्थिति :indeterminate
होती है, जहां चेकबॉक्स दोनों में से कोई नहीं होता
चुना गया या उससे सही का निशान हटाया गया है. यह एक मज़ेदार स्थिति है, यह लुभावने और साधारण है. बहुत अच्छा
ध्यान रखें कि दो राज्यों के बीच बूलियन स्टेट स्नीकी हो सकते हैं.
चेकबॉक्स को तय नहीं करना मुश्किल है, सिर्फ़ JavaScript इसे सेट कर सकता है:
<label for="switch-indeterminate" class="gui-switch">
Indeterminate
<input type="checkbox" role="switch" id="switch-indeterminate">
<script>document.getElementById('switch-indeterminate').indeterminate = true</script>
</label>
चूंकि राज्य मेरे लिए सादगी भरा और आमंत्रित है, इसलिए इस बीच में स्विच अंगूठे की स्थिति:
.gui-switch > input:indeterminate {
--thumb-position: calc(
calc(calc(var(--track-size) / 2) - calc(var(--thumb-size) / 2))
* var(--isLTR)
);
}
कर्सर घुमाएं
होवर इंटरैक्शन को कनेक्ट किए गए यूज़र इंटरफ़ेस (यूआई) के लिए विज़ुअल सपोर्ट देना चाहिए. साथ ही, इंटरैक्टिव यूज़र इंटरफ़ेस (यूआई) के बारे में जानकारी देता है. यह स्विच इसके साथ अंगूठे को हाइलाइट करता है लेबल या इनपुट पर कर्सर घुमाने पर, आधा-पारदर्शी रिंग होता है. यह होवर इसके बाद ऐनिमेशन, इंटरैक्टिव थंब एलिमेंट के बारे में बताता है.
"हाइलाइट" इफ़ेक्ट box-shadow
के साथ किया गया. कर्सर घुमाने पर, बंद नहीं किए गए इनपुट के लिए --highlight-size
का साइज़ बढ़ाएं. अगर उपयोगकर्ता को मोशन से जुड़ी कोई समस्या नहीं है, तो हम box-shadow
का ट्रांज़िशन करके इसे बढ़ाएंगे. अगर उनमें गति ठीक नहीं होती, तो हाइलाइट तुरंत दिखने लगती है:
.gui-switch > input::before {
box-shadow: 0 0 0 var(--highlight-size) var(--thumb-color-highlight);
@media (--motionOK) { & {
transition:
transform var(--thumb-transition-duration) ease,
box-shadow .25s ease;
}}
}
.gui-switch > input:not(:disabled):hover::before {
--highlight-size: .5rem;
}
JavaScript
मुझे लगता है कि स्विच इंटरफ़ेस किसी फ़िज़िकल प्रोसेस को टेस्ट करने के लिए, विशेष रूप से इस प्रकार के इंटरफ़ेस में एक सर्कल बना होता है. iOS ने यह सही जवाब दिया साथ ही, उन्हें एक-दूसरे से खींचकर दूसरी तरफ़ ले जाया जा सकता है. इससे अच्छा अनुभव मिलता है कि का विकल्प है. इसके उलट, अगर खींचकर छोड़ने का जेस्चर काम नहीं करता है, तो यूआई एलिमेंट काम नहीं कर रहा कोशिश की गई, लेकिन कुछ नहीं हुआ.
खींचने योग्य थंब्स
अंगूठे के छद्म एलिमेंट को .gui-switch > input
से अपनी पोज़िशन मिलती है
var(--thumb-position)
के दायरे में, JavaScript एक इनलाइन स्टाइल वैल्यू दे सकता है
थंब पोज़िशन को डाइनैमिक तौर पर अपडेट करने के लिए इनपुट. इससे ऐसा लगता है कि
पॉइंटर जेस्चर का इस्तेमाल करें. पॉइंटर रिलीज़ होने पर, इनलाइन स्टाइल हटा दें और
कस्टम प्रॉपर्टी का इस्तेमाल करके यह पता लगाएं कि ड्रैग की प्रोसेस बंद थी या चालू थी
--thumb-position
. यह घोल का आधार है; पॉइंटर इवेंट
सीएसएस कस्टम प्रॉपर्टी में बदलाव करने के लिए, पॉइंटर की पोज़िशन को ट्रैक करना.
इस स्क्रिप्ट के दिखने से पहले, यह कॉम्पोनेंट पूरी तरह से काम कर रहा था साथ ही, मौजूदा व्यवहार को बनाए रखने में भी बहुत मेहनत लगती है, जैसे इनपुट को टॉगल करने के लिए, किसी लेबल पर क्लिक करें. हमारी JavaScript में सुविधाएं नहीं जोड़ी जानी चाहिए मौजूदा सुविधाओं का खर्च बढ़ सकता है.
touch-action
खींचें और छोड़ें, एक जेस्चर है, जो इसे पसंद के मुताबिक बनाया जाता है. इस वजह से यह जेस्चर,
touch-action
के फ़ायदे. इस स्विच के मामले में, हॉरिज़ॉन्टल जेस्चर को
उसे हमारी स्क्रिप्ट से हैंडल किया जाएगा या वर्टिकल स्विच के लिए कैप्चर किया गया वर्टिकल जेस्चर
वैरिएंट. touch-action
की मदद से हम ब्राउज़र को बता सकते हैं कि हाथ के किन जेस्चर का इस्तेमाल करना है
इस एलिमेंट की मदद से, स्क्रिप्ट बिना किसी प्रतिस्पर्धा के जेस्चर को हैंडल कर सकती है.
नीचे दिया गया सीएसएस, ब्राउज़र को निर्देश देता है कि जब पॉइंटर जेस्चर शुरू होता है इस स्विच ट्रैक में, वर्टिकल जेस्चर हैंडल करें, हॉरिज़ॉन्टल वाला कुछ भी न करें इनमें शामिल हैं:
.gui-switch > input {
touch-action: pan-y;
}
जो नतीजा मिलता है वह एक हॉरिज़ॉन्टल जेस्चर होता है जो पेज के जेस्चर को पैन या स्क्रोल नहीं करता करें. पॉइंटर इनपुट में से वर्टिकल तौर पर स्क्रोल करके, नीचे की ओर स्क्रोल करके पेज, लेकिन हॉरिज़ॉन्टल मैन्युअल तौर पर हैंडल किए जाते हैं.
Pixel वैल्यू की स्टाइल से जुड़ी सुविधाएं
सेटअप करने के दौरान और खींचकर छोड़ने के दौरान, कंप्यूट की गई संख्या की अलग-अलग वैल्यू को पता करना होगा
एलिमेंट से निकाल दिया जाता है. यहां दिए गए JavaScript फ़ंक्शन, कंप्यूट किए गए पिक्सल वैल्यू दिखाते हैं
को सीएसएस प्रॉपर्टी दी गई है. इसका इस्तेमाल सेटअप स्क्रिप्ट में इस तरह किया जाता है
getStyle(checkbox, 'padding-left')
.
const getStyle = (element, prop) => {
return parseInt(window.getComputedStyle(element).getPropertyValue(prop));
}
const getPseudoStyle = (element, prop) => {
return parseInt(window.getComputedStyle(element, ':before').getPropertyValue(prop));
}
export {
getStyle,
getPseudoStyle,
}
ध्यान दें कि window.getComputedStyle()
किस तरह दूसरे आर्ग्युमेंट, टारगेट pseudo एलिमेंट को स्वीकार करता है. इस बात की अच्छी बात है कि JavaScript, एलिमेंट के कई वैल्यू पढ़ सकता है. यहां तक कि pseudo एलिमेंट से भी.
dragging
यह ड्रैग लॉजिक के लिए एक खास पल है और कुछ बातों का ध्यान रखना होगा फ़ंक्शन इवेंट हैंडलर से:
const dragging = event => {
if (!state.activethumb) return
let {thumbsize, bounds, padding} = switches.get(state.activethumb.parentElement)
let directionality = getStyle(state.activethumb, '--isLTR')
let track = (directionality === -1)
? (state.activethumb.clientWidth * -1) + thumbsize + padding
: 0
let pos = Math.round(event.offsetX - thumbsize / 2)
if (pos < bounds.lower) pos = 0
if (pos > bounds.upper) pos = bounds.upper
state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)
}
स्क्रिप्ट हीरो state.activethumb
है, जो कि इस स्क्रिप्ट का छोटा गोला है
पॉइंटर के साथ पोज़िशनिंग करें. switches
ऑब्जेक्ट एक Map()
है, जहां
कुंजियां .gui-switch
की हैं और वैल्यू, कैश मेमोरी में सेव की गई सीमाएं और साइज़ हैं, जो
सही तरीके से काम किया है. दाएं से बाएं हैंडल को एक ही कस्टम प्रॉपर्टी का इस्तेमाल करके हैंडल किया जाता है
वह सीएसएस --isLTR
है. साथ ही, वह लॉजिक को उलटा करने और जारी रखने के लिए इसका इस्तेमाल कर सकती है
RTL का समर्थन करना. event.offsetX
भी अहम है, क्योंकि इसमें डेल्टा है
अंगूठे को सही जगह पर रखने के लिए उपयोगी मान है.
state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)
सीएसएस की यह आखिरी लाइन, थंब एलिमेंट में इस्तेमाल की जाने वाली कस्टम प्रॉपर्टी सेट करती है. यह
वैल्यू असाइनमेंट समय के साथ ट्रांज़िशन होगा, लेकिन एक पिछला पॉइंटर
इवेंट ने --thumb-transition-duration
को कुछ समय के लिए 0s
पर सेट कर दिया है. यह इवेंट हटा दिया गया है
एक सुस्त इंटरैक्शन होता.
dragEnd
उपयोगकर्ता को स्विच से बाहर दूर ले जाने और उसे छोड़ने की अनुमति देने के लिए, ग्लोबल विंडो इवेंट को रजिस्टर करने की ज़रूरत है:
window.addEventListener('pointerup', event => {
if (!state.activethumb) return
dragEnd(event)
})
मुझे लगता है कि यह बहुत ज़रूरी है कि उपयोगकर्ता को आसानी से खींचकर छोड़ने की आज़ादी हो और इंटरफ़ेस पर्याप्त स्मार्ट होना चाहिए. इसे मैनेज करने में ज़्यादा समय नहीं लगा पर क्लिक किया था, लेकिन डेवलपमेंट के दौरान इसे ध्यान से प्रोसेस.
const dragEnd = event => {
if (!state.activethumb) return
state.activethumb.checked = determineChecked()
if (state.activethumb.indeterminate)
state.activethumb.indeterminate = false
state.activethumb.style.removeProperty('--thumb-transition-duration')
state.activethumb.style.removeProperty('--thumb-position')
state.activethumb.removeEventListener('pointermove', dragging)
state.activethumb = null
padRelease()
}
एलिमेंट के साथ इंटरैक्शन पूरा हो गया है. इनपुट को सेट करने का समय हो गया है
प्रॉपर्टी चुनने और जेस्चर से जुड़े सभी इवेंट को हटाने का तरीका. चेकबॉक्स इससे बदल जाता है
state.activethumb.checked = determineChecked()
.
determineChecked()
dragEnd
के ज़रिए कॉल किया जाने वाला यह फ़ंक्शन, तय करता है कि अंगूठे करंट कहां है
अपने ट्रैक की सीमाओं के अंदर होता है. साथ ही, अगर यह बराबर या इससे ज़्यादा हो, तो 'सही' दिखाता है
ट्रैक के आधे हिस्से में:
const determineChecked = () => {
let {bounds} = switches.get(state.activethumb.parentElement)
let curpos =
Math.abs(
parseInt(
state.activethumb.style.getPropertyValue('--thumb-position')))
if (!curpos) {
curpos = state.activethumb.checked
? bounds.lower
: bounds.upper
}
return curpos >= bounds.middle
}
अतिरिक्त विचार
शुरुआती एचटीएमएल स्ट्रक्चर की वजह से, ड्रैग जेस्चर की वजह से कोड पर कुछ क्रेडिट लिमिट आ गई है
चुना गया, खास तौर पर इनपुट को किसी लेबल में रैप करना. लेबल, अभिभावक होने के नाते
एलिमेंट है, तो इनपुट के बाद क्लिक इंटरैक्शन मिलेंगे. आखिर में
dragEnd
इवेंट, शायद आपने padRelease()
को अजीब तरीके से सुना हो
फ़ंक्शन का इस्तेमाल करना होगा.
const padRelease = () => {
state.recentlyDragged = true
setTimeout(_ => {
state.recentlyDragged = false
}, 300)
}
यह उस लेबल को ध्यान में रखकर बनाया गया है जिस पर बाद में क्लिक किया जाएगा. इससे सही का निशान हट जाएगा, या देखें कि उपयोगकर्ता ने क्या इंटरैक्शन किया है.
अगर मुझे इसे फिर से करना है, तो DOM को JavaScript से अडजस्ट कर सकते हैं एक ऐसा एलिमेंट बनाने के लिए जो लेबल वाले क्लिक को खुद हैंडल करता हो और बिल्ट-इन बिहेवियर के साथ काम नहीं करता है.
मुझे इस तरह का JavaScript लिखना बहुत कम पसंद है, क्योंकि मुझे इसे मैनेज नहीं करना शर्तों के साथ इवेंट के लिए बबल्स की सुविधा:
const preventBubbles = event => {
if (state.recentlyDragged)
event.preventDefault() && event.stopPropagation()
}
नतीजा
इस बेहद छोटे हिस्से में स्विच करने से, जीयूआई चैलेंज पर सबसे ज़्यादा काम हुआ अभी तक! अब जब आपको पता है कि मैंने इसे कैसे किया, तो आप कैसे करेंगे ‽ 🙂
आइए, हम अलग-अलग तरह के काम करते हैं और वेब पर काम करने के सभी तरीके सीखते हैं. एक डेमो बनाएं, मुझे ट्वीट करें और मैं इसे जोड़ दूंगा कम्यूनिटी रीमिक्स बनाने के लिए यहां दिए गए सेक्शन पर जाएं!
कम्यूनिटी रीमिक्स
- कस्टम एलिमेंट के साथ @KonstantinRouda: डेमो और कोड.
- @jhvanderschee पर इस बटन के साथ: कोडपेन.
संसाधन
.gui-switch
का सोर्स कोड यहां ढूंढें
GitHub.