Javascript.RU

10 лучших функций на JavaScript

Переписанный вариант статьи Дастина Диаза

Если бы существовал универсальный файл common.js, которым пользовались бы все разработчики, вы бы нашли там эти десять (плюс одна бонусная) функций.

UPDATE март 2010: Эта статья была обновлена и переписана, чтобы соответствовать сегодняшнему дню и общему уровню сайта.

Эти функции неоднократно были испытаны и доказали свою полезность всем тем, кто их использовал. Поэтому, без лишних вступлений, вот список из десяти, по моему мнению, величайших пользовательских функций на JavaScript, которые используются в настоящее время.

Современные яваскрипт-фреймворки, конечно же, умеют все эти функции. Но иногда нужно сделать что-то без фреймворка. По разным причинам. Для этого и предназначен данный сборник полезных функций

Несомненно, важнейший инструмент в управлении событиями! Вне зависимости от того, какой версией вы пользуетесь и кем она написана, она делает то, что написано у неё в названии: присоединяет к элементу обработчик события.

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 можно заменить соответствующую строку addEvent на:

elem.attachEvent("on"+evType, function() { fn.apply(elem) })

Это решит проблему с передачей this, но обработчик никак нельзя будет снять, т.к. detachEvent должен вызывать в точности ту функцию, которая была передана attachEvent.

Существует два варианта обхода проблемы:

  1. Возвращать функцию, использованную для назначения обработчика:
    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)
    
  2. Можно не использовать 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
	}
}
classList
Список классов, разделенный пробелами, элементы с которыми нужно искать.
node
Контекст поиска, внутри какого узла искать

Например:

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 })
}

Аргументы:

name
название cookie
value
значение cookie (строка)
props
Объект с дополнительными свойствами для установки cookie:

expires
Время истечения cookie. Интерпретируется по-разному, в зависимости от типа:

  • Если число - количество секунд до истечения.
  • Если объект типа Date - точная дата истечения.
  • Если expires в прошлом, то cookie будет удалено.
  • Если expires отсутствует или равно 0, то cookie будет установлено как сессионное и исчезнет при закрытии браузера.
path
Путь для cookie.
domain
Домен для cookie.
secure
Пересылать cookie только по защищенному соединению.

Она позволяет функции работать одинаково при передаче 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-функций будет столь же полезен вам, сколь он полезен мне.


Автор: 온라인카지노 (не зарегистрирован), дата: 10 августа, 2022 - 07:11
#permalink

While looking for articles on these topics, I came across this article on the site here. As I read your article, I felt like an expert in this field. I have several articles on these topics posted on my site. Could you please visit my homepage? 온라인카지노


Автор: 온라인카지노 (не зарегистрирован), дата: 10 августа, 2022 - 07:12
#permalink

While looking for articles on these topics, I came across this article on the site here. As I read your article, I felt like an expert in this field. I have several articles on these topics posted on my site. Could you please visit my homepage? 온라인카지노
hh


Автор: 바카라게임사이트 (не зарегистрирован), дата: 10 августа, 2022 - 07:12
#permalink

I'm so happy to finally find a post with what I want. 바카라게임사이트 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.


Автор: 바카라게임사이트 (не зарегистрирован), дата: 10 августа, 2022 - 07:13
#permalink

I'm so happy to finally find a post with what I want. 바카라게임사이트 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.


Автор: 카지노사이트추천 (не зарегистрирован), дата: 10 августа, 2022 - 07:25
#permalink

Hello, I am one of the most impressed people in your article. 카지노사이트추천 I'm very curious about how you write such a good article. Are you an expert on this subject? I think so. Thank you again for allowing me to read these posts, and have a nice day today. Thank you.


Автор: 카지노사이트추천 (не зарегистрирован), дата: 15 августа, 2022 - 06:01
#permalink

I'm writing on this topic these days, 카지노사이트추천 , but I have stopped writing because there is no reference material. Then I accidentally found your article. I can refer to a variety of materials, so I think the work I was preparing will work! Thank you for your efforts.


Автор: 바카라사이트 (не зарегистрирован), дата: 16 августа, 2022 - 09:29
#permalink

I have been looking for articles on these topics for a long time. 바카라사이트 I don't know how grateful you are for posting on this topic. Thank you for the numerous articles on this site, I will subscribe to those links in my bookmarks and visit them often. Have a nice day.


