Попытка смоделировать щелчок на ярлыке
Почему это не работает? Метка находится внутри родительского элемента.item. Я не хочу помещать это вне элементов блока, поскольку это не будет действительным.
Поэтому я пытаюсь смоделировать щелчок на ярлыке:
$(".item").click(function(){
$(this).find("label").click();
});
Изменить: он должен вызвать ярлык и проверить радио.
<script type="text/javascript">
$(document).ready(function () {
$(".item").click(function() {
$(this).find("label").click();
});
});
</script>
<div class="item">
<h4>Item</h4>
<ul>
<li>Description</li>
</ul>
<div class="radio-container">
<div class="radio-stack">
<input type="radio" class="styled" id="item1">
</div>
<label for="item1">$100</label>
</div>
</div>
2 ответа
Поскольку этот ярлык прикреплен к некоторому входу (используя for
атрибут), вы можете попробовать что-то вроде:
var inputID = $(this).find("label").attr("for");
$('#' + inputID).click();
Однако вы должны быть осторожны: так как ваш ввод находится внутри div с .item
класс, имитирующий щелчок по радио, снова вызовет ваш пользовательский обработчик, вызывая бесконечный цикл. Если возможно, просто установите радио checked
приписывать true
вместо симуляции клика:
$('#' + inputID).attr("checked",true);
(Рабочий пример на jsFiddle)
В противном случае вам нужно будет найти способ исключить это радио из .item
селектор, чтобы избежать этого бесконечного цикла.
Обновление: после небольшой борьбы с not
селекторы, безуспешно, я придумал быстрый и грязный хак: использовать глобальный (для ready
переменная), чтобы контролировать, происходит ли симуляция клика:
var updating = false;
$(".item").click(function() {
if ( !updating ) {
var inputID = $(this).find("label").attr("for");
updating = true;
$('#' + inputID).click();
updating = false;
}
});
Рабочий пример здесь. IMO Айман Сафади ответ лучше, но если у вас возникли проблемы с его работой в кросс-браузерах, эту альтернативу можно использовать в качестве отправной точки.
Чтобы строго ответить на ваш вопрос, он не работает, потому что вызывает бесконечный цикл "кликов", а ваш браузер просто молча убивает событие.
Запустите эту демонстрацию и посмотрите на свою консоль JS: http://jsfiddle.net/bRyR3/
div
захватывает label
событие клика. Другими словами, JavaScript интерпретирует вашу логику следующим образом:
Когда вы нажимаете на
.item
вызватьlabel
"click
" событие.
label
это внутри.item
следовательно, еслиlabel
щелкнул, так это.item
,Когда вы нажимаете на
.item
вызватьlabel
"click
" событие.
label
это внутри.item
следовательно, еслиlabel
щелкнул, так это.item
,Когда вы нажимаете на
.item
вызватьlabel
"click
" событие.
label
это внутри.item
следовательно, еслиlabel
щелкнул, так это.item
,так далее...
Работаем над актуальным решением.
Решение
$('.item').on('click', function(e) {
console.log('click');
$('label', $(this)).trigger('click');
});
$('.item label').on('click', function(e) {
e.stopPropagation();
});
Это остановит .item
от захвата label
"s click
событие.
Рабочая демонстрация: http://jsfiddle.net/bRyR3/1/
Поскольку этот вопрос и ответ появляются при поиске решения, существует третий способ решить эту проблему:
JQuery позволяет отправлять настраиваемые параметры обработчикам событий on() с помощью trigger()
См. https://api.jquery.com/trigger/
Это означает, что можно избежать бесконечного цикла, просто сообщив обработчику события, что текущее событие является "искусственным":
$( document ).on( 'click touch', '.item', function( event, artificial ) {
if( artificial ) return;
$(this).find("label").trigger( 'click', [ true ] );
} );
Это имеет то преимущество, что не останавливает распространение (или не полагается на него), а также не возится с различными типами ввода (флажками, радио, текстами и т. Д.). Он просто имитирует щелчок по этикетке без какой-либо дополнительной работы с нашей стороны или каких-либо бесконечных циклов.