Если бы существовал универсальный файл common.js, которым пользовались бы все разработчики, вы бы нашли там эти десять (плюс одна бонусная) функций.
UPDATE март 2010: Эта статья была обновлена и переписана, чтобы соответствовать сегодняшнему дню и общему уровню сайта.
Эти функции неоднократно были испытаны и доказали свою полезность всем тем, кто их использовал. Поэтому, без лишних вступлений, вот список из десяти, по моему мнению, величайших пользовательских функций на JavaScript, которые используются в настоящее время.
Несомненно, важнейший инструмент в управлении событиями! Вне зависимости от того, какой версией вы пользуетесь и кем она написана, она делает то, что написано у неё в названии: присоединяет к элементу обработчик события.
addEvent()
function addEvent(elem, evType, fn) {
if (elem.addEventListener) {
elem.addEventListener(evType, fn, false);
}
else if (elem.attachEvent) {
elem.attachEvent('on' + evType, fn)
}
else {
elem['on' + evType] = fn
}
}
Этот код обладает двумя достоинствами - он простой и кросс-браузерный.
Основной его недостаток - в том, он не передает this в обработчик для IE. Точнее, этого не делает attachEvent.
this Для передачи правильного this можно заменить соответствующую строку addEvent на:
elem.attachEvent("on"+evType, function() { fn.apply(elem) })
Это решит проблему с передачей this, но обработчик никак нельзя будет снять, т.к. detachEvent должен вызывать в точности ту функцию, которая была передана attachEvent.
Существует два варианта обхода проблемы:
function addEvent(elem, evType, fn) {
if (elem.addEventListener) {
elem.addEventListener(evType, fn, false)
return fn
}
iefn = function() { fn.call(elem) }
elem.attachEvent('on' + evType, iefn)
return iefn
}
function removeEvent(elem, evType, fn) {
if (elem.addEventListener) {
elem.removeEventListener(evType, fn, false)
return
}
elem.detachEvent('on' + evType, fn)
}
Используется так:
function handler() {
alert(this)
}
var fn = addEvent(elem, "click", handler)
...
removeEvent(elem, "click", fn)
this в обработчике события вообще, а передавать элемент через замыкание:
function handler() {
// используем не this, а переменную, ссылающуюся на элемент
alert(*!*elem*/!*)
}
...
В качестве альтернативы и для примера более серьезной библиотеки обработки событий вы можете рассмотреть статью Кросс-браузерное добавление и обработка событий.
Для инициализации страницы исторически использовалось событие window.onload, которое срабатывает после полной загрузки страницы и всех объектов на ней: счетчиков, картинок и т.п.
Событие onDOMContentLoaded - гораздо лучший выбор в 99% случаев. Это событие срабатывает, как только готов DOM документ, до загрузки картинок и других не влияющих на структуру документа объектов.
Это очень удобно, т.к. картинки могут загружаться долго, а обработчик onDOMContentLoaded может произвести необходимые изменения на странице и инициализацию интерфейсов тут же, не дожидаясь загрузки всего.
Для добавления обработчика можно использовать следующий кроссбраузерный код:
function bindReady(handler){
var called = false
function ready() { // (1)
if (called) return
called = true
handler()
}
if ( document.addEventListener ) { // (2)
document.addEventListener( "DOMContentLoaded", function(){
ready()
}, false )
} else if ( document.attachEvent ) { // (3)
// (3.1)
if ( document.documentElement.doScroll && window == window.top ) {
function tryScroll(){
if (called) return
if (!document.body) return
try {
document.documentElement.doScroll("left")
ready()
} catch(e) {
setTimeout(tryScroll, 0)
}
}
tryScroll()
}
// (3.2)
document.attachEvent("onreadystatechange", function(){
if ( document.readyState === "complete" ) {
ready()
}
})
}
// (4)
if (window.addEventListener)
window.addEventListener('load', ready, false)
else if (window.attachEvent)
window.attachEvent('onload', ready)
/* else // (4.1)
window.onload=ready
*/
}
readyList = []
function onReady(handler) {
if (!readyList.length) {
bindReady(function() {
for(var i=0; i<readyList.length; i++) {
readyList[i]()
}
})
}
readyList.push(handler)
}
Использование:
onReady(function() {
// ...
})
Подробное описание функций bindReady, onReady и принципы их работы вы можете почерпнуть в статье Кроссбраузерное событие onDOMContentLoaded.
Изначально не написана никем конкретно. Многие разработчики писали свои собственные версии и ничья не показала себя лучше остальных.
Следующая функция использует встроенный метод getElementsByClass, если он есть, и ищет элементы самостоятельно в тех браузерах, где этого метода нет.
if(document.getElementsByClassName) {
getElementsByClass = function(classList, node) {
return (node || document).getElementsByClassName(classList)
}
} else {
getElementsByClass = function(classList, node) {
var node = node || document,
list = node.getElementsByTagName('*'),
length = list.length,
classArray = classList.split(/\s+/),
classes = classArray.length,
result = [], i,j
for(i = 0; i < length; i++) {
for(j = 0; j < classes; j++) {
if(list[i].className.search('\\b' + classArray[j] + '\\b') != -1) {
result.push(list[i])
break
}
}
}
return result
}
}
Например:
var div = document.getElementById("mydiv")
elements = getElementsByClass('class1 class2', div)
Следующие две функции добавляют и удаляют класс DOM элемента.
function addClass(o, c){
var re = new RegExp("(^|\\s)" + c + "(\\s|$)", "g")
if (re.test(o.className)) return
o.className = (o.className + " " + c).replace(/\s+/g, " ").replace(/(^ | $)/g, "")
}
function removeClass(o, c){
var re = new RegExp("(^|\\s)" + c + "(\\s|$)", "g")
o.className = o.className.replace(re, "1ドル").replace(/\s+/g, " ").replace(/(^ | $)/g, "")
}
Если быть честным, наверное для этой функции существует больше различных вариантов, чем было бы нужно.
Этот вариант никоим образом он не претендует на звание универсальной функции-"переключателя", но он выполняет основную функциональность показывания и спрятывания.
function toggle(el) {
el.style.display = (el.style.display == 'none') ? '' : 'none'
}
Обратите внимание, в функции нет ни слова про display='block', вместо этого используется пустое значение display=''. Пустое значение означает сброс свойства, т.е. свойство возвращается к значению, указанному в CSS.
Таким образом, если значение display для данного элемента, взятое из CSS - none (элемент спрятан по умолчанию), то эта функция toggle не будет работать.
Этот вариант функции toggle красив и прост, однако этот и некоторые другие недостатки делают его недостаточно универсальным. Более правильный вариант toggle, а также функции show и hide описаны в статье Правильные show/hide/toggle.
Как и getElementsByClass, этой функции почему-то нет в стандарте DOM. Возможно, чтобы избежать дублирования функционала, т.к. insertAfter реализуется всего одной строчкой.
function insertAfter(parent, node, referenceNode) {
parent.insertBefore(node, referenceNode.nextSibling);
}
Очень жаль, что это не часть встроенной функциональности DOM. Зато теперь у нас есть возможность всё время вставлять такие вот замечания!
Для поиска эта функция использует проверку ===, которая осуществляет поиск по точному сравнению, без приведения типов.
Метод Array.prototype.indexOf поддерживается не во всех браузерах, поэтому используется, если существует.
inArray = Array.prototype.indexOf ?
function (arr, val) {
return arr.indexOf(val) != -1
} :
function (arr, val) {
var i = arr.length
while (i--) {
if (arr[i] === val) return true
}
return false
}
В javascript нет способа нормально работать с cookie без дополнительных функций. Не знаю, кто проектировал document.cookie, но сделано на редкость убого.
Поэтому следующие функции или их аналоги просто необходимы.
// возвращает cookie если есть или undefined
function getCookie(name) {
var matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\1ドル') + "=([^;]*)"
))
return matches ? decodeURIComponent(matches[1]) : undefined
}
// уcтанавливает cookie
function setCookie(name, value, props) {
props = props || {}
var exp = props.expires
if (typeof exp == "number" && exp) {
var d = new Date()
d.setTime(d.getTime() + exp*1000)
exp = props.expires = d
}
if(exp && exp.toUTCString) { props.expires = exp.toUTCString() }
value = encodeURIComponent(value)
var updatedCookie = name + "=" + value
for(var propName in props){
updatedCookie += "; " + propName
var propValue = props[propName]
if(propValue !== true){ updatedCookie += "=" + propValue }
}
document.cookie = updatedCookie
}
// удаляет cookie
function deleteCookie(name) {
setCookie(name, null, { expires: -1 })
}
Аргументы:
byId Она позволяет функции работать одинаково при передаче DOM-узла или его id.
function byId(node) {
return typeof node == 'string' ? document.getElementById(node) : node
}
Используется просто:
function hide(node) {
node = byId(node)
node.style.display = 'none'
}
function animateHide(node)
node = byId(node)
something(node)
hide(node)
}
Здесь обе функции полиморфны, допускают и узел и его id, что довольно удобно, т.к. позволяет не делать лишних преобразований node <-> id.
Надеюсь, этот небольшой и удобный список JavaScript-функций будет столь же полезен вам, сколь он полезен мне.
| Поиск по сайту |
| Последние темы на форуме |
Forum |
в JS нет худших и лучших функций, все нужны и полезны в конкретных ситуациях
Я бы еще добавил динамическую подгрузку JavaScript файлов, например этот метод: http://www.artlebedev.ru/tools/technogrette/js/include/
или метод который используется в Scriptalicous
Не нашел куда написать, поэтому пишу сюда. Я написал самое компактное определение IE из всех которые я знаю. Думаю пригодится:
можно и в 5 символов, но будет возвращаться false в эксплорере
Используется баг с подсчетом элементов массива.
Подробнее здесь: линк
Статью переписал. Как следствие, многие комментарии перестали относиться к переписанному варианту и были убраны.
По виду, получилось более актуально чем было...
Функции setCookie и getCookie работают в FireFox, но не работают в Chrome:
setCookie('Test1', 'TestText1', ""); alert(getCookie('Test1'));В чём тут дело? Либо можно пример вызова, который точно работает?
Дело в том, что 3й аргумент - props - объект. Если не хотите его указывать - не надо ставить "".
setCookie('Test1', 'TestText1'); alert(getCookie('Test1'));Так тоже не работает. У вас установлен Хром? Ну, попробуйте создать пустую страничку с одним этим скриптом. Выдаст undefined. A FireFox - "TestText1".
Да, установлен. Попробуйте сами - вот страничка http://javascript.ru/test.html . Все работает.
Но я же не могу свои странички к вам на сервер закачивать. Я запускаю со своего винчестера. И не работает.
Закачайте их к себе на сервер и запустите. Дело, видимо, как раз в том, что вы с винчестера запускаете, а надо - с сайта.
А у меня сейчас нету сервера. Да и неудобно это. Вот на винчестере страничка, я её правлю, и сразу проверяю в браузере, никуда не закачивая.
Да и в FireFox'e то работает нормально. Может что-то не учтено, надо в скрипт ещё какую-то строчку кода для Хрома добавить?
Насколько я знаю, кука ставиться для УРЛа (Домена).
Если вы открываете страничку с винта, то где там имя домена?
Возможно Хром понимает бесполезность такого действия и ничего не предпринимает.
Насчет сервера: почему это неудобно? Неужели трудно поставить Денвер или какой-нибудь его аналог и работать в нормальных условиях, приближенных к реальным?
у хрома (по крайней мере на начальных этапах его становления и развития) наблюдается проблема с работой кук. долго бился, пока не понял это =( куки ни одним обычным методом не удалялись: и пустоту в них писал, и нулл, и время в прошлое... просто голову сломал.
Объясните пожалуйста, зачем в функции getElementsByClass():
a) нужна переменная key
b) нужны границы слова в
а) убрал, она лишняя была
б) границы нужны, чтобы корректно обрабатывать элемент со множеством классов:
Без указания границ слова всё обрабатывается корректно. По крайней мере я не смог создать такую ситуацию, когда отсутствие границ слова вызвало бы ошибку. Проверял с разными классами, с разным количеством пробелов, в разных браузерах. Не могли бы вы привести пример когда без границ слова, будет выводиться что-то неправильное?
Всё. Дошло. На самом деле "\\b" нужно не для того чтобы обрабатывать элементы с несколькими классами. А для таких случаев, если у меня есть один элемент с "class1" и другой элемент с "class11111". Без "\\b" по запросу "class1" будут найдены оба элемента.
Пожалуйста верните комментарий, в котором приведены аналоги на JQuery.
Он был очень полезным.
Нашел красивейшую функцию по замене inArray:
function oc(a) { var o = {}; for (var i = 0, l = a.length; i < l; i++) { o[a[i]] = ''; } return o; } alert('test' in oc(['te', 'st', 'test'])); alert('test' in oc(['te', 'st', 'es', 't'])); alert(25 in oc([1, 2, 3, 4, 25])); alert(1 in oc([2, 3, 4, 25]));Источник
Да действительно орининальное решение - но бесполезное - слишком много итераций. Это при больших массивах очень долго, особенно если искомое значение (по "закону полдлости") будет вначале масива.
Еще недостаток она не универсальна - с объектами работать не будет
("...a.length ...").
Знаю что не открываю Америку и не изобретаю велосипед - поэтому это только для GreatRash (автора комментария):
//-Проверяет содержится ли значение в массиве/объекте
inObject=inArray=function(obj, value, flEqualityType){
/*
Параметры:
- obj - объект или массив значений в котором ищем
- value - искомое значение
- flEqualityType - (необязательный) - флаг сравнения типов [true | false]
(по умолчанию false - сравнение без типов данных)
*/
var obj=obj, value=value, flEqualityType=flEqualityType || false;
if(!obj || typeof(obj)!='object') return false;
for(var i in obj){
if(flEqualityType===true && obj[i]===value) return true;
if(flEqualityType===false && obj[i]==value) return true;
}
return false;
};
Функция insertAfter не будет работать, если попытаться вставить ноду после последнего элемента в узле, т.к. его nextSibling == null. Вот рабочий вариант:
function insertAfter(node, ref_node) { var next = ref_node.nextSibling; if (next) next.parentNode.insertBefore(node, next); else ref_node.parentNode.appendChild(node); }Можно обойтись и без дополнительной переменной next, но так наглядней...
Ваш пример нужно дорабатывать, т.к. nextsibling может указывать на текстовый элемент.
function next(elem) { do { elem = elem.nextSibling; } while ( elem && elem.nodeType != 1 ); return elem; }Ну и соответственно
RomanWeberov, с какой такой стати текстовые элементы не должны учитываться? Функция insertAfter() должна вставлять элемент строго после указанного и никак иначе.
Вы проверяли, что не будет работать?
Относительно текстового элемента - он тоже элемент..
Да, надо было проверить:(
Теперь буду знать:)
Но в любом случае, функцию можно упростить, убрав из списка аргументов parent'а.
Отличная подборка сценариев Обожаю ваш блог и ваш труд
Илья, мне кажется пример с getElementsByClassName() может ввести в заблуждение новичков, потому как этот метод по спецификации принимает один аргумент, а у тебя в примере использования их несколько причем еще и ID. Для этого есть querySelector(), querySelectorAll();
К тому же код можно упростить, сделать более универсальным, а также значительно увеличить производительность:
<script type="text/javascript"> window.onload = function() { getElementsByClass = function(getClass){ if(document.querySelectorAll) { return document.querySelectorAll("." + getClass); } else if(document.getElementsByClassName) { return document.getElementsByClassName(getClass); } else { var list = document.getElementsByTagName('*'), i = list.length, classArray = getClass.split(/\s+/), result = []; while(i--) { if(list[i].className.search('\\b' + classArray + '\\b') != -1) { result.push(list[i]); } } return result; } }; getElementsByClass('class')[0].style.color = 'red'; }; </script> <p class="class">text</p>PS: добавление querySelectorAll() дает нам возможность работать с IE8+, а обратный цикл уменьшает время выполнения функции в несколько раз
Отличный вариант, спасибо.
Нельзя использовать в регулярках \bneedle\b, так как christmas-tree-needle это один класс.
if (document.getElementsByClassName) { getElementsByClass = function(classList, node) { return (node || document).getElementsByClassName(classList) } } else { getElementsByClass = function(classList, node) { var node = node || document, list = node.getElementsByTagName('*'), length = list.length, classArray = classList.split(/\s+/), classes = classArray.length, result = [], i,j for(i = 0; i < length; i++) { for(j = 0; j < classes; j++) { if(list[i].className.search('\\b' + classArray[j] + '\\b') != -1) { result.push(list[i]) break } } } return result } } function findByClass(str, node) { node || (node = document); if (node.getElementsByClassName) { return node.getElementsByClassName(str); } else { var nodeList = node.getElementsByTagName('*'), nodeListIndex = 0, classList = (' '+str.split(/\s+/).join(' ; ')+' ').split(';'), classListIndex, result = [], className, index; while (node = nodeList[nodeListIndex++]) { index = 0; classListIndex = 0; while (className = classList[classListIndex++]) { if ((' ' + node.className + ' ').indexOf(className) >= 0) { index++; } } if (index == classList.length) { result.push(node); } } return result; } } var elems = getElementsByClass('par par1', document.getElementById("d1")); for (var i = 0, len = elems.length; i < len; i++) { elems[i].style['color'] = 'red'; } var elems = findByClass('par par1', document.getElementById("d2")); for (var i = 0, len = elems.length; i < len; i++) { elems[i].style['color'] = 'blue'; }В FireFox 11 подсветка не работает.
Функция getElementsByClass() работает неверно в IE при поиске узлов с несколькими классами.
<script type="text/javascript"> if(document.getElementsByClassName) { getElementsByClass = function(classList, node) { return (node || document).getElementsByClassName(classList) } } else { getElementsByClass = function(classList, node) { var node = node || document, list = node.getElementsByTagName('*'), length = list.length, classArray = classList.split(/\s+/), classes = classArray.length, result = [], i,j for(i = 0; i < length; i++) { for(j = 0; j < classes; j++) { if(list[i].className.search('\\b' + classArray[j] + '\\b') != -1) { result.push(list[i]) break } } } return result } } elems=getElementsByClass('par par1'); for (var i=0;elems.length;i++) elems[i].style.color='red'; </script> <p class="par">Текстовый блок</p> <p class="par par1">Текстовый блок под номером два</p>В FF и Opera будет выделен второй абзац, т.к. используется встроенная функция, а IE выделит оба.
8) getElementsByClass()
Все таки не представлен настоящии универсальный метод:(
По моему самый лучшии вариант от monolithed
НО он загружает только 1 класс
Как правильно сделать полный обход?
var classl=getElementsByClass('class1').length;
for (var i=0; i<classl; i++) {
getElementsByClass('class1')[i].style.color='red';
};// пока только так придумал.. подскажите плиз
Я для себя написал вот такой inArray, он работает и для многомерных массивов
Array.prototype.inArray = Array.prototype.indexOf ? function(elem){ for(var i = 0, len = this.length; i < len; i ++){ if(this.indexOf(elem) != -1 || (this[i] instanceof Array && this[i].inArray(elem))){ return true; } } return false; } : function(elem){ for(var i = 0, len = this.length; i < len; i ++){ if(elem === this[i] || (this[i] instanceof Array && this[i].inArray(elem))){ return true; } } return false; }Точнее так
Array.prototype.inArray = Array.prototype.indexOf ? function(elem){ if(this.indexOf(elem) != -1){ return true; }else{ for(var i = 0, len = this.length; i < len; i ++){ if(this[i] instanceof Array && this[i].inArray(elem)){ return true; } } } return false; } : function(elem){ for(var i = 0, len = this.length; i < len; i ++){ if(elem === this[i] || (this[i] instanceof Array && this[i].inArray(elem))){ return true; } } return false; }Ошибка в inArray(), строка 8. вместо a[] надо arr[]
Как по мне, так такой вариант выборки классов будет побыстрее:
getElementsByClassName = function(klass, root) { root = root || document; if (root.querySelectorAll) { return root.querySelectorAll('.' + klass) } else if (root.getElementsByClassName) { return root.getElementsByClassName(klass) } else { var list = root.all || root.getElementsByTagName('*'); var result = []; for (var index = 0, elem; elem = list[index++];) { if (elem.className && (' ' + elem.className + ' ').indexOf(' ' + klass + ' ') > -1) { result[result.length] = elem } } return result } };мой вариант функции inArray
без цикла, и символов меньше
А не легче использовать такой код:
document.getElementsByClassName = function (cl) { return document.querySelectorAll('.' + cl); }Или я чего-то не понимаю?
Например, того, что некоторые недобраузеры функции querySelectorAll не понимают.
8) getElementsByClass()
if(document.getElementsByClassName){ /* Здесь логика AND: getElementsByClassName - ищет строгое соответствие строке classList т.е. к элементу должно быть применено class1 && class2 */ }else{ /* Здесь логика OR: разбор строки classList т.е. к элементу может быть применено море классов и поиск такой class1 || class2 */ }Вариант:
if(document.getElementsByClassName){ var getElementsByClass = function(classList, node){ var node = node || document, classArray = classList.split(/\s+/), result=[]; for(i=0; i<classArray.length; i++){ j=node.getElementsByClassName(classArray[i]); if(j!='undefined'){ result.push(node.getElementsByClassName(classArray[i])); } } return result;//aray nodes } }else{ // ... для недобраузеров код прежний }Подскажите, пожалуйста setCookie(name, value, props)
как у эту функцию установить время или дату.
я так понимаю что она сидит в props
как задать в него параметры
подскожите пож. как из .csv где есть много строк, наити самыю длиныю строку и выведить её ,при етом показати сколько букв содержит строка и какой ряд?
Предлагаю свой вариант работы с классами:
var has_class=function(obj,class_name){ return _has_class.apply(null,arguments); }; var _has_class=function(obj,class_name){ var hc1=function( obj , class_name ){ return obj.classList.contains(class_name); } var hc2=function( obj , class_name ){ class_name = " " + class_name + " "; return ( (' '+obj.className+' ').indexOf(class_name) >= 0 ); } if( obj.classList ){ _has_class=hc2; }else{ _has_class=hc2; } hc1=hc2=null; return _has_class.apply(null,arguments); }; var add_class=function( obj , class_name ){return _add_class.apply(null,arguments); }; var _add_class=function( obj , class_name ){ var ac1=function( obj , class_name ){ obj.classList.add(class_name); return this;} var ac2=function( obj , class_name ){ var re = new RegExp("(^|\\s)" + class_name + "(\\s|$)", "g"); if (!re.test(obj.className)) {obj.className = (obj.className + " " + class_name).replace(/\s+/g, " ").replace(/(^ | $)/g, "");} }; if( obj.classList ){ _add_class=ac1; }else{ _add_class=ac2; } ac1=ac2=null; _add_class.apply( null, arguments ); }; var remove_class=function( obj , class_name ){ return _remove_class.apply(null,arguments); }; var _remove_class=function( obj , class_name ){ var rc1=function( obj , class_name ){ obj.classList.remove(class_name); }; var rc2=function( obj , class_name ){ var re = new RegExp("(^|\\s)" + class_name + "(\\s|$)", "g"); obj.className = obj.className.replace(re, "1ドル").replace(/\s+/g, " ").replace(/(^ | $)/g, ""); } if( obj.classList ){_remove_class=rc1;}else{_remove_class=rc2;} rc1=rc2=null; remove_class.apply(null,arguments); };Немного сжато, рабочий вариант.
Применен шаблон самоопределяемых функций.
Функции обертки нужны, чтобы иметь возможность правильно импортировать функции из области видимости.
Преимущества: определение пути выполнения осуществляется только один раз, при первом вызове функции, при этом используются возможности HTML5. Нормальные браузеры будут работать еще быстрее (чем в JQuery, но не проверял), не нормальные - на том же уровне.
Немного переживаю за излишнее замыкание, но пошел на наго из-за компактности.
Еще пара функций:
var get_offset=function(elem){ return _get_offset(elem); }; var _get_offset=function(elem){ var __getOffsetRect=function(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 = box.top + scrollTop - clientTop; var left = box.left + scrollLeft - clientLeft; return { top: Math.round(top), left: Math.round(left) }; }; var __getOffsetSum=function(elem) { var top=0, left=0; while(elem) {top = top + parseInt(elem.offsetTop);left = left + parseInt(elem.offsetLeft);elem = elem.offsetParent ;} return {top: top, left: left}; }; if (elem.getBoundingClientRect) { _get_offset=__getOffsetRect; } else { _get_offset=__getOffsetSum; } __getOffsetRect=__getOffsetSum=null; return _get_offset(elem); }; var fix_event=function(e){ return _fix_event(e); }; var _fix_event=function(e){ var __fix_event_ie=function(e){ e = e || window.event; var html = document.documentElement; var body = document.body; e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0); e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0); if (e.button & 1) { e.which = 1; } else if (e.button & 4) { e.which = 2; } else if (e.button & 2) {e.which = 3;} e.target=e.srcElement; return e; }; var __fix_event_html5=function(e){ return e; }; e = e || window.event; if( e.pageX == null && e.clientX != null ){ _fix_event=__fix_event_ie; }else{ _fix_event=__fix_event_html5; } __fix_event_ie=__fix_event_html5=null; return _fix_event(e); };Добрый день.
Не могу разобраться с клонированием картинок при перетаскивании. Можете направить где копать?
addClass
Какая-то стрёмная замена classList.add()
function insertAfter(parent, node, referenceNode) {parent.insertBefore(node, referenceNode.nextSibling);
}
И где тут проверка, что это не младший сын?
Эти приемы слишком не соответствуют сути прототипно-ориентированного языка.
Почему бы не myObject.addEvent?
как де queryString?
Где демонстрация работы с динамическими элементами?
Да, порой фреймворк использовать не получается (покажите мне такой, в ЛС), но это плохой подход.
ПС: Кину свою мини-библиотеку нужнрых мне порой функций.
Array.prototype.last = function(){ return this[this.length - 1]; } Array.prototype.unique = function(){ var u = {}, a = []; for(var i = 0, l = this.length; i < l; ++i){ if(u.hasOwnProperty(this[i])) { continue; } a.push(this[i]); u[this[i]] = 1; } return a; } Array.prototype.remove = function(i){ this.splice(i, 1); } String.prototype.times = function(n){ var s = ''; for (var i = 0; i < n; i++){ s += this; } return s; } ObjLength = function(obj) { if(typeof(obj) != "object") return null; var n = 0; for(var i in obj){ n++; } return n; } String.prototype.zp = function(n) { return '0'.times(n - this.length) + this; } Number.prototype.zp = function(n) { return this.toString().zp(n); } String.prototype.zt = function(n) { return this + '0'.times(n - this.length); } Number.prototype.zt = function(n) { return this.toString().zt(n); } String.prototype.toInt = function() { return parseInt(this); } String.prototype.toFloat = function() { return parseFloat(this); } String.prototype.toNumber = function() { return parseFloat(this); } Number.prototype.toInt = function() { return parseInt(this); } Number.prototype.toFloat = function() { return parseFloat(this); } Number.prototype.toNumber = function() { return parseFloat(this); } Date.prototype.daysInMonth = function() { return 33 - new Date(this.getFullYear(), this.getMonth(), 33).getDate(); }; HTMLElement.prototype.remove = function(){ if(this.parentNode != null) this.parentNode.removeChild(this); else delete(this); } HTMLElement.prototype.insertAfter = function(elem){ this.parentNode.insertBefore(elem, this.nextSibling); } HTMLElement.prototype.replace = function(elem){ this.parentNode.insertBefore(elem, this.nextSibling); this.remove(); } var webStore = { setItem: function (name, object) { localStorage.setItem(name, JSON.stringify(object)) }, getItem: function (name) { return JSON.parse(localStorage.getItem(name)) }, clear: function (name) { localStorage.clear() } }ПС2: Пользуйтесь jQ, Angular, polymer и все будет в порядке.
onReady() дала течь. Вернулся к windows.onload
onReady(function () { var out = document.getElementById('out'); var n7 = getElementsByClass('n7')[0]; var fff = getComputedStyle(n7); //Выводит ложные данные! out.innerHTML = n7.offsetTop + '<br>'; out.innerHTML += fff.width; });А jQuery использовать мешает высокомерие - мы же крутые JS-разработчики а не х.пойми что )))
Функции полезные, но можно использовать jQuery и разрабатывать на Javascript еще быстрее и эффективнее.