| Пара полезных, кроссбраузерных функцийРешил собрать функции с которыми разработчики встречаются часто. 1. Обработка события DOMContentLoaded (полная загрузка html кода) что бы func не вызывался два раза, нужно поставить проверку на выполнение этой функции 
function DOMOnload(func) {
    var doc = document;
    if(doc.addEventListener) {
	        doc.addEventListener('DOMContentLoaded', func, false);	
	}
	else if(doc.attachEvent) {
	    if(doc.documentElement.doScroll && window == window.top) {
		    (function() {
		        try {
			        doc.documentElement.doScroll('left');
				    func();
			    }
			    catch(e) {
			        setTimeout(arguments.callee, 10);
			    }
			})()
		}
	}
        
	if(window.attachEvent) {
	    window.attachEvent('onload', func);	
	}
	else if(window.addEventListener) {
	    window.addEventListener('load', func, false);
	}
} // в функции func добавьте проверку, что бы она вызвалась только 1 раз
2. Получение прозрачности getOpacity 
function getOpacity(obj) {
    var result = window.getComputedStyle ? window.getComputedStyle(obj, null).opacity : null; 
	if(!+"\v1")   //самое короткое определение ie		
		result = obj.filters.alpha ? (obj.filters.alpha.opacity / 100) : 1; 		
	
	return result;
}
3. Установка прозрачности setOpacity 
function setOpacity(obj, val) {
    if(!+"\v1") {
	    typeof obj.filters.alpha != 'undefined'
	        ? obj.filters.alpha.opacity = val * 100
		    : obj.style.filter = 'alpha(opacity=' + val * 100 + ');';
	}
		
	obj.style.opacity = val;
}
4. Добавление события addEvent 
function addEvent(obj, type, func) {
    if(obj.addEventListener) {
        obj.addEventListener(type, func, false);	
    }
    else if(obj.attachEvent) {
        var f = function(e) {
            func.call(obj, e); 
        }
        obj.attachEvent('on' + type, f); // obj.attachEvent('on' + type, func); не правильно передаст объект this
    }	
}
5. Получение координат мыши getMousePos 
function getMousePos(e) {
    var mouseX = mouseY = 0;
    var e = e || window.event;
    var html = document.documentElement;
    var bady = document.body;
		
    if(document.attachEvent) {
        mouseX = e.clientX + (html.scrollLeft ? html.scrollLeft : bady.scrollLeft);
	    mouseY = e.clientY + (html.scrollTop  ? html.scrollTop  : bady.scrollTop);			
    }
    else if(document.addEventListener) {
	    mouseX = e.clientX + window.scrollX;
	    mouseY = e.clientY + window.scrollY;
    }
	return {x : mouseX, y : mouseY}
}
6. Получение места расположения объекта getObjPos 
function getObjPos(elem) {  
    var box = elem.getBoundingClientRect()  
    
    var body = document.body  
    var docElem = document.documentElement  
    
    var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop  
    var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft  
    
    var clientTop = docElem.clientTop || body.clientTop || 0  
    var clientLeft = docElem.clientLeft || body.clientLeft || 0  
    
    var top  = Math.round(box.top +  scrollTop - clientTop);
    var left = Math.round(box.left + scrollLeft - clientLeft);  
	
	return {x : left, y : top}
}
 | 