Автор: 바카라사이트 (не зарегистрирован), дата: 16 августа, 2022 - 09:31
#permalink

I have been looking for articles on these topics for a long time. 바카라사이트 I don't know how grateful you are for posting on this topic. Thank you for the numerous articles on this site, I will subscribe to those links in my bookmarks and visit them often. Have a nice day.


Автор: 카지노게임사이트 (не зарегистрирован), дата: 17 августа, 2022 - 10:45
#permalink

When I read your article on this topic, the first thought seems profound and difficult. There is also a bulletin board for discussion of articles and photos similar to this topic on my site, but I would like to visit once when I have time to discuss this topic. 카지노게임사이트


Автор: 온라인카지노 (не зарегистрирован), дата: 20 августа, 2022 - 11:26
#permalink

I finally found what I was looking for! I'm so happy. 온라인카지노 Your article is what I've been looking for for a long time. I'm happy to find you like this. Could you visit my website if you have time? I'm sure you'll find a post of interest that you'll find interesting.


Автор: keonhacai (не зарегистрирован), дата: 22 августа, 2022 - 11:58
#permalink

The assignment submission period was over and I was nervous, keonhacai and I am very happy to see your post just in time and it was a great help. Thank you ! Leave your blog address below. Please visit me anytime.


Автор: 카지노사이트 (не зарегистрирован), дата: 22 августа, 2022 - 12:06
#permalink

Hello, I'm happy to see some great articles on your site. Would you like to come to my site later? My site also has posts, comments and communities similar to yours. Please visit and take a look 카지노사이트
dgghd


Автор: 카지노게임사이트 (не зарегистрирован), дата: 24 августа, 2022 - 06:13
#permalink

I was impressed by your writing. Your writing is impressive. I want to write like you.카지노게임사이트 I hope you can read my post and let me know what to modify. My writing is in I would like you to visit my blog.


Автор: 카지노사이트추천 (не зарегистрирован), дата: 24 августа, 2022 - 07:12
#permalink

That's a great article! The neatly organized content is good to see. Can I quote a blog and write it on my blog? My blog has a variety of communities including these articles. Would you like to visit me later? 카지노사이트추천


Автор: 온라인카지노사이트 (не зарегистрирован), дата: 24 августа, 2022 - 10:41
#permalink

I accidentally searched and visited your site. I still saw several posts during my visit, but the text was neat and readable. I will quote this post and post it on my blog. Would you like to visit my blog later? 온라인카지노사이트
zfdxdfg


Автор: 온라인바카라 (не зарегистрирован), дата: 24 августа, 2022 - 11:47
#permalink

Hello, I read the post well. 온라인바카라 It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once


Автор: 온라인카지노 (не зарегистрирован), дата: 26 августа, 2022 - 10:35
#permalink

I've been looking for photos and articles on this topic over the past few days due to a school assignment, 온라인카지노 and I'm really happy to find a post with the material I was looking for! I bookmark and will come often! Thanks


Автор: 카지노게임사이트 (не зарегистрирован), дата: 27 августа, 2022 - 12:50
#permalink

When I read your article on this topic, the first thought seems profound and difficult. There is also a bulletin board for discussion of articles and photos similar to this topic on my site, but I would like to visit once when I have time to discuss this topic. 카지노게임사이트


Автор: 다낭 밤문화 (не зарегистрирован), дата: 29 августа, 2022 - 12:58
#permalink

After study a handful of the blog posts with your internet site now, we truly like your technique for blogging. I bookmarked it to my bookmark internet site list and are checking back soon. 다낭 밤문화


Автор: 바카라게임사이트 (не зарегистрирован), дата: 30 августа, 2022 - 10:02
#permalink

I'm so happy to finally find a post with what I want. 바카라게임사이트 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.


Автор: 바카라사이트 (не зарегистрирован), дата: 30 августа, 2022 - 10:45
#permalink

This is the perfect post.바카라사이트 It helped me a lot. If you have time, I hope you come to my site and share your opinions. Have a nice day.


Автор: Гость카지노게임사이트 (не зарегистрирован), дата: 5 сентября, 2022 - 12:13
#permalink

When I read your article on this topic, the first thought seems profound and difficult. There is also a bulletin board for discussion of articles and photos similar to this topic on my site, but I would like to visit once when I have time to discuss this topic. 카지노게임사이트


Автор: 카지노게임사이트 (не зарегистрирован), дата: 10 сентября, 2022 - 10:03
#permalink

I was impressed by your writing. Your writing is impressive. I want to write like you.카지노게임사이트 I hope you can read my post and let me know what to modify. My writing is in I would like you to visit my blog.


Автор: 바카라사이트 (не зарегистрирован), дата: 11 сентября, 2022 - 07:19
#permalink

This is the perfect post.바카라사이트 It helped me a lot. If you have time, I hope you come to my site and share your opinions. Have a nice day.
xdgsxs


Автор: 카지노사이트추천 (не зарегистрирован), дата: 15 сентября, 2022 - 10:28
#permalink

What an interesting story! I'm glad I finally found what I was looking for 카지노사이트추천.


Автор: 카지노사이트추천 (не зарегистрирован), дата: 15 сентября, 2022 - 10:29
#permalink

What an interesting story! I'm glad I finally found what I was looking for 카지노사이트추천.


Автор: 카지노사이트추천 (не зарегистрирован), дата: 15 сентября, 2022 - 10:29
#permalink

What an interesting story! I'm glad I finally found what I was looking for 카지노사이트추천.


Автор: 카지노사이트추천 (не зарегистрирован), дата: 15 сентября, 2022 - 10:30
#permalink

What an interesting story! I'm glad I finally found what I was looking for 카지노사이트추천.


Автор: 카지노사이트추천 (не зарегистрирован), дата: 15 сентября, 2022 - 10:30
#permalink

What an interesting story! I'm glad I finally found what I was looking for 카지노사이트추천.


Автор: 바카라사이트추천 (не зарегистрирован), дата: 16 сентября, 2022 - 09:45
#permalink

That's a really impressive new idea! 바카라사이트추천 It touched me a lot. I would love to hear your opinion on my site. Please come to the site I run once and leave a comment. Thank you.


Автор: 바카라사이트추천 (не зарегистрирован), дата: 16 сентября, 2022 - 10:10
#permalink

Your article was very impressive to me. It was unexpected information,but after reading it like this 바카라사이트추천, I found it very interesting.


Автор: 온라인카지노사이트 (не зарегистрирован), дата: 17 сентября, 2022 - 12:22
#permalink

Really no matter if someone doesn't be aware of after that its up to other users that they will help, so here it takes place 온라인카지노사이트.


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 23 сентября, 2022 - 06:04
#permalink

Your ideas inspired me very much. 온라인바카라사이트 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thank you.


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 23 сентября, 2022 - 06:05
#permalink

Your ideas inspired me very much. 온라인바카라사이트 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thank you.


Автор: 온라인바카라 (не зарегистрирован), дата: 26 сентября, 2022 - 10:03
#permalink

Hello, I read the post well. 온라인바카라 It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once


Автор: 카지노게임사이트 (не зарегистрирован), дата: 28 сентября, 2022 - 11:24
#permalink

I was impressed by your writing. Your writing is impressive. I want to write like you.카지노게임사이트 I hope you can read my post and let me know what to modify. My writing is in I would like you to visit my blog.


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 30 сентября, 2022 - 09:25
#permalink

We stumbled over here by a different website and thought I might check things out. I like what I see so now i am following you. Look forward to finding out about your web page again. 온라인바카라사이트
fhggggyy


Автор: 카지노게임사이트 (не зарегистрирован), дата: 1 октября, 2022 - 09:40
#permalink

It is my first visit to your blog, and I am very impressed with the articles that you serve. Give adequate knowledge for me. Thank you for sharing useful material. I will be back for the more great post. 카지노게임사이트 But by chance looking at your post solved my problem! I will leave my blog, so when would you like to visit it?!


Автор: 온라인바카라 (не зарегистрирован), дата: 1 октября, 2022 - 09:43
#permalink

I’m not sure exactly why but this weblog is loading incredibly slow for me. Is anyone else having this problem or is it a problem on my end? I’ll check back later on and see if the problem still exists. 온라인바카라


Автор: 온라인바카라 (не зарегистрирован), дата: 1 октября, 2022 - 09:44
#permalink

I’m not sure exactly why but this weblog is loading incredibly slow for me. Is anyone else having this problem or is it a problem on my end? I’ll check back later on and see if the problem still exists. 온라인바카라


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 1 октября, 2022 - 09:46
#permalink

We stumbled over here by a different website and thought I might check things out. I like what I see so now i am following you. Look forward to finding out about your web page again. 온라인바카라사이트


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
1 + 0 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum