Поведение щелчка JavaScript отличается от поведения ручного

#javascript #prototypejs

#javascript #prototypejs

Вопрос:

С prototype я прослушиваю событие щелчка на нескольких флажках. При щелчке флажка я хочу отключить все <select> элементы. Я использую prototype. Итак, у меня есть этот код:

 
$$('.silhouette-items input[type="checkbox"]').invoke('observe', 'click', function(event) {
            var liItem = this.up('li.item');      
            if(this.checked) {
                alert('checked');
                liItem.removeClassName('inactive');
                var selectItem = liItem.select('select');
                for(i=0;i<selectItem.length;i  ) {
                    selectItem[i].disabled=false;   
                    if (selectItem[i].hasClassName('super-attribute-select')) {
                        selectItem[i].addClassName('required-entry');
                    }
                }
            } else {
                alert('unchecked');
                liItem.addClassName('inactive');
                var selectItem = liItem.select('select');
                for(i=0;i<selectItem.length;i  ){
                    selectItem[i].disabled=true;
                    if (selectItem[i].hasClassName('super-attribute-select')) {
                        selectItem[i].removeClassName('required-entry');
                    }
                }
            }
            calculatePrice();
        });
  

Когда я вручную нажимаю на флажок, кажется, все в порядке. Все элементы отключены по мере необходимости.
Однако у меня также есть эта кнопка, которая при событии щелчка запускает одну функцию, которая запускает событие щелчка по этому флажку.

В браузере Opera это работает. В других — нет. Это похоже на то, что Opera сначала (отменяет) проверку, а затем выполняет событие. Firefox сначала запускает событие, затем (отменяет) элемент проверки.

Я не знаю, как это исправить.

HTML:

 
<ul class="silhouette-items">
  <li>
    <input type="checkbox" checked="checked" id="include-item-17" class="include-item"/>
    <select name="super_attribute[17][147]">(...)</select>
    <select name="super_group[17]">(...)</select>
    <button type="button" title="button" onclick="addToCart(this, 17)">Add to cart</button>
  </li>
  <!-- Repeat li few time with another id -->
</ul>
  

Другой JS:

 
addToCart = function(button, productId) {
            inactivateItems(productId);
            productAddToCartForm.submit(button);
        }
inactivateItems = function(productId) {
             $$('.include-item').each(function(element) {
                var itemId = element.id.replace(/[a-z-]*/, '');
                if (itemId != productId amp;amp; element.checked) {
                    simulateClickOnElement(element);
                }
                if (itemId == productId amp;amp; !element.checked) {
                    simulateClickOnElement(element);
                }
            });
        }
simulateClickOnElement = function(linkElement) {
            fireEvent(linkElement, 'click');
        }
  

Где fireEvent находится функция Magento, которая запускает событие

Комментарии:

1. Можете ли вы использовать change событие вместо a click ?

2. @clockworkgeek Я пытался с этим, и это тоже не было хорошо.

Ответ №1:

Не утруждайте себя имитацией onclick, если вам это сойдет с рук. В вашем случае должно работать наличие отдельной функции, которую можно вызывать как из обработчика событий, так и извне.


 var handler = function(){
    //...
}
var nodeW = $('#node');
handler.call(nodeW);
  

Конечно, это не запускает все возможные обработчики onclick, но это проще, поэтому все должно работать нормально. Указывает на то, когда вы используете .call для вызова функции:

  1. Все, что вы передаете в качестве первого параметра, используется как this внутри вызова. Я не помню точно, что устанавливает jQuery this , но вы должны попробовать передать то же самое для согласованности.

  2. Остальные параметры становятся фактическими параметрами функции. В моем примере я не пропускаю ни одного, поскольку мы фактически не используем объект event, а также поскольку я не знаю, как эмулировать то, как jQuery также создает этот объект.

Комментарии:

1. Я понимаю вашу точку зрения здесь. Переосмысление и переопределение здесь не плохая идея. Спасибо, я рассмотрю это позже.

Ответ №2:

замена

 fireEvent(linkElement, 'click');
  

с

 linkElement.click();
  

работает в firefox 5 и Safari 5.1, поэтому, возможно, проблема заключается в методе fireEvent().

Комментарии:

1. Спасибо, но, насколько я знаю click() , функция может не работать в более старом IE. На самом деле я сначала использовал его, но некоторые люди из моей компании сказали, что они использовали fireEvent , потому что он более совместим с браузерами.