Как скрыть-отобразить элементы HTML? Назначать при решении этой важнейшей задачи Javascript элементам style.display="none" - вчерашний день! Нужно изменять className элемента. Здесь решение!

Javascript: часто задаваемые вопросы

Как удалить пробелы в Javascript с учётом  ?

  • Речь, понятно, идёт не о всех пробелах подряд, а о лишних пробелах справа и слева, т.е. об аналоге функции trim (удаляющей справа и слева строки символы с кодами \u0020, \u0009, \u000B, \u000C, \u00A0, \u000A, \u000D, \u2028, \u2029): newstr=str.replace(/^\s+|\s+$/g,"");
  • В идеале (при полном аналоге с PHP) у функции trim должен быть второй параметр – произвольная группа символов, которые тоже удаляются в конце и в начале строки. На сайте javascript.ru в аналоге функции trim этот параметр есть, но при этом функция становится существенно сложнее.
  • Для HTML-сущности  , к счастью, можно найти вполне простое решение, добавив в функцию trim всего одну строку:

Это решение возможно потому, что   как раз и вставляет в HTML символ с кодом A0 – мы просто меняем условную последовательность на сам символ, что никак не отражается на HTML-отображении страницы.

Рабочий пример: ir2ru_230210120611.htm

Как сделать кликабельные ссылки Javascript'ом?

Точнее, как превратить адрес ссылки, найденный в произвольном тексте, в гиперссылку (сделать текст ссылкой):

Это довольно интересный и сложный вопрос. Outlook Express, например, превращает в ссылки не только фрагменты, начинающиеся с http://, но и с www., а также [буква][@][буква] (адреса e-mail). Гугл в своих Ответах превращает в ссылку любую последовательность вида [буква][точка][буква] (буквы, разумеется, латинские). Т.е. что (какую последовательность символов?) следует считать адресом будущей гиперссылки? Следуя серединному пути, мы выбираем фрагменты с начальной последовательностью www. или http://.