> function getOpacity(obj)
Ой, порочный способ по-моему. Прежде всего result, возвращаемый фильтром, затирается, затем страшная конструкция с currentStyle (проприетарное из Explorer'а, да?).
Я бы сократил так, но не уверен в целесообразности currentStyle:
function getOpacity(obj) { if (obj.filters) { return obj.filters.alpha.opacity || 1; } else { return (obj.currentStyle || obj.style).opacity || 1; } }Так нельзя сокращать, т.к. если значение прозрачности будет равно нулю, то такая строка
всегда будет возвращать 1. Поэтому важной проверкой в этой функции является эта строка
Если возвращаемый результат будет равен 0 и сравнение будет != , то опять таки возвращаемый результат всегда будет 1. А obj.currentStyle нужен для того, что бы получить значение стиля если он установлен через CSS
Да, действительно. Но с currentStyle я все равно не понял. Он ведь проприетарный и работает только в ie, который изначально отфильтровывается. В семерке разве не поддерживается element.style?
Удобства currentStyle в этом случае таково, что оно работает точно так же (кроме установки значения) как и style, но может получать первоначальное значение стиля прописанного с помощью CSS
Ерунда и велосипед.
После этого вы сразу переписываете значение.
Хотя бы так:
getOpacity=function(elem){ if(typeof elem.style.opacity=="number") return elem.style.opacity; if(elem.style.filter) return Number(elem.style.filter.match(/opacity=(\d+)/i)||[1,1])[1]); return 1; }> DOMContentLoaded (полная загрузка html кода)
CB DOMContentLoaded
Не думаю, что ерунда, то чуточку не доработанная функция оказалась.
А в список ерунды это
точно попадает, т.к. таким образом не получишь значение прописанное через CSS
Переписал функцию
function getOpacity(obj) { var result; result = window.getComputedStyle ? window.getComputedStyle(obj, null).opacity : null; // Firefox, Opera, Chrome if(result === null) { // для IE так же удобно получать значение opacity, что бы прописывать в setOpacity result = typeof (obj.currentStyle || obj.style).opacity != 'undefined' && (obj.currentStyle || obj.style).opacity !== '' ? (obj.currentStyle || obj.style).opacity : 1; } return result; }В список ерунды попадает твоя фунция в принципе, ибо она не достанет свойство в 70% браузеров. В IE<8, свойства opacity нет.
>всегда будет возвращать 1. Поэтому важной проверкой в этой функции является >эта строка
Бред. style.opacity возвращает не число, а строку...
!!0 - будет false, !!"0" - будет true;
>В список ерунды попадает твоя фунция в принципе, ибо она не достанет свойство в 70% браузеров. В IE<8, свойства opacity нет.
Опять вы ленитесь! IE6 и 7 поддерживают это свойство.
>Бред. style.opacity возвращает не число, а строку...
Если значение будет установлено след. образом
то
эта строка вернет 1 хотя должна была вернуть 0
> эта строка вернет 1 хотя должна была вернуть 0
Если ты установишь 0 туда, где не поддерживается свойство opacity, поэтому рекомендую устанавливать "0", на такой случай. Так и правильней, ведь в CSS свойства строковые. Попробуй проверить typeof в разных браузерах
И с каких пор IE поддерживает свойство opacity?
Ты мне говоришь "Опять вы ленитесь!", если самому лень элементарно проверить или прочитать где нибудь в интернете про это свойство...
Если его можно установить - это не значит, что оно меняет прозрачность.
Это свойство поддерживается лишь в W3C совместимых браузерах и является частью рекомендаций CSS3, IE таковым никогда не был и использует DirectX фильтры...
Зачем тогда в своем первом примере считываешь прозрачность через фильтр, а в фунции setOpacity записываешь фильтр?
Не заметил, сам себе противоречишь!
Проще рассказать минусы.
1) Нет обработки filter для ie
2) В первую очередь ты вытаскиваешь изначальное значение, которое никогда не поменяется. т.е. в первую очередь нужно смотреть в .style, а потом уже вычислять computed.
Твоя функция будет возвращать всегда только одно значение, если изначально стиль имел значение opacity.
4) var result; result =
Не проще var result=, сэкономил 9 байт
Можно еще перечислить, но лень...
Вот еще вариант, который можно улучшить, опять же лень))
var getOpacity=function(style){ if(!style) return; if(style.nodeName){ var computed=window.getComputedStyle?getComputedStyle(style,null):style.currentStyle; return getOpacity(style.style)||getOpacity(computed)||1; } var opacity=style.opacity, filter=style.filter; if(opacity){ return Number(opacity); }else if(filter){ var alpha=filter.match(/opacity=(\d+)/i); if(alpha&&alpha[1]) return Number(alpha[1])/100; } }Функция setOpacity:
function setOpacity(obj, val) { obj.style.filter && obj.filters ? obj.filters.alpha.opacity = val * 100 : obj.style.filter = 'alpha(opacity=' + val * 100 + ');'; obj.style.opacity = val; }Если будет указан фильтр, но не будет указана alpha, то свойство obj.filters.alpha - будет undefined, дальнейший вызов obj.filters.alpha.opacity выкинет ошибку-исключение...
Зачем вообще извращение с obj.filters.alpha.opacity, если можно просто установить obj.style.filter? Разве что только для сохранения другого фильтра.
Наверное лучше:
var setOpacity=function(el,alpha){ el.style.filter="alpha(opacity="+(el.style.opacity=alpha)*100+")"; }>1) Нет обработки filter для ie
2) В первую очередь ты вытаскиваешь изначальное значение, которое никогда не поменяется. т.е. в первую очередь нужно смотреть в .style, а потом уже вычислять computed.
Твоя функция будет возвращать всегда только одно значение, если изначально стиль имел значение opacity.
1) Взамен этого и достается значение opacity
2) Разница getComputedStyle и style для не IE в том, что с помощью первого можно только читать, а с помощью второго можно и читать и устанавливать. Не ленитесь не в чем!
.d { opacity:0.2; }var d = document.getElementById('d'); d.style.opacity = 0.33; function getOpacity(obj) { var result = window.getComputedStyle ? window.getComputedStyle(obj, null).opacity : null; // Firefox, Opera, Chrome if(result === null) { //IE result = typeof (obj.currentStyle || obj.style).opacity != 'undefined' && (obj.currentStyle || obj.style).opacity !== '' ? (obj.currentStyle || obj.style).opacity : 1; } return result; } alert(getOpacity(d));>Наверное лучше:
Опять таки не ленитесь и если сомневаетесь, то проверьте!
> Взамен этого и достается значение opacity
Оно всего лишь достается, раз ты сам его вписал! А прозрачности не будет в IE, если фильтр не установлен.
А со вторым, просмотрел я проверку if(result === null) { //IE
function addEvent(obj, evnt, func) { if(obj.attachEvent) { obj.attachEvent('on' + evnt, func); } else if(obj.addEventListener) { obj.addEventListener(evnt, func, false); } }Зачем так Oper'у обидел? Будет вернее:
function addEvent(obj, evnt, func) { if(obj.addEventListener) { obj.addEventListener(evnt, func, false); }else if(obj.attachEvent) { obj.attachEvent('on' + evnt, func); } }То же самое и тут:
function getMousePos(e) { mouseX = mouseY = 0; var e = e || window.event; var html = document.documentElement; var bady = document.body; if(document.attachEvent) { mouseX = e.clientX + (html.scrollLeft ? html.scrollLeft : bady.scrollLeft); mouseY = e.clientY + (html.scrollTop ? html.scrollTop : bady.scrollTop); } else if(document.addEventListener) { mouseX = e.clientX + window.scrollX; mouseY = e.clientY + window.scrollY; } return {x : mouseX, y : mouseY} }Плюс засоряешь глобал переменными mouseX = mouseY = 0;
Сам писал, что при нуле условие не сработает, так?
html.scrollLeft ? html.scrollLeft : bady.scrollLeft
А вообще можно перечислить еще громадное количество ошибок, можешь поверить на слово.
Зачем надо было это писать и путать новичков в js, подобным абсурдным арсеналом?
>Плюс засоряешь глобал переменными mouseX = mouseY = 0;
Согласен!
>Сам писал, что при нуле условие не сработает, так?
В этом случае это не играет роли, если прокрутка равна нулю, но так и надо!
>Зачем надо было это писать и путать новичков в js, подобным абсурдным арсеналом?
Не соглашаюсь, вашим мнением, т.к. они основаны всего лишь на ваших рассуждениях!
> Не соглашаюсь, вашим мнением, т.к. они основаны всего лишь на ваших рассуждениях!
Ну да, в прошлой статье ты тоже был уверен, что открыл мега способ, ну да ладно...
Понимаю, что мне не доверяешь, а себе доверяешь?
Тогда предлагаю протестировать (!) СВОИ (!) функции:
1) Функции addEvent, getMousePos под браузерами Opera, особенно 9.XX, посмотреть, как ставятся ивенты.
2) setOpacity в IE, если установлен фильтр и не указана alpha.
3) Свою последнюю getOpacity в IE, если .div {filter: alpha(opacity=90)}
4) DOMOnload попробовать навесить два обработчика, это позволяют делать все библиотеки.
5) getObjPos попробовать запустить в Safari, Chrome, Konqueror, FF2 (В самых новых версиях WebKit уже поддерживается getBoundingClientRect)
> Пара полезных, кроссбраузерных функций
Да уж, кроссбраузерность!
Даже я твои функции потестил, а ты никак не соберёшься, а еще мне пишешь, чтобы не ленился...
Похоже на повторное изобретение велосипеда, только отточенный аппарат был сделан заново некрасиво и с ошибками...
Всё это есть в jquery и иже с ними, причём в гораздо более продуманном виде.
Вашим хозяйством как-то совсем уж неудобно пользоваться...
В DOMOnload хорошо бы сделать проверку document.readyState и/или document.onreadystatechange, как в цивиллизованых библиотеках.
В DOMOnload навешивая мнежества обработчиков, с коллбеком func, ты обрекаешь пользователь на её многокрытный запуск, потому что в 90% случаев сработает несколько событий.
Вот это проверка!!!
Когда это opacity бывало со значением "undefined"?
Может быть так, не?
Или
И ещё
Большинство браузеров возвращают null, если свойство поддерживается, но не установлено, а ""!==null
Вызовет ошибку у элемента с пустым style и если браузер не поддерживает getComputedStyle (кроме IE). У undefined не возможно прочитать свойство opacity
Пишу снова, что есть еще куча ошибок
Исправил функцию getOpacity!
Протестил IE6,7,8 Firefox 3.6 Opera 10.53 Chrome 6.0.472.63
function getOpacity(obj) { var result = window.getComputedStyle ? window.getComputedStyle(obj, null).opacity : null; if(result === null) result = obj.filters.alpha ? (obj.filters.alpha.opacity / 100) : 1; return result; }>Протестил IE6,7,8 Firefox 3.6 Opera 10.53 Chrome 6.0.472.63
1) Браузеры не поддерживающие getComputedStyle и страницы в которых не установлена .opacity (! КРОМЕ IE) попадают в жестокую битву с result = obj.filters.alpha ? (obj.filters.alpha.opacity / 100) : 1; и сразу же выкидывают исключение, потому что у них нет свойства obj.filters.
Большинство браузеров W3C в которых свойство не установлено никаким из способов, будет вызывать ошибку исключение.
2) obj.style.filter="progid:DXImageTransform.Microsoft.Alpha(opacity=80)";
Этот вариант является предпочтительным в IE (синтаксис IE5), и именно таким способом устанавливают прозрачность множество (если не большинство) webdev.
obj.filters.alpha - не считает это свойство, а считывается оно так:
obj.filters['DXImageTransform.Microsoft.alpha']
Потому и удобнее использовать регулярку /opacity=([0-9])/i
3) А если opacity не задано? Будешь undefined на сто делить и возврашать пользователю NaN, чтобы у него весь дальнейший код порушить? (obj.filters.alpha.opacity / 100)
4) window.getComputedStyle ? window.getComputedStyle(obj, null).opacity
В этом случае, ты возвращаешь string.
obj.filters.alpha ? (obj.filters.alpha.opacity / 100)
А в этом - number.
Если пользователь захочет прибавить 0.1 к opacity равмому 0.1 полученному через твою функцию, в IE он получит число 0.2, в других браузерах строку "0.10.1"
Стоит хотя бы так сделать: return Number(result);
5) И опять же можно продолжить
Воспользуюсь твоей фразой: "Не ленитесь не в чем!" и "Опять таки не ленитесь и если сомневаетесь, то проверьте!"
>1) Браузеры не поддерживающие getComputedStyle
Хотел бы поинтересоваться, что это за браузеры кроме IE
>и страницы в которых не установлена .opacity
если у элемента не установлен opacity не в каком виде, getComputedStyle вернет 1, а это выражение
тоже вернет 1.
Функция работает так:
1) Если это не IE и opacity не установлен, то
вернет 1! А если opacity установлен либо через css либо через javascript, то
вернет это значение.
2) Если IE и
установлен через css или
, то
будет иметь значение [object] и свойство opacity всегда доступно. А если alpha никаким образом и ни где не указано, то возвращаемый результат будет 1!
Долго тестил перед тем как выкладывать! согласен на счет того, что выдаваемый результат нужно возвращать в числовом виде!
И действительно getComputedStyle возвращает 1, хотя и есть ноды, в которых свойство не прочитать.
И alpha тоже возвращает, с любыми стилями, позициями и конечной прозрачностью в фильтре.
Проглядел.
ОК, 1 и 3 пункт снимаются из за невнимательности
Ну а такое:
.filter="progid:DXImageTransform.Microsoft.Alpha(opacity=80)";
или, как сейчас валидней в ie8:
.MsFilter="progid:DXImageTransform.Microsoft.Alpha(opacity=80)";
функция не достанет, что очень печально, так как использует этот синтаксис очень много девелоперов
Ну раз снял 2 пункта, надо бы их возместить
function setOpacity(obj, val) { if(document.all) { typeof obj.filters.alpha != 'undefined' ? obj.filters.alpha.opacity = val * 100 : obj.style.filter = 'alpha(opacity=' + val * 100 + ');'; } obj.style.opacity = val; }1) Коллекция document.all есть уже почти во всех современных браузерах и obj.filters.alpha вызовет исключение в браузерах (не ie).
2) Этим:
obj.style.filter = 'alpha(opacity=' + val * 100 + ');
затираешь другие фильтры, применённые к элементу. Например так часто используемый DXImageTransform.Microsoft.AlphaImageLoader.
Удачи
у вас тут ошибочка!!!
Форум Книги Блоги Стандарт языка * Мастер-классы по javascript * Справочник
Статьи Тест знаний Аналоги функций PHP PHPClub.ru Примерочная Курсы javascript
Поиск по форуму
Отображать темы Отображать сообщения
Расширенный поиск
К странице...
Главная » Javascript-Блоги » HelpeR » Пара полезных, кроссбраузерных функций
« Проблема insertBefore с таблицейДоступ к объекту filters »
HelpeR (блог) , 4 окт 2010 - 13:34 функции просмотров:2232
Пара полезных, кроссбраузерных функций
Решил собрать функции с которыми разработчики встречаются часто.
1. Обработка события DOMContentLoaded (полная загрузка html кода) что бы func не вызывался два раза, нужно поставить проверку на выполнение этой функции
показать чистый исходник в новом окнеСкрыть/показать номера строкпечать кода с сохранением подсветки01 function DOMOnload(func) {
02 var doc = document;
03 if(doc.addEventListener) {
04 doc.addEventListener('DOMContentLoaded', func, false);
05 }
06 else if(doc.attachEvent) {
07 if(doc.documentElement.doScroll && window == window.top) {
08 (function() {
09 try {
10 doc.documentElement.doScroll('left');
11 func();
12 }
13 catch(e) {
14 setTimeout(arguments.callee, 10);
15 }
16 })()
17 }
18 }
19
20 if(window.attachEvent) {
21 window.attachEvent('onload', func);
22 }
23 else if(window.addEventListener) {
24 window.addEventListener('load', func, false);
25 }
26 } // в функции func добавьте проверку, что бы она вызвалась только 1 раз
2. Получение прозрачности getOpacity
показать чистый исходник в новом окнеСкрыть/показать номера строкпечать кода с сохранением подсветки1 function getOpacity(obj) {
2 var result = window.getComputedStyle ? window.getComputedStyle(obj, null).opacity : null;
3 if(!+"\v1") //самое короткое определение ie
4 result = obj.filters.alpha ? (obj.filters.alpha.opacity / 100) : 1;
5
6 return result;
7 }
3. Установка прозрачности setOpacity
показать чистый исходник в новом окнеСкрыть/показать номера строкпечать кода с сохранением подсветки1 function setOpacity(obj, val) {
2 if(!+"\v1") {
3 typeof obj.filters.alpha != 'undefined'
4 ? obj.filters.alpha.opacity = val * 100
5 : obj.style.filter = 'alpha(opacity=' + val * 100 + ');';
6 }
7
8 obj.style.opacity = val;
9 }
4. Добавление события addEvent
показать чистый исходник в новом окнеСкрыть/показать номера строкпечать кода с сохранением подсветки01 function addEvent(obj, type, func) {
02 if(obj.addEventListener) {
03 obj.addEventListener(type, func, false);
04 }
05 else if(obj.attachEvent) {
06 var f = function(e) {
07 func.call(obj, e);
08 }
09 obj.attachEvent('on' + type, f); // obj.attachEvent('on' + type, func); не правильно передаст объект this
10 }
11 }
5. Получение координат мыши getMousePos
показать чистый исходник в новом окнеСкрыть/показать номера строкпечать кода с сохранением подсветки01 function getMousePos(e) {
02 var mouseX = mouseY = 0;
03 var e = e || window.event;
04 var html = document.documentElement;
05 var bady = document.body; здесь var body!!!!<<<<<<<<<
с чего вы взяли, что должно быть body?
Синтаксически-правильнее, более читабельно.
Можно было-бы и var html назвать var hpml