Нужна проверка поддержки события "DOMMouseScroll"
Никак не могу найти способ выяснить поддерживает ли браузер событие "DOMMouseScroll". Проверять ЮА на предметт соответствия FF кажется плохой идеей.
|
Можно попробовать использовать сторонний плагин - http://github.com/brandonaaron/jquer...el/tree/master
|
Цитата:
|
can3p, постановка задачи (кроссбраузерные функции установки обрабочиков) исключает использование jquery.
B~Vladi, Цитата:
Временно я опеделяю FF через Event.LOAD, но это очень криво, надо поменять на что-то. Или решить проблему иным способом.
/*
Установка обработчиков событий.
windows.addEH(node, type, handler) -- повесить обработчик
windows.delEH(node, type, handler) -- снять обработчик
В MSIE обработчик получает аргумент event дополненный следующими методами и свойствами:
event.preventDefault
event.stopPropagation
event.pageX
event.pageY
event.relatedTarget
event.which
Во всех браузерах:
метод stop объекта Event выполняет методы preventDefault и stopPropagation
свойство isWheelDown возвращает направление колеса мыши (true -- колесо на себя, false -- от себя)
*/
(function(){
//
// Установка обработчиков для MSIE основана на коде Dean Edwards.
//
var win = window,
doc = document,
huid = 0, // счетчик, используемый для создания уникальных ID
uniPropName = "$RNV601MCTCU",
W3C = !! win.addEventListener, // document.implementation.hasFeature("Events", "2.0")
// -------------------------------------------------------------------------------------
// ВОТ ЗДЕСЬ
// надо заменить Event.LOAD на внятную проверку поддержки события "DOMMouseScroll"
mousewheel = { mousewheel : win.Event && Event.LOAD ? "DOMMouseScroll" : null },
handle = function () {
var returnValue = true,
event = getFixedIEEvent(window.event || (this.ownerDocument || this).parentWindow.event),
handlers = this[uniPropName][event.type];
for (var i in handlers)
if (handlers[i].call(this, event) === false)
returnValue = false;
return returnValue;
},
getFixedIEEvent = function (event) {
// Добавление стандартных методов событий W3C
var d = doc.documentElement,
b = doc.body,
button = event.button,
target = event.target = event.srcElement || doc;
// pageX и pageY корректные для quirks и строгих режимов
event.pageX = event.clientX + (d.scrollLeft || b.scrollLeft || 0) - (d.clientLeft || 0);
event.pageY = event.clientY + (d.scrollTop || b.scrollTop || 0) - (d.clientTop || 0);
event.relatedTarget = event.fromElement == target ? event.toElement : event.fromElement;
// which -- Returns the numeric keyCode of the key pressed, or the character code (charCode) for an alphanumeric key pressed
// -------------------------------------------------------------------------
// | MSIE | Konqueror | Opera, FF, Safari Win
// -------------------------------------------------------------------------
// левая | event.which | undefined | 1 | 1
// кнопка | event.button | 1 | 1 | 0
// средняя | event.which | undefined | 2 | 2
// кнопка | event.button | 4 | 4 | 1
// правая | event.which | undefined | 3 | 3
// кнопка | event.button | 2 | 2 | 2
//
// Поскольку в W3C-совместимых движках мы обходимся без оберток, (и соответственно фиксим событие только в ие),
// то для определения нажатой кнопки мыши приходится использовать устаревший which (почему -- см. таблицу)
//
event.which = event.charCode || event.keyCode || (button < 2 ? 1 : button == 4 ? 2 : 3);
event.preventDefault = preventDefault;
event.stopPropagation = stopPropagation;
//event.detail = event.wheelDelta / -40;
event.stop = stop;
event.isWheelDown = event.wheelDelta < 0;
return event;
},
preventDefault = function() {
this.returnValue = false;
},
stopPropagation = function() {
this.cancelBubble = true;
},
stop = function () {
this.preventDefault();
this.stopPropagation();
};
if(win.Event) {
Event.prototype.stop = stop;
// В FF MouseScrollEvent не наследует у Event, поэтому добавляем "isWheelDown" соответствующему объекту
(win.MouseScrollEvent || Event).prototype.__defineGetter__("isWheelDown", function (){
// Особенности события mousewheel в браузерах: [url]http://generalized.ru/?p=133[/url]
return this.detail > 0 || this.wheelDelta < 0
})
};
win.addEH = W3C ?
function(node, type, handler) {
node.addEventListener(mousewheel[type] || type, handler, false);
} :
function(node, type, handler) {
type = mousewheel[type] || type;
var ontype = "on" + type,
events = node[uniPropName] || (node[uniPropName] = {}),
handlers = events[type];
handlers || (
handlers = events[type] = {},
node[ontype] &&
(handlers[0] = node[ontype])
);
handler[uniPropName] || (
handler[uniPropName] = huid++
);
handlers[huid] = handler;
node[ontype] = handle;
};
win.delEH = W3C ?
function(node, type, handler) {
node.removeEventListener(mousewheel[type] || type, handler, false);
} :
function(node, type, handler) {
type = mousewheel[type] || type;
if (node[uniPropName] && node[uniPropName][type])
delete node[uniPropName][type][handler[uniPropName]];
};
})()
|
Denisko-Redisko,
прошу прощения, больше не буду. Но кроссбраузерный jquery плагин может быть источником кроссбраузерных самопальных функций. |
Они там вешают сразу оба обработчика, как и все везде.
|
Цитата:
|
Цитата:
|
B~Vladi,
что в этом плохого? |
Цитата:
|
А некрасивого чего? Если одни и те же действия должны выполнятся при возникновении нескольких событий. Делать несколько одинаковых функций?
|
Некрасиво то, что мы пытаемся прикрутить обработчик на событие, которого не существует.
|
И кроме того будет очень весело если FF начнет поддерживать onmousewheel.
|
Можно поступить так... Создаём элемент, вешаем на него обработчик для onmousewheel, программно генерим событие и регистрируем это. После генерации проверяем - произошло или нет, а потом уже делаем соответствующие выводы;)
|
Да, пожалуй это самый правильный способ :) Спасибо.
|
Вроде нашел короткое решение. В Gecko DOMMouseScroll является частью интерфейса nsIDOMMouseScrollEvent. Наличие этого интерфейса проверяется так:
Components.interfaces.nsIDOMMouseScrollEvent Теперь тот участок скрипта выглядит так:
...
//
// Gecko использует событие "DOMMouseScroll" вместо "mousewheel"
// Наличие этого интерфейса в Gecko можно проверить так: Components.interfaces.nsIDOMMouseScrollEvent
//
ff, mousewheel = {
mousewheel : (ff = window.Components) &&
(ff = ff.interfaces) &&
(ff = ff.nsIDOMMouseScrollEvent ) ? "DOMMouseScroll" : null
},
|
Цитата:
|
Цитата:
|
B~Vladi,
оно у тебя якобы работает лишь по простой причине, то что ты допустил ошибку в коде. Строка 12 вместо onmousewheel нужно писать mousewheel а так ты не пытаешься вызвать событие на которое повесил обработчик в браузерах поддерживающих addEvenetListener |
попробуй написать брехню вместо onmousewheel и оно у тебя также сработает. Тоесть ты просто вызовешь собственное событие, которое не обязательно должно существовать в браузере
|
Цитата:
Цитата:
|
B~Vladi,
Ну вот смотри, Опера поддерживает как mousewheel так и DOMMouseScroll. привожу пример:
function getWheelEvent(){
var eventType='DOMMouseScroll';
var listener=function(){
eventType='myevent';
}
var ele=document.createElement('div');
document.body.appendChild(ele);
if(ele.addEventListener)ele.addEventListener('myevent',listener,false);
else if(ele.attachEvent)ele.attachEvent('onmyevent',listener);
if(document.createEvent&&ele.dispatchEvent){
var evt=document.createEvent('HTMLEvents');
evt.initEvent('myevent',true,true);
ele.dispatchEvent(evt);
}else ele.fireEvent('onmyevent',event);
if(ele.removeEventListener)ele.removeEventListener('myevent',listener,false);
else if(ele.detachEvent)ele.detachEvent('onmyevent',listener);
document.body.removeChild(ele);
return eventType;
}
alert(getWheelEvent());
тут ты получишь myevent потому что функция addEvenetListener по стандартам w3c позволяет создавать собственные события и инициировать их. просто пример по аналогии jQuery
$('div').bind('myevent', function(){
alert("triggered myevent");
});
$('div').trigger('myevent');
тоесть в твоем коде по стандарту initEvent не должен начинаться с префикса on у тебя же оно есть, а событие висит на обычном событие без префикса. |
Цитата:
Цитата:
|
Цитата:
function test( event ) {
var status = false,
elem = document.createElement('div');
document.body.appendChild( elem );
elem.addEventListener( event, function() {
status = true;
}, false);
var evt=document.createEvent('HTMLEvents');
evt.initEvent( event ,true, true );
elem.dispatchEvent( evt );
document.body.removeChild( elem );
return status;
}
alert( test( 'TratataEvent' ) );
alert( test( 'click' ) );
alert( test( 'DOMMouseScroll' ) );
alert( test( 'onmousewheel' ) );
alert( test( 'mousewheel' ) );
Все эти тесты всегда выведут значение true Цитата:
А для ИЕ достаточно сделать такую проверку:
function test( event ) {
var status = false,
elem = document.createElement('div');
document.body.appendChild( elem );
try {
elem.fireEvent( event, document.createEventObject() );
status = true;
} catch ( _ ) {
}
document.body.removeChild( elem );
return status;
}
alert( test( 'onmousewheel' ) );
alert( test( 'onblahtest' ) );
|
B~Vladi,
У вас таки ошибка.
if(ele.addEventListener)ele.addEventListener('mousewheel',listener,false);
var evt=document.createEvent('HTMLEvents');
evt.initEvent('onmousewheel',true,true);
ele.dispatchEvent(evt);
Найдите разницу в 2 символа в создаваемом и запускаемом объекте. Это лишь ИЕ падает на fireEvent, когда пытаешься ему вызвать не существующее событие в браузере. И так, как правильно проверить, в браузере поддерживается mousewheel или DOMMouseScroll
if(document.body.addEventListener){
if('onmousewheel' in document.body || document.body.onmousewheel === null){
// mousewheel event
}else if(window.MouseScrollEvent){
//DOMMouseScroll by Gecko
}else if(window.WheelEvent){
//DOMMouseScroll DOM 3 Events - Webkit support
}else {
//default behavior
//passing 2 events - DOMMouseScroll && mousewheel
}
}else if(window.attachEvent){
//old IE - mousewheel
}else {
//default behavior ...
}
|
Как заметили мне в приват, лучше конечно проверять с начала на существование DOMMouseScroll события :)
|
if ( window.MouseScrollEvent || window.WheelEvent ) {
// Gecko | Webkit
event = "DOMMouseScroll";
} else if ( window.addEventListener ) {
// Opera | IE 9
event = "mousewheel";
} else {
// IE before v9
event = "onmousewheel";
}
|
Цитата:
|
Да ок ок, вы посмотрите какого года этот пост. Кстати, я удалил 2 последние.
|
B~Vladi,
гг, действительно, кто блин такое апает :) |
хех... дык сам автор темы и апнул ее сегодня =)
|
Цитата:
Цитата:
Отписался. Так как с 2009 года в этом отношении ничего не улучшилось, как вешали под два обработчика, так и вешают, и в популярных фреймворках, и в велосипедах. |
Denisko-Redisko,
Вообще вы правы, да. WebKit поддерживает событие mousewheel, причём которое тоже не является стандартизированным, в отличии от события wheel. Но хоть интерфейс для него правильный использует. |
| Часовой пояс GMT +3, время: 14:26. |