Следуя простой логике, мы добавляем к подозреваемому тексту несколько очевидных условий:

  1. Перед www. не должно быть http://.
  2. Перед подозреваемыми не должно быть кавычек и закрывающей угловой скобки – подобные контексты означают, что фрагмент уже обработан (или изначально является частью готовой гиперссылки или какой-то другой сомнительной в данном случае конструкции).
  3. Строго говоря, надо было бы ещё находить границу слова, т.е. следить, чтобы подозреваемые не являлись частью какого-то более длинного слова (например, чwww. или 12mhttp://), но подобное кажется нам совершенно невероятным. Хотя... вполне может существовать адрес типа ab.c3www.com.
  4. Важна будет также последовательность обработки: первым должен идти фрагмент http://.

Мы допускаем присутствие в ссылках русских букв. И вообще чего угодно, кроме пробелов (особенно в строке параметров после знака вопроса). Поэтому в основе нашего регулярного выражения – текст после подозреваемого фрагмента, состоящий из непробельных символов. Но вот оканчиваться текст этот может не на что угодно, а только на букву, слэш или чёрточку. Это наше произвольное решение, кто может, пусть сделает лучше. Вот код:

Рабочий пример: gq_313edc5fac07f7a5.htm

Как извлечь тексты и адреса ссылок Javascript'ом?

По-другому: распознать ссылки в тексте, распарсить текст с определённой целью. Цель некоторые считают не очень приличной: ссылки с HTML страниц вроде бы извлекают только спамеры и «синонимизаторы», ворующие контент. Ну, с одной стороны, Эйнштейн тоже ведь не планировал атомную бомбу; а с другой, спамеры наверняка используют серверные скрипты (или программы), а извлечение ссылок с помощью Javascript больше можно отнести к играм, чем к работе (хотя кому-то, может, и пригодится).

Тут возможны два варианта: анализ (парсинг) HTML-кода как текста и извлечение объектов DOM (поскольку каждая ссылка является таким объектом). Вот код:

В примере работы скрипта видно, что регулярное выражение работает более «жёстко», чем анализатор DOM: если какая-то часть ссылки (адрес или текст) отсутствует, ссылка вообще не попадает в список.

Рабочий пример: ir2ru_260210093101.htm

Как получить GET переменные с помощью javascript?

  • otvety.google.ru, mihaild, 09.09.2009 22:41:15
  • (С небольшим изменением: вместо document.location.split("?")[1] мы решили использовать document.location.search.substr(1) – раз уж у объекта location есть свойство search...)

Рабочий пример: mihaild_090909224115.htm?d=1&k=2

Код:

Как получить свойства CSS, которые не были назначены через JavaScript?

  • otvety.google.ru, balou, 11.03.2008 7:30:52

Рабочий пример: balou_110308073052.htm

Код:

Как узнать все методы объекта в Javascript?

На сайте otvety.google.ru есть ответ от Solnce, 12.01.2008 5:44:26; но это (!внимание) не очень хороший ответ:

При его тестировании (например fnShowProps(document.documentElement, "HTML")), практически все браузеры зависают. Кстати, на сайте, на который ссылается автор ответа (htmlcoder.visions.ru), прямо написано, что функция работает только в ИЕ.

Не все свойства (и не всякого объекта) можно получить так уж просто, одной функцией в 3 строки. Наш DOM-инспектор занимает целых 3 Кб, с его помощью можно действительно получить в достаточно удобном виде свойства разных DOM-объектов. Принципы его работы описаны в статье JavaScript.

Возможны ли математические вычисления в работе RegExp?

По-другому: как посчитать выражение, заданное в строке Javascript var str='4+7*8-9*6'?

Самый простой ответ напрашивается в виде eval(str). Но всегда найдутся люди, которым хочется странного. Можно сосчитать такую строку и регулярными выражениями, используя в методе replace в качестве второго параметра функцию:

Рабочий пример: ir2ru_260210103501.htm

Как получить список (массив) всех дочерних элементов определённого элемента HTML?

С помощью свойства childNodes и методов работы с массивами:

Рабочий пример: ir2ru_260210123501.htm

Как проверить на javascript, есть ли в строке руские символы?

Рабочий пример: ir2ru_260210193501.htm

Как узнать полный размер документа, открытого в браузере?

Каких только странных конструкций не встретишь в сети! Иногда ширину документа пытаются определить, например, так:

Это выражение трижды неверно. Во-первых, начальная часть (проверка условий) просто лишняя:

Этот более короткий код даёт точно такой же результат. Во-вторых, на первое место следует ставить document.body (даёт более правильный результат), а document.documentElement (HTML) либо просто дублирует размеры body (в правильных браузерах), либо выдаёт совершенно непонятные результаты. В-третьих, приведённый код вычисляет ширину окна, а не всего документа (часть которого может быть скрыта). Ширину документа (с учётом возможной прокрутки, практически во всех браузерах) можно получить так:

Можно долго пытаться понять, чем scrollWidth отличается от offsetWidth, но вместо этих мучительных раздумий мы просто нашли с помощью своего дом-инспектора все существующие свойства DOM, имеющие отношение к размерам элемента, и потом несложным скриптом вывели эти свойства в виде таблицы:

Выбирайте ширину и высоту из любого свойтва DOM – что больше понравится!

Рабочий пример: ir2ru_260210195201.htm

Как извлечь домен из url с помощью регулярных выражений?

Начало текста, (http://www.dbmodern.ru/price.htm) текст
http://ir2.ru/static/testip.php?host=belttrade.ru другой текст

Результат:
Начало текста, (www.dbmodern.ru) текст
ir2.ru другой текст

Код:

Рабочий пример: gq_00dab22d6ed88f19.php

Как однократно обновить страницу в JavaScript (без участия пользователя)?

Если просто сформировать HTML-страницу с Javascript, в котором написано document.location.reload(), страница будет перегружаться снова и снова, бесконечно. Нужна какая-то метка, без которой страница не должна перегружаться. Можно, например, при необходимости перезагрузки добавлять к url какой-нибудь параметр типа "reload=1", а в процессе перезагрузки удалять его:

Рабочий пример: gq_2bb719c5cce2d6e0.htm?c=2&reload=1&d=1

D.M., admin

Комментарии

лесник 15.03.2010 02:02:45

Как скрыть-отобразить элемент(ы) одной кнопкой?

Функция toggle() была когда-то включена в 10 лучших на Javascript приблизительно в таком виде:

Как оказывается теперь, это крайне плохое понимание и использование DOM-манипуляций для отображения элементов. Мы добавили в функцию всего одно скромное замечание о 'block' или 'inline', на сайте же javascript.ru Илья Кантор расширил эту мелкую трещинку до полного разгрома части Jquery, ответственной за скрытие-отображение DOM элементов.

Но в коллективе всё легко, и участник того же сайта javascript.ru/person/kolyaj подсказал великолепную идею об использовании className вместо style.display. Вероятно, эта идея не используется в известных «фреймворках» из-за их «самодостаточности»: они «не знают» о наборе правил CSS, расположенном в каком-то отдельном файле (чтО говорит о вреде стремления к универсальности того, что по самой своей природе призвано быть частью общего замысла).

Идея основана на одной интересной особенности CSS: у элемента может быть несколько className разделённых в HTML коде пробелами: <div id="d1" class="border bgyell">, и каждый класс может быть отдельно описан в таблице стилей:

– задав такую таблицу стилей, мы можем программно изменять отображение выбранного элемента через добавление к нему класса disnone:

Обратная процедура – удаление disnone (чтобы сделать элемент видимым) – несколько сложнее:

Но в целом такой способ обходит все подводные камни, описанные в статье javascript.ru/ui/show-hide-toggle: вопрос о том, как отображался элемент до скрытия ("block", "inline"...), и вопрос о том, не был ли элемент скрыт правилом CSS, назначенным через className. Мы сами добавляем "класс невидимости" с пробелом впереди, поэтому найти его по имени будет не очень сложно, и ядро функции "Скрыть-показать элемент" будет выглядеть так:

Разрослась наша функция по двум направлениям: из-за интерфейса (как всегда) – смены текста кнопки, переключающей режимы, и из-за допущения в качестве параметра для функции не одного, а нескольких элементов (массива). Функция принимает, таким образом, два параметра: элемент obj (или массив элементов) и элемент-переключатель knop (с надписью, которую надо менять):

Элемент-переключатель может быть разным, поэтому мы меняем в нём надпись через свойство, которое у него существует (value или innerHTML) и не пустое. Для поиска существующего и непустого (ess) свойства (из набора предполагаемых – arr) нам пришлось написать отдельную функцию findProp (она в общей библиотеке ir2.js):

Рабочий пример: ir2ru_130310204701.htm

лесник 02.03.2010 19:19:28

Как получить фрагмент текста другой страницы с помощью Javascript?

Для начала нужно открыть новую страницу в другом окне браузера (1) или послать к ней фоновый (скрытый) http-запрос (2). К сожалению, фоновый запрос в данном случае нельзя выполнить с помощью атрибута src элемента script (2.1), а только с помощью Ajax (XMLHttpRequest) (2.2); Ajax же на нашем сайте считается лишней сущностью, поэтому из всех вариантов у нас остаётся только (1).

Открыть Javascript'ом новую страницу тоже можно разными способами: во фрейме (1.1), вложенном в исходный документ (элемент iframe), или в совсем новом окне (1.2).

Ограничение (3). Во всех вариантах (включая Ajax) нельзя получить текст (документ) новой страницы, если она расположена в другом домене; браузер выдаст ошибку, что-нибудь вроде "Ошибка: Permission denied to get property Window.document".

По условиям задачи нужно получить какую-то часть другой страницы (например, текст элемента с заданным id). Значит, вся новая страница вместе со своим окном нам (пользователям) не нужна, её нужно открыть, забрать фрагмент и быстренько закрыть обратно. Значит, окно с новой страницей вообще лучше всего делать невидимым. Это можно делать только с помощью варианта (1.1) – iframe. Схема работы будет примерно такая:

  1. Создать на странице фрейм с заданным src.
  2. Дождавшись полной загрузки фрейма, получить доступ к его документу.
  3. Извлечь из документа нужные фрагменты и записать их в отведённое место на главной странице.
  4. Удалить созданный программой фрейм.

Создание временного элемента iframe

Это только на словах легко и быстро. Кроссбраузерное создание элемента iframe с помощью "классических" методов DOM (createElement, appendChild) выглядит довольно "криво" из-за ИЕ. Поэтому мы используем примитивный innerHTML. Просто и надёжно: элементу-контейнеру присваиваем свойство innerHTML="<iframe src=...". Но ИЕ, правда, и тут достал: не позволяет создать элемент-контейнер динамически (где логика?..). Впрочем, это уже не так страшно – создаём контейнер заранее, сразу с текстом страницы, как уже делали при редактировании таблицы MySQL.

Получение текста из документа iframe

Дождаться полной загрузки фрейма – тоже непростая задача. Мы не знаем, сколько времени будет открываться его внутренняя страница, и когда станет доступно свойство contentDocument (или contentWindow). Поэтому при запуске таймера временной интервал выбираем произвольно, исходя из размеров страницы (которые мы знаем заранее – ведь страница на том же нашем сайте) и разумного времени ожидания пользователя. В нашем случае это 1-2 секунды (пусть будет 2!). Страница маленькая, и если за 2 с от неё нет отклика, значит какие-то проблемы со связью (сбой на сервере или провайдер пользователя – без разницы), и пользователю пора выдать табличку "Миссия провалилась!".

Единственное преимущество XMLHttpRequest перед выбранной технологией – Ajax "знает" о том, загрузилась ли уже страница. Но это очень мелкое преимущество. При реальной проблеме доступа к сайту оно сходит на нет, потому что если Ajax "знает" об отсутствии желаемого документа больше 2 секунд, ему придётся делать совершенно то же самое, что и нам: измерять время с помощью таймера и по истечении некоторого произвольно назначенного интервала вывешивать точно такую же табличку (или продолжать злить пользователя песочными часами).

При хорошей связи незачем растягивать время ожидания, поэтому минимальный интервал мы берём такой, чтоб не был заметен пользователю – 200 мс. И повторяем попытки получения документа до 10-ти раз (разумеется, если успех не придёт раньше):

Проверяем мы при этом не доступ к contentDocument, а доступ к конкретному, нужному нам объекту – потому что в ходе опытов у нас возникала ситуация, когда contentDocument уже доступен, а contentDocument.body.innerHTML=null! Мы не нашли объяснения этому чуду, но избежать его появления, надеемся, у нас получилось.

Вывод результатов

В примере мы находим на странице этого сайта javascript10.aspx элемент с id="art" и извлекаем его второй дочерний элемент – что-то вроде оглавления страницы. Полученное значение (свойство innerHTML) записываем в заранее заготовленный контейнер – div id="newbox".

Рабочий пример: ir2ru_280210090101.htm