2011-07-11 2 views
3

Я хочу отключить целую кучу объектов на странице, а затем снова включить их позже. Поскольку некоторые из них являются тегами, а не кнопками, я отключу их, удалив их onclick attr. Я попытался сохранить старый обработчик в .data(), но, к сожалению, когда я пытаюсь восстановить их с помощью $(obj).attr('onclick',$(obj).data('onclick')), он вызывает функцию, а не восстанавливает ее в атрибуте. И если я попытаюсь сохранить его в другом атрибуте вместо данных, он не сохранит функцию, он сохранит возвращаемое значение для функции.Сохранить и восстановить действие «onclick» на объектах jQuery

Есть ли способ сделать это без повторной записи каждого тега и каждого обработчика onclick на моей странице?

if(doEnable) { 

    $(obj).attr('href', $(obj).data('href')); 
    $(obj).attr('onclick', $(obj).data('onclick')); 


    $(obj).removeClass(EIS.config.classes.disabled); 
    $(obj).show(); 

} 
else { 
    // Save the things you're going to remove 
    $(obj).data('onclick', $(obj).attr('onclick')); 
    $(obj).data('href', $(obj).attr('href')); 

    $(obj).prop("href", null); 
    $(obj).prop("onclick", null); 

    $(obj).addClass(EIS.config.classes.disabled); 
    $(obj).show(); 
    } 

Кстати, этот код, кажется, работает хорошо в Chrome и Firefox, но только иногда в IE8 и никогда в IE6. К сожалению, клиент сначала тестирует IE6.

ответ

5
$(obj).attr('onclick', ... 

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

Проблема является разрыв между onclickатрибутом и onclickсобственности. jQuery попытался очистить разницу между атрибутом и свойством под ковром в прошлом, используя attr для доступа к обоим, но они совсем разные. Это было изменено в jQuery 1.6 и частично вернулось в 1.6.1, к широко распространенным спорам, путанице и несовместимости.

Для многих свойств значения атрибута и соответствующего свойства DOM одинаковы; для других, включая все свойства, которые не являются строками, они не являются. Обработчики событий, конечно же, не являются: свойство является объектом Function, тогда как атрибут строки может быть (a) исходной строкой атрибута onclick="..." в HTML, (b) ничего (если onclick был назначен из скрипта как функция объект) или (c) недоступно (в более старом IE).

Чтобы получить доступ к функциям свойства обработчика событий, используйте prop() в JQuery 1.6:

$(obj).data('onclick', $(obj).prop('onclick')); 
... 
$(obj).prop('onclick', $(obj).data('onclick')); 

или просто использовать обычный старый JavaScript, который на самом деле проще и более удобным для чтения; jQuery ничего не выигрывает здесь.

obj._onclick= obj.onclick; 
... 
obj.onclick= obj._onclick; 

В любом случае это не будет надежно «отключить» элементы, так как они могут (и скорее всего будет, если вы используете JQuery) другие слушатели событий, зарегистрированных на них, используя addEventListener/attachEvent, а не интерфейсы обработчиков событий старой школы.

+0

Использование метода Javascript было самым простым изменением, и, похоже, оно работает. –

0

Как связать событие в jQuery вместо установки атрибута onclick?

$(obj).click($(obj).data('onclick')); 

Можем ли мы увидеть код, который вы используете для установки атрибута данных?

1

Похоже, сохранение функции через .data() работает просто отлично:

var f1 = function() { console.log('invoked'); }; 
$('a').data('func', f1) 
var f2 = $('a').data('func'); // 'invoked' is not printed 
f1 === f2 // true 

так, как вы хранение функции с помощью .data? если вы делаете что-то вроде

a = $('a'); 
a.data('onclick', a.click()); // click handler is invoked here 

тогда вы на самом деле вызова обработчика щелчка (ы) преждевременно, и хранения возвращаемого значения с .data().

--edit--

оказывается, что .attr(function) вызывает переданную функцию. Это особенность jQuery. Я бы предложил использовать метод jQuery .click() для присоединения функции как обработчик кликов.

a = $('a'); 
a.each(function() { 
    this.data('onclick', handler_fn); 
    this.bind('click', handler_fn); 
}); 

// later 
a.each(function() { 
    this.unbind('click'); 
}); 

// even later 
a.each(function() { 
    this.bind('click', this.data('onclick')); 
}); 
Смежные вопросы