This page has been robot translated, sorry for typos if any. Original content here.

Використання Java скриптів

JavaScript - прототипна-орієнтований сценарний мову програмування. Є діалектом мови ECMAScript.

JavaScript зазвичай використовується як вбудований мова для програмного доступу до об'єктів додатків. Найбільш широке застосування знаходить в браузерах як мова сценаріїв для додання інтерактивності веб-сторінок. Основні архітектурні риси: динамічна типізація, слабка типізація, автоматичне керування пам'яттю, прототипне програмування, функції як об'єкти першого класу. На JavaScript вплинули багато мов, при розробці була мета зробити мову схожим на Java, але при цьому легким для використання непрограмістів. Мовою JavaScript не володіє будь-яка компанія або організація, що відрізняє його від ряду мов програмування, використовуваних в веб-розробці. Назва «JavaScript» є зареєстрованим товарним знаком компанії Oracle Corporation.

10 кращих функцій на JavaScript

Сучасні яваскрипт-фреймворки, звичайно ж, вміють всі ці функції. Але іноді потрібно зробити щось без фреймворку. З різних причин. Для цього і призначений даний збірник корисних функцій.

10) 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.

Існує два варіанти обходу проблеми:

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 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 () { 
  // використовуємо не this, а змінну, що посилається на елемент
  alert (elem) 
 }
 ...

9) onReady ()

Для ініціалізації сторінки історично використовувалося подія 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 () {
  // ...
 })

8) getElementsByClass ()

Спочатку не написана ніким конкретно. Багато розробники писали свої власні версії і нічия не показала себе краще за інших.

Наступна функція використовує вбудований метод 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) 

7) addClass () / removeClass ()

Наступні дві функції додають і видаляють клас 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, "")
 } 

6) toggle ()

Якщо бути чесним, напевно для цієї функції існує більше різних варіантів, ніж було б потрібно.

Цей варіант жодним чином він не претендує на звання універсальної функції-"перемикача", але він виконує основну функціональність показування і спрятиванія.


функція toggle (), слова народні

  function toggle (el) {
  el.style.display = (el.style.display == 'none')?  '': 'None'
 }

Зверніть увагу, в функції немає ні слова про display = 'block', замість цього використовується пусте значення display = ''. Пусте значення означає скидання властивості, тобто властивість повертається до значення, зазначеного в CSS.

Таким чином, якщо значення display для даного елемента, взяте з CSS - none (елемент захований за замовчуванням), то ця функція toggle не працюватиме.

Цей варіант функції toggle гарний і простий, однак цей і деякі інші недоліки роблять його недостатньо універсальним.

5) insertAfter ()

Як і getElementsByClass, цієї функції чомусь немає в стандарті DOM. Можливо, щоб уникнути дублювання функціоналу, тому що insertAfter реалізується за все одним рядком.

  function insertAfter (parent, node, referenceNode) {
  parent.insertBefore (node, referenceNode.nextSibling);
 }

4) inArray ()

Дуже шкода, що це не частина вбудованої функціональності 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
  }

3, 2 і 1) getCookie (), setCookie (), deleteCookie ()

У 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 тільки по захищеному з'єднанню.

Остання, але часто корисна: функція 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.