В этой лекции рассматриваются основы использования
Лекция имеет следующее содержание:
Легче всего начать с управления кодом HTML, который уже имеется, скрывая или отображая элементы, которые находятся на странице. Для этого можно использовать display является ключом для отображения и скрытия элемента: если задать его как display:none;, элемент будет скрыт. Представьте параграф следующего вида:
<p id="mypara" style="display: none">I am a paragraph</p>
Этот параграф будет невидим на странице. display: none для элемента и удалять его.
var el = document.getElementById(" выдает ссылку на элемент с id=". Когда ссылка на элемент получена, можно с помощью атрибута style изменить примененный к нему код CSS. Например, параграф "mypara" выше в настоящий момент скрыт (в нем задано display: none ). Чтобы показать его, задайте атрибут display как block:
var el = document.getElementById('mypara');
el.style.display = 'block';
И вот, параграф появился. Задание CSS на элементе через атрибут style делает то же самое, что задание его в атрибуте style в самом HTML, поэтому код выше, задающий el.style.display = 'block', добивается того же эффекта, что и размещение style="display: block" прямо в коде HTML. За исключением того, что он является динамическим. Скрытие любого элемента также просто:
var el = document.getElementById('mypara');
el.style.display = 'none';
С теорией все хорошо, но здесь может быть полезен более практический пример. Представьте множество вкладок, где щелчок на самой вкладке показывает ее и скрывает все остальные.
Вот пример множества вкладок:
<ol class="tablinks"> <li><a href="#tab1">Tab 1</a></li> <li><a href="#tab2">Tab 2</a></li> <li><a href="#tab3">Tab 3</a></li> </ol> <div class="tab" id="tab1">This is tab 1</div> <div class="tab" id="tab2">This is tab 2</div> <div class="tab" id="tab3">This is tab 3</div>
В разделе head файла примера (см. действующий пример tabs.html по адресу http://dev.opera.com/articles/view/creating-and-modifying-html/tabs.html), вы найдете следующий код CSS и
<style type="text/css">
ol.tablinks {
margin: 0; padding: 0;
}
ol.tablinks li {
float: left;
border: 2px solid red;
border-width: 2px 2px 0 2px;
background: #eee;
list-style: none;
padding: 5px;
margin: 0;
}
ol.tablinks li a {
text-decoration: none;
color: black;
}
div.tab {
clear: left;
border: 2px solid red;
border-width: 1px 2px 2px 2px;
}
</style>
<script type="text/javascript">
var tabify = {
hasClass: function(el,c) {
return el.className.match(new RegExp('(\\s|^)'+c+'(\\s|$)'));
},
addClass: function(el,c) {
if (!tabify.hasClass(el,c)) el.className += " " + c;
},
removeClass: function(el,c) {
if (tabify.hasClass(el,c)) {
el.className=el.className.replace(new RegExp('(\\s|^)'+c+'(\\s|$)'),' ');
}
},
hideAllTabs: function(ol) {
var links = ol.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
tabify.setTabFromLink(links[i], "none");
}
},
setTabFromLink: function(link, style) {
var dest = link.href.match(/#(.*)$/)[1];
document.getElementById(dest).style.display = style;
if (style == "none") {
tabify.removeClass(link, "active");
} else {
tabify.addClass(link, "active");
}
},
addEvent: function(obj, type, fn) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
obj.attachEvent('on'+type, obj[type+fn] );
} else {
obj.addEventListener( type, fn, false );
}
},
init: function() {
var ols = document.getElementsByTagName("ol");
for (var i=0; i<ols.length; i++) {
var ol = ols[i];
if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
tabify.addEvent(ol, "click", function(e) {
var target = window.event ? window.event.srcElement : e.target;
if (target.nodeName.toLowerCase() === "a") {
tabify.hideAllTabs(e.target.parentNode.parentNode);
tabify.setTabFromLink(e.target, "block");
if (e) e.preventDefault();
if (window.event) window.event.returnValue = false;
return false;
}
}, true);
tabify.hideAllTabs(ol);
tabify.setTabFromLink(ol.getElementsByTagName("a")[0], "block");
}
}
};
tabify.addEvent(window, "load", tabify.init);
</script>
Каждая вкладка является ссылкой. Каждая ссылка содержит обработчик onclick. Этот обработчик div (используя подход display: none, показанный выше), а затем показывает div, соответствующий этой вкладке, задавая style этого div как display: block.
Можно видеть, что код HTML задан таким образом, чтобы все работало даже в отсутствие сценария, хотя щелчок на ссылке не показывает и не скрывает вкладку, ссылки переходят на соответствующую вкладку, поэтому страница по-прежнему действует корректно, и имеет семантический смысл даже в браузерах без
Весь код
отображение вкладки, соответствующей определенной ссылке, с помощью двух строчек кода
var dest = link.href.match(/#(.*)$/)[1]; document.getElementById(dest).style.display = "block";
Ссылки, если вы помните, выглядят следующим образом <a href="#tab1">Tab 1</a>, и поэтому первая строка использует регулярное выражение (см. Примечание ниже) для извлечения той части ссылки, которая появится после символа # ; в данном примере это будет строка tab1. Эта часть ссылки будет такой же как ID соответствующего div (потому что, как упоминалось, страница создается таким образом, чтобы иметь семантический смысл, поэтому "вкладка" ссылается на свой div ). Затем мы извлекаем ссылку на этот div с помощью document.getElementById, и задаем style.display как block, как было показано ранее.
Регулярные выражения являются разновидностью мини-языка-программирования, созданного для решения проблемы "'abc123def' какие имеются цифры между 'c' и 'd'?" Они являются очень мощным инструментом, но также достаточно сложным. Ниже находится описание, для чего предназначены регулярные выражения; пока, однако, можете принять это на веру, и вернуться к описанию позже.
Используемое в этом примере регулярное выражение имеет вид /#(.*)$/. Каждый символ регулярного выражения создан для представления последовательности символов в некоторой целевой строке, идея состоит в том, чтобы выразить по частям, как составлена целевая строка.
/ … / - косая черта указывает начало и конец регулярного выражения, также как двойные или одиночные кавычки используются для "строки"# - хэш-символ (#) фактически означает "совпадает с хэш-символом"( … ) - скобки означают "здесь находится часть строки, которая понадобится позже".* - означает "любые символы"; на самом деле это точка (.), означающая "один любой символ", за которой следует звездочка (*), означающая "повторить любое количество раз"$ - знак доллара означает "конец строки"Поэтому наше регулярное выражение описывает "подходящий шаблон" строки, состоящей из "хэша, за которым следуют любые символы". link.href является местом назначения рассматриваемой ссылки (например, #tab1, и так как эта строка подходит под описание "хэш, за которым следуют любые символы"), то "подходящий шаблон" применим к этой строке.
link.href.match(our_regexp), вернет, поэтому, результат true, а не false ; в действительности будет возвращен массив из двух элементов ["#tab1", "tab1"]. Первый является текстом, который соответствует всему регулярному выражению, а второй является текстом, соответствующим символам в кавычках, поэтому скобки здесь и присутствуют - чтобы пометить эту часть строки как "этот фрагмент нас интересует". tab1 является строкой, которая нам требуется, поэтому мы можем извлечь ее из возвращаемого массива (это второй элемент, поэтому его извлекает индекс [1] - массивы начинают нумерацию с нуля.)
Как упоминалось выше, имеется две части кода: часть, которая фактически выполняет работу, и часть, которая соединяет ее с HTML. Соединение работающего кода с HTML осуществляется с помощью
Выполнение кода в ответ на addEventListener, и с помощью функции attachEvent в Internet Explorer. Здесь мы создаем функцию "оболочку", которая делает правильный выбор, в зависимости от того, что поддерживается:
addEvent: function(obj, type, fn) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
obj.attachEvent('on'+type, obj[type+fn] );
} else {
obj.addEventListener( type, fn, false );
}
}
(Не беспокойтесь слишком много о том, как это работает; примите пока просто на веру - вы поймете код лучше, когда станете более опытным пользователем obj, type, и fn, которые являются соответственно "объектом, порождающим tabify.init ; функция tabify.init затем позаботится о присоединении click для каждой вкладки.
addEvent(window, "load", tabify.init);
Как можно видеть из структуры кода HTML выше, множество вкладок в действительности представляется как упорядоченный список с class="tablinks". Поэтому функция tabify.init должна сделать следующее:
<ol> на странице с классом tablinksclick каждого элемента <ol> некоторый код, который делает следующее:Функция init, которая все это делает, выглядит следующим образом:
init: function() {
var ols = document.getElementsByTagName("ol");
for (var i=0; i<ols.length; i++) {
var ol = ols[i];
if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
tabify.addEvent(ol, "click", function(e) {
var target = window.event ? window.event.srcElement : e.target;
if (target.nodeName.toLowerCase() === "a") {
tabify.hideAllTabs(e.target.parentNode.parentNode);
tabify.setTabFromLink(e.target, "block");
if (e) e.preventDefault();
if (window.event) window.event.returnValue = false;
return false;
}
}, true);
tabify.hideAllTabs(ol);
tabify.setTabFromLink(ol.getElementsByTagName("a")[0], "block");
}
}
Давайте пройдем по этой функции шаг за шагом, просматривая по очереди, что делает каждая часть:
var ols = document.getElementsByTagName("ol");
for (var i=0; i<ols.length; i++) {
var ol = ols[i];
if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
}
Этот фрагмент находит все элементы <ol> на странице с классом tablinks - и затем извлекает список всех <ol> и для каждого проверяет "если этот элемент не имеет класс 'tablinks', пропустить его". (Проверка класса делается с помощью регулярного выражения; continue означает "пропустить этот элемент и перейти к следующему".)
tabify.addEvent(ol, "click", function(e) {
...
});
Этот фрагмент присоединяет некоторый код к click каждого <ol>.
var target = window.event ? window.event.srcElement : e.target;
Этот фрагмент точно определяет, на какой ссылке вкладки щелкнул пользователь …
tabify.setTabFromLink(e.target, "block");
…затем этот фрагмент, показывает эту единственную вкладку …
tabify.hideAllTabs(e.target.parentNode.parentNode);
… и наконец, эта строка скрывает все другие вкладки.
Функции setTabFromLink и hideAllTabs также присутствуют в коде; они используют показанные выше методы для скрытия или отображения вкладки. Посмотрите на то, как они работают - они являются отдельными функциями, так как часто полезно иметь блок кода, который вызывается более чем из одного места, и поместить его в отдельную функцию. (Это облегчает понимание кода и позволяет повторно использовать его в нескольких местах. Этот подход часто называют "разбиением" или "факторизацией" кода в функцию.)
В ней выполняется также небольшая "дополнительная" работа, которая демонстрирует добавление и удаление атрибутов. Функция setTabFromLink не только отображает соответствующую вкладку, но задает также class="active" на активной вкладке. Она делает это с помощью трех hasClass, removeClass, и addClass. Таким же образом, как мы скрыли все вкладки, а затем показали активную, мы используем removeClass для удаления "active" из className всех ссылок на вкладки, а затем addClass, чтобы добавить "active" в одну ссылку на вкладку, которая действительно активна. Простое добавление класса в ссылку может показаться бессмысленным - в конечном счете классы невидимы - но это зацепка для стилевого оформления.
Мы можем (и должны) делать так, чтобы ссылки с class="active" появлялись с другим оформлением, добавляя код CSS:
ol.tablinks li a {
background-color: red;
}
ol.tablinks li a.active {
background-color: white;
}
Поэтому теперь "активная" вкладка выводится белой, в то время как другие вкладки будут красными. Использование
Однако сценарии для <a href="http://opera.com"> A web browser </a> будет выводиться как <a href="http://opera.com">A web browser</a> [opera.com]. (Это было сделано, чтобы исключить использование фальшивых ссылок, направляющих пользователя в нежелательное место.) Добавление этого небольшого кода HTML, выводящего домен места назначения каждой ссылки на странице, легко делается с помощью
Создание новых элементов HTML делается с помощью функции ) содержащую действующий пример). Код HTML примера выглядит следующим образом:
<p id="start">This is some text that has <a href="http://www.w3.org/TR/html4/struct/links.html">links</a> in it to various places, including <a href="http://www.opera.com">Opera</a>, <a href="http://www.bbc.co.uk/">the BBC</a> and an internal link to <a href="#start">the beginning of this section</a>. All the external links should have <span>[domain]</span> after them.</p>
Код
<script type="text/javascript">
var linksuffix = {
addEvent: function(obj, type, fn) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
obj.attachEvent('on'+type, obj[type+fn] );
} else {
obj.addEventListener( type, fn, false );
}
},
init: function() {
var links = document.getElementById("linksuffixtext").getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
var matches = links[i].href.match(/^http:\/\/(.*?)\//);
if (matches) {
var linkdomain = matches[1];
var span = document.createElement("span");
var spantext = document.createTextNode(" ["+linkdomain+"]");
span.appendChild(spantext);
links[i].parentNode.insertBefore(span, links[i].nextSibling);
}
}
}
};
linksuffix.addEvent(window, "load", linksuffix.init);
</script>
Часть сценария, которая выполняет здесь работу, имеет следующий вид:
var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
var matches = links[i].href.match(/^http:\/\/(.*?)\//);
if (matches) {
var linkdomain = matches[1];
var span = document.createElement("span");
var spantext = document.createTextNode(" ["+linkdomain+"]");
span.appendChild(spantext);
links[i].parentNode.insertBefore(span, links[i].nextSibling);
}
}
Этот код разбивается следующим образом:
var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
...
}
Сначала он находит все ссылки ( getElementsByTagName("a") ) в документе
var matches = links[i].href.match(/^http:\/\/(.*?)\//);
if (matches) {
...
}
Эта строка использует регулярное выражение на каждой ссылке, чтобы определить, что место назначение начинается с http://что-то/. Если это так …
var linkdomain = matches[1];
var span = document.createElement("span");
var spantext = document.createTextNode(" ["+linkdomain+"]");
span.appendChild(spantext);
… следующая часть сначала получает "домен ссылки", часть www.opera.com ссылки. Затем с помощью document.createElement создается элемент <span>. Затем создается "textNode" ("текстовыйУзел"). В то время как сами элементы HTML создаются с помощью document.createElement, весь текст в документе HTML фактически содержится в "textNode", и их необходимо создать отдельно. Нет необходимости беспокоиться об этом (или даже знать об этом) при написании реального HTML, но нужно знать об этом при создании элементов с помощью сценария appendChild элемента <span>, чтобы поместить textNode внутрь span.
links[i].parentNode.insertBefore(span, links[i].nextSibling);
Эта строка добавляет span в документ. В этом месте span является ссылкой на элемент HTML, который выглядит следующим образом:
<span> [example.com]</span>
Этот элемент, однако, не является частью документа. Он не является пока частью никакого документа, он просто находится в некоторой неопределенности. Добавление элемента в документ можно сделать одним из двух способов: используя appendChild как выше, или используя insertBefore. Функция appendChild добавляет наш элемент в конце существующего элемента (именно поэтому она называет append ). Так как мы хотим добавить ее в середине существующего элемента, нам нужно использовать insertBefore. Вспомните, что наш текущий фрагмент кода HTML выглядит примерно следующим образом:
<p>... text that has <a href="http://www.w3.org/TR/html4/struct/links.html">links</a> in it to ...
Это приводит к дереву
(рис 9.1) Дерево DOM tree перед добавлением элемента span после ссылкиМы хотим вставить новый span между <a> и textNode "in it to", чтобы он появлялся после <a>. Это приведет к дереву
(рис 9.2) Дерево DOM после добавления элемента spanили, более просто, коду HTML следующего вида
<p>... text which has <a href="http://www.w3.org/TR/html4/struct/links.html">links</a> <span> [domain]</span> in it to ...
Здесь было бы удобно иметь возможность сказать: "вставьте новый span после ссылки". К сожалению функции insertAfter нет. Вместо этого мы должны вставлять его перед элементом после ссылки (несколько запутано, но подумайте об этом, и все встанет на место). Краткая запись для выражения "вещь после элемента помеченного el " будет el.nextSibling. Функция insertBefore должна вызываться на элементе, в который происходит вставка, т.е. на предке <p> ссылки, легко доступной с помощью link.parentNode. Поэтому весь вызов, как выше, будет
links[i].parentNode.insertBefore(span, links[i].nextSibling);
То есть, находим предка ( <p> ) ссылки, которая обрабатывается ( links[i] ) в данный момент, и вставляем созданный элемент span перед элементом после ссылки ( links[i].nextSibling ). Использование HTML в виде дерева
HTML предоставляет структуру страниц, а CSS предоставляет описание внешнего вида. А
Можно время от времени изменять внешний вид страниц и их работу, на основе того, что делают пользователи. Следующий шаг: от хорошо-продуманной и хорошо-структурированной информации к данным, которые изменяются в зависимости от требований пользователя. Можно показывать и скрывать элементы, изменять
display CSS элемента, чтобы скрыть элемент?appendChild и insertBefore?addClass, а не просто соединяем имя нового класса с атрибутом className существующего элемента?document.getElementById("marker").nextSibling?<p>This is a <strong>block of HTML with <span id="marker">various markup</span> in it</strong>.</p>

Стюарт Лэнгридж вполне возможно единственный человек в мире, который имеет степень бакалавра по программированию и философии. Когда он не занят с компьютерами, он программист на
В этой лекции рассматриваются основы использования
Лекция имеет следующее содержание:
Легче всего начать с управления кодом HTML, который уже имеется, скрывая или отображая элементы, которые находятся на странице. Для этого можно использовать display является ключом для отображения и скрытия элемента: если задать его как display:none;, элемент будет скрыт. Представьте параграф следующего вида:
<p id="mypara" style="display: none">I am a paragraph</p>
Этот параграф будет невидим на странице. display: none для элемента и удалять его.
var el = document.getElementById(" выдает ссылку на элемент с id=". Когда ссылка на элемент получена, можно с помощью атрибута style изменить примененный к нему код CSS. Например, параграф "mypara" выше в настоящий момент скрыт (в нем задано display: none ). Чтобы показать его, задайте атрибут display как block:
var el = document.getElementById('mypara');
el.style.display = 'block';
И вот, параграф появился. Задание CSS на элементе через атрибут style делает то же самое, что задание его в атрибуте style в самом HTML, поэтому код выше, задающий el.style.display = 'block', добивается того же эффекта, что и размещение style="display: block" прямо в коде HTML. За исключением того, что он является динамическим. Скрытие любого элемента также просто:
var el = document.getElementById('mypara');
el.style.display = 'none';
С теорией все хорошо, но здесь может быть полезен более практический пример. Представьте множество вкладок, где щелчок на самой вкладке показывает ее и скрывает все остальные.
Вот пример множества вкладок:
<ol class="tablinks"> <li><a href="#tab1">Tab 1</a></li> <li><a href="#tab2">Tab 2</a></li> <li><a href="#tab3">Tab 3</a></li> </ol> <div class="tab" id="tab1">This is tab 1</div> <div class="tab" id="tab2">This is tab 2</div> <div class="tab" id="tab3">This is tab 3</div>
В разделе head файла примера (см. действующий пример tabs.html по адресу http://dev.opera.com/articles/view/creating-and-modifying-html/tabs.html), вы найдете следующий код CSS и
<style type="text/css">
ol.tablinks {
margin: 0; padding: 0;
}
ol.tablinks li {
float: left;
border: 2px solid red;
border-width: 2px 2px 0 2px;
background: #eee;
list-style: none;
padding: 5px;
margin: 0;
}
ol.tablinks li a {
text-decoration: none;
color: black;
}
div.tab {
clear: left;
border: 2px solid red;
border-width: 1px 2px 2px 2px;
}
</style>
<script type="text/javascript">
var tabify = {
hasClass: function(el,c) {
return el.className.match(new RegExp('(\\s|^)'+c+'(\\s|$)'));
},
addClass: function(el,c) {
if (!tabify.hasClass(el,c)) el.className += " " + c;
},
removeClass: function(el,c) {
if (tabify.hasClass(el,c)) {
el.className=el.className.replace(new RegExp('(\\s|^)'+c+'(\\s|$)'),' ');
}
},
hideAllTabs: function(ol) {
var links = ol.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
tabify.setTabFromLink(links[i], "none");
}
},
setTabFromLink: function(link, style) {
var dest = link.href.match(/#(.*)$/)[1];
document.getElementById(dest).style.display = style;
if (style == "none") {
tabify.removeClass(link, "active");
} else {
tabify.addClass(link, "active");
}
},
addEvent: function(obj, type, fn) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
obj.attachEvent('on'+type, obj[type+fn] );
} else {
obj.addEventListener( type, fn, false );
}
},
init: function() {
var ols = document.getElementsByTagName("ol");
for (var i=0; i<ols.length; i++) {
var ol = ols[i];
if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
tabify.addEvent(ol, "click", function(e) {
var target = window.event ? window.event.srcElement : e.target;
if (target.nodeName.toLowerCase() === "a") {
tabify.hideAllTabs(e.target.parentNode.parentNode);
tabify.setTabFromLink(e.target, "block");
if (e) e.preventDefault();
if (window.event) window.event.returnValue = false;
return false;
}
}, true);
tabify.hideAllTabs(ol);
tabify.setTabFromLink(ol.getElementsByTagName("a")[0], "block");
}
}
};
tabify.addEvent(window, "load", tabify.init);
</script>
Каждая вкладка является ссылкой. Каждая ссылка содержит обработчик onclick. Этот обработчик div (используя подход display: none, показанный выше), а затем показывает div, соответствующий этой вкладке, задавая style этого div как display: block.
Можно видеть, что код HTML задан таким образом, чтобы все работало даже в отсутствие сценария, хотя щелчок на ссылке не показывает и не скрывает вкладку, ссылки переходят на соответствующую вкладку, поэтому страница по-прежнему действует корректно, и имеет семантический смысл даже в браузерах без
Весь код
отображение вкладки, соответствующей определенной ссылке, с помощью двух строчек кода
var dest = link.href.match(/#(.*)$/)[1]; document.getElementById(dest).style.display = "block";
Ссылки, если вы помните, выглядят следующим образом <a href="#tab1">Tab 1</a>, и поэтому первая строка использует регулярное выражение (см. Примечание ниже) для извлечения той части ссылки, которая появится после символа # ; в данном примере это будет строка tab1. Эта часть ссылки будет такой же как ID соответствующего div (потому что, как упоминалось, страница создается таким образом, чтобы иметь семантический смысл, поэтому "вкладка" ссылается на свой div ). Затем мы извлекаем ссылку на этот div с помощью document.getElementById, и задаем style.display как block, как было показано ранее.
Регулярные выражения являются разновидностью мини-языка-программирования, созданного для решения проблемы "'abc123def' какие имеются цифры между 'c' и 'd'?" Они являются очень мощным инструментом, но также достаточно сложным. Ниже находится описание, для чего предназначены регулярные выражения; пока, однако, можете принять это на веру, и вернуться к описанию позже.
Используемое в этом примере регулярное выражение имеет вид /#(.*)$/. Каждый символ регулярного выражения создан для представления последовательности символов в некоторой целевой строке, идея состоит в том, чтобы выразить по частям, как составлена целевая строка.
/ … / - косая черта указывает начало и конец регулярного выражения, также как двойные или одиночные кавычки используются для "строки"# - хэш-символ (#) фактически означает "совпадает с хэш-символом"( … ) - скобки означают "здесь находится часть строки, которая понадобится позже".* - означает "любые символы"; на самом деле это точка (.), означающая "один любой символ", за которой следует звездочка (*), означающая "повторить любое количество раз"$ - знак доллара означает "конец строки"Поэтому наше регулярное выражение описывает "подходящий шаблон" строки, состоящей из "хэша, за которым следуют любые символы". link.href является местом назначения рассматриваемой ссылки (например, #tab1, и так как эта строка подходит под описание "хэш, за которым следуют любые символы"), то "подходящий шаблон" применим к этой строке.
link.href.match(our_regexp), вернет, поэтому, результат true, а не false ; в действительности будет возвращен массив из двух элементов ["#tab1", "tab1"]. Первый является текстом, который соответствует всему регулярному выражению, а второй является текстом, соответствующим символам в кавычках, поэтому скобки здесь и присутствуют - чтобы пометить эту часть строки как "этот фрагмент нас интересует". tab1 является строкой, которая нам требуется, поэтому мы можем извлечь ее из возвращаемого массива (это второй элемент, поэтому его извлекает индекс [1] - массивы начинают нумерацию с нуля.)
Как упоминалось выше, имеется две части кода: часть, которая фактически выполняет работу, и часть, которая соединяет ее с HTML. Соединение работающего кода с HTML осуществляется с помощью
Выполнение кода в ответ на addEventListener, и с помощью функции attachEvent в Internet Explorer. Здесь мы создаем функцию "оболочку", которая делает правильный выбор, в зависимости от того, что поддерживается:
addEvent: function(obj, type, fn) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
obj.attachEvent('on'+type, obj[type+fn] );
} else {
obj.addEventListener( type, fn, false );
}
}
(Не беспокойтесь слишком много о том, как это работает; примите пока просто на веру - вы поймете код лучше, когда станете более опытным пользователем obj, type, и fn, которые являются соответственно "объектом, порождающим tabify.init ; функция tabify.init затем позаботится о присоединении click для каждой вкладки.
addEvent(window, "load", tabify.init);
Как можно видеть из структуры кода HTML выше, множество вкладок в действительности представляется как упорядоченный список с class="tablinks". Поэтому функция tabify.init должна сделать следующее:
<ol> на странице с классом tablinksclick каждого элемента <ol> некоторый код, который делает следующее:Функция init, которая все это делает, выглядит следующим образом:
init: function() {
var ols = document.getElementsByTagName("ol");
for (var i=0; i<ols.length; i++) {
var ol = ols[i];
if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
tabify.addEvent(ol, "click", function(e) {
var target = window.event ? window.event.srcElement : e.target;
if (target.nodeName.toLowerCase() === "a") {
tabify.hideAllTabs(e.target.parentNode.parentNode);
tabify.setTabFromLink(e.target, "block");
if (e) e.preventDefault();
if (window.event) window.event.returnValue = false;
return false;
}
}, true);
tabify.hideAllTabs(ol);
tabify.setTabFromLink(ol.getElementsByTagName("a")[0], "block");
}
}
Давайте пройдем по этой функции шаг за шагом, просматривая по очереди, что делает каждая часть:
var ols = document.getElementsByTagName("ol");
for (var i=0; i<ols.length; i++) {
var ol = ols[i];
if (!/(^|\s)tablinks(\s|$)/.test(ol.className)) { continue; }
}
Этот фрагмент находит все элементы <ol> на странице с классом tablinks - и затем извлекает список всех <ol> и для каждого проверяет "если этот элемент не имеет класс 'tablinks', пропустить его". (Проверка класса делается с помощью регулярного выражения; continue означает "пропустить этот элемент и перейти к следующему".)
tabify.addEvent(ol, "click", function(e) {
...
});
Этот фрагмент присоединяет некоторый код к click каждого <ol>.
var target = window.event ? window.event.srcElement : e.target;
Этот фрагмент точно определяет, на какой ссылке вкладки щелкнул пользователь …
tabify.setTabFromLink(e.target, "block");
…затем этот фрагмент, показывает эту единственную вкладку …
tabify.hideAllTabs(e.target.parentNode.parentNode);
… и наконец, эта строка скрывает все другие вкладки.
Функции setTabFromLink и hideAllTabs также присутствуют в коде; они используют показанные выше методы для скрытия или отображения вкладки. Посмотрите на то, как они работают - они являются отдельными функциями, так как часто полезно иметь блок кода, который вызывается более чем из одного места, и поместить его в отдельную функцию. (Это облегчает понимание кода и позволяет повторно использовать его в нескольких местах. Этот подход часто называют "разбиением" или "факторизацией" кода в функцию.)
В ней выполняется также небольшая "дополнительная" работа, которая демонстрирует добавление и удаление атрибутов. Функция setTabFromLink не только отображает соответствующую вкладку, но задает также class="active" на активной вкладке. Она делает это с помощью трех hasClass, removeClass, и addClass. Таким же образом, как мы скрыли все вкладки, а затем показали активную, мы используем removeClass для удаления "active" из className всех ссылок на вкладки, а затем addClass, чтобы добавить "active" в одну ссылку на вкладку, которая действительно активна. Простое добавление класса в ссылку может показаться бессмысленным - в конечном счете классы невидимы - но это зацепка для стилевого оформления.
Мы можем (и должны) делать так, чтобы ссылки с class="active" появлялись с другим оформлением, добавляя код CSS:
ol.tablinks li a {
background-color: red;
}
ol.tablinks li a.active {
background-color: white;
}
Поэтому теперь "активная" вкладка выводится белой, в то время как другие вкладки будут красными. Использование
Однако сценарии для <a href="http://opera.com"> A web browser </a> будет выводиться как <a href="http://opera.com">A web browser</a> [opera.com]. (Это было сделано, чтобы исключить использование фальшивых ссылок, направляющих пользователя в нежелательное место.) Добавление этого небольшого кода HTML, выводящего домен места назначения каждой ссылки на странице, легко делается с помощью
Создание новых элементов HTML делается с помощью функции ) содержащую действующий пример). Код HTML примера выглядит следующим образом:
<p id="start">This is some text that has <a href="http://www.w3.org/TR/html4/struct/links.html">links</a> in it to various places, including <a href="http://www.opera.com">Opera</a>, <a href="http://www.bbc.co.uk/">the BBC</a> and an internal link to <a href="#start">the beginning of this section</a>. All the external links should have <span>[domain]</span> after them.</p>
Код
<script type="text/javascript">
var linksuffix = {
addEvent: function(obj, type, fn) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );};
obj.attachEvent('on'+type, obj[type+fn] );
} else {
obj.addEventListener( type, fn, false );
}
},
init: function() {
var links = document.getElementById("linksuffixtext").getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
var matches = links[i].href.match(/^http:\/\/(.*?)\//);
if (matches) {
var linkdomain = matches[1];
var span = document.createElement("span");
var spantext = document.createTextNode(" ["+linkdomain+"]");
span.appendChild(spantext);
links[i].parentNode.insertBefore(span, links[i].nextSibling);
}
}
}
};
linksuffix.addEvent(window, "load", linksuffix.init);
</script>
Часть сценария, которая выполняет здесь работу, имеет следующий вид:
var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
var matches = links[i].href.match(/^http:\/\/(.*?)\//);
if (matches) {
var linkdomain = matches[1];
var span = document.createElement("span");
var spantext = document.createTextNode(" ["+linkdomain+"]");
span.appendChild(spantext);
links[i].parentNode.insertBefore(span, links[i].nextSibling);
}
}
Этот код разбивается следующим образом:
var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
...
}
Сначала он находит все ссылки ( getElementsByTagName("a") ) в документе
var matches = links[i].href.match(/^http:\/\/(.*?)\//);
if (matches) {
...
}
Эта строка использует регулярное выражение на каждой ссылке, чтобы определить, что место назначение начинается с http://что-то/. Если это так …
var linkdomain = matches[1];
var span = document.createElement("span");
var spantext = document.createTextNode(" ["+linkdomain+"]");
span.appendChild(spantext);
… следующая часть сначала получает "домен ссылки", часть www.opera.com ссылки. Затем с помощью document.createElement создается элемент <span>. Затем создается "textNode" ("текстовыйУзел"). В то время как сами элементы HTML создаются с помощью document.createElement, весь текст в документе HTML фактически содержится в "textNode", и их необходимо создать отдельно. Нет необходимости беспокоиться об этом (или даже знать об этом) при написании реального HTML, но нужно знать об этом при создании элементов с помощью сценария appendChild элемента <span>, чтобы поместить textNode внутрь span.
links[i].parentNode.insertBefore(span, links[i].nextSibling);
Эта строка добавляет span в документ. В этом месте span является ссылкой на элемент HTML, который выглядит следующим образом:
<span> [example.com]</span>
Этот элемент, однако, не является частью документа. Он не является пока частью никакого документа, он просто находится в некоторой неопределенности. Добавление элемента в документ можно сделать одним из двух способов: используя appendChild как выше, или используя insertBefore. Функция appendChild добавляет наш элемент в конце существующего элемента (именно поэтому она называет append ). Так как мы хотим добавить ее в середине существующего элемента, нам нужно использовать insertBefore. Вспомните, что наш текущий фрагмент кода HTML выглядит примерно следующим образом:
<p>... text that has <a href="http://www.w3.org/TR/html4/struct/links.html">links</a> in it to ...
Это приводит к дереву
(рис 9.1) Дерево DOM tree перед добавлением элемента span после ссылкиМы хотим вставить новый span между <a> и textNode "in it to", чтобы он появлялся после <a>. Это приведет к дереву
(рис 9.2) Дерево DOM после добавления элемента spanили, более просто, коду HTML следующего вида
<p>... text which has <a href="http://www.w3.org/TR/html4/struct/links.html">links</a> <span> [domain]</span> in it to ...
Здесь было бы удобно иметь возможность сказать: "вставьте новый span после ссылки". К сожалению функции insertAfter нет. Вместо этого мы должны вставлять его перед элементом после ссылки (несколько запутано, но подумайте об этом, и все встанет на место). Краткая запись для выражения "вещь после элемента помеченного el " будет el.nextSibling. Функция insertBefore должна вызываться на элементе, в который происходит вставка, т.е. на предке <p> ссылки, легко доступной с помощью link.parentNode. Поэтому весь вызов, как выше, будет
links[i].parentNode.insertBefore(span, links[i].nextSibling);
То есть, находим предка ( <p> ) ссылки, которая обрабатывается ( links[i] ) в данный момент, и вставляем созданный элемент span перед элементом после ссылки ( links[i].nextSibling ). Использование HTML в виде дерева
HTML предоставляет структуру страниц, а CSS предоставляет описание внешнего вида. А
Можно время от времени изменять внешний вид страниц и их работу, на основе того, что делают пользователи. Следующий шаг: от хорошо-продуманной и хорошо-структурированной информации к данным, которые изменяются в зависимости от требований пользователя. Можно показывать и скрывать элементы, изменять
display CSS элемента, чтобы скрыть элемент?appendChild и insertBefore?addClass, а не просто соединяем имя нового класса с атрибутом className существующего элемента?document.getElementById("marker").nextSibling?<p>This is a <strong>block of HTML with <span id="marker">various markup</span> in it</strong>.</p>

Стюарт Лэнгридж вполне возможно единственный человек в мире, который имеет степень бакалавра по программированию и философии. Когда он не занят с компьютерами, он программист на
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.