Пользовательская точность переключателя

В настоящее время у меня есть два переключателя с пользовательскими стилями. Код стиля и переключателя был найден в основном в Интернете, с некоторыми изменениями, которые я изменил в соответствии со своими потребностями. Проблема, с которой я столкнулся, заключается в том, что если вы щелкнете за пределами поля, он все равно выберет определенное расстояние, но не вызовет соответствующее событие щелчка.

let calcType = document.querySelector('#calcType')
let calcTypeLabels = document.querySelectorAll('.styled-label span')

calcTypeLabels.forEach((check) => {
check.addEventListener('click', (ev) => {
    let parent = ev.target.parentElement
    if (parent.querySelector('input').checked == false) {
        parent.querySelector('input').checked = true
        console.info("clicked radio button")
        // setCalcType(parent.querySelector('input').value)
        // currentType = parent.querySelector('input').value
        // setRangeStyle()
    }
})
})
/* Custom Radio Buttons */

.styled-radio {
  display: none;
}

.styled-label {
  display: inline-block;
  padding: 5px 10px;
  cursor: pointer;
  /* This is the element that senses the clicks */
}

.styled-label span {
  position: relative;
  line-height: 22px;
}

.styled-label span:before,
.styled-label span:after {
  content: "";
}

.styled-label span:before {
  border: 1px solid #222021;
  width: 20px;
  height: 20px;
  /* margin-right: 10px; */
  display: inline-block;
  vertical-align: top;
}

.styled-label span:after {
  width: 14px;
  height: 14px;
  position: absolute;
  top: 2px;
  left: 4px;
  transition: 300ms;
  opacity: 0;
}

.styled-label input:checked + span:after {
  opacity: 1;
}

.radio-label::after {
  pointer-events: none;
}

.styled-label span:after {
    background-color: red;
}
<!DOCTYPE html>
<html>
    <head>
        <link href = "./example.css" rel = "stylesheet" type = "text/css" />
    </head>
    <body>
        <label class = "styled-label">
            <label class = "radio-label" for = "calcType">Difficulty</label>
            <br />
            <input
                class = "styled-radio"
                id = "calcType"
                type = "radio"
                name = "calcType"
                value = "diff"
                checked
            />
            <span></span>
        </label>

        <label class = "styled-label">
            <label class = "radio-label" for = "calcType">Study Days</label>
            <br />
            <input
                class = "styled-radio"
                id = "calcType"
                type = "radio"
                name = "calcType"
                value = "days"
            />
            <span></span>
        </label>

        <script src = "./example.js"></script>
    </body>
</html>

Есть ли способ исправить это, либо остановив события щелчка на определенных элементах (попробовал несколько вещей ::after, но ничего не помогло), либо, возможно, используя другой способ стилизации переключателей.

Сначала исправьте HTML-код: ярлык внутри ярлыка быть не может.

A Haworth 10.07.2024 21:47

Кроме того, идентификаторы должны быть уникальными.

j08691 10.07.2024 21:48

@AHaworth Вот почему я пишу. Это было из онлайн-руководства, которое я использовал, и оно является основной частью работы этих кнопок, поэтому я не уверен, как исправить, чтобы ничего не сломалось.

kaitlynmm569 10.07.2024 21:50

Радио находятся внутри метки, которая также активирует радио и существует за пределами фактического ввода. Диапазон, в котором есть прослушиватель событий, находится над переключателем, поэтому вместо этого вы можете добавить прослушиватель событий к метке.

mykaf 10.07.2024 21:50

Вы должны сообщить человеку, написавшему руководство, которому вы следовали, что он дает плохой совет и пишет неверный HTML.

j08691 10.07.2024 21:52

Что ж, я бы для начала прекратил использовать этот урок, а затем почитал бы о метках и о том, какой эффект они оказывают.

A Haworth 10.07.2024 21:55
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

HTML-код неправильный; id должен быть уникальным и другие вещи должны быть изменены. Когда вы помещаете атрибут for на метку, вы говорите, что если я нажму на метку, я выберу радиовход, поэтому он выбирается, когда вы нажимаете рядом с входом. Нет, для проблемы, с которой вы столкнулись, если хотите запускать событие каждый раз, когда вы выбираете переключатель, вы можете использовать событие change вместо click и поместить событие на сам вход. Так:


let calcTypeLabels = document.querySelectorAll('[name = "calcType"]')



    calcTypeLabels.forEach((check) => {
      check.addEventListener('change', (ev) => {
        console.info("clicked radio button")

        let parent = ev.target.parentElement
        if (parent.querySelector('input').checked == false) {
          parent.querySelector('input').checked = true
          console.info("clicked radio button")
        }
      })
    })

Теперь каждый раз, когда значение меняется, вы можете его прослушивать.

Но основная проблема, с которой вы сталкиваетесь в своем JS, заключается в том, что вы прикрепляете событие к span внутри метки, которая имеет ширину и высоту ввода, но когда вы щелкаете по метке или окружающему пространству, for запускает событие change. и автоматически измените значение. Но click не сработает, потому что вы не нажали на элемент span. Обратите внимание на селектор в функции querySelectorAll.

Если вы хотите зарегистрироваться конкретно на click мероприятие, сообщите мне, и я проверю.

Другие вопросы по теме