Js переключение между вкладками браузера
Репутация: нет
Всего: нет
Здравствуйте. Помогите пожалуйста со скриптом который по замыслу должен делать следующее.
1. Перемещаться по вкладкам firefox.
2. Вызывать событие submit для форму на каждой вкладке. Форма везде одна и та же.
2-ой пункт я реализовал в кач-ве скрипта для greasemonkey:
init: function() window.addEventListener('keydown',window.go.handler,false);
>,
runScript: function()
document.forms[0].submit();
>
В результате при нажатии Alt + G выполняется submit(). Теперь хочу сделать тоже самое, но чтобы выполнялось sumbit() для всех открытых вкладок. Проблема в том, что не могу сообразить, как мне с помощью скрипта переключаться между вкладками.
Заранее спасибо за помощь.
Репутация: 7
Всего: 22
А с чего ты взял, что это можно сделать? - Каждая вкладка - фактически отдельное окно со своим контентом, песочницей и ДОМом и у каждой вкладки "свой javascript". У тебя не получится это делать изнутри.
Репутация: нет
Всего: нет
Если не получится изнутри, то может быть снаружи? Как-то же в firefox происходит управление вкладками, да и переключаться между ними можно с помощью Ctr+Tab. Вот здесь вопрос - можно ли реализовать это событие переключения между вкладками с помощью пользовательского скрипта, если нет - то как такое еще можно сделать. Теперь если мою задачу сформулировать по-другому - то получится такая:
Как реализовать в firefox такой цикл:
Пока не перебраны все вкладки
делать на каждой вкладке submit();
Конец цикла.
Репутация: 7
Всего: 22
Блин, не понял "в лоб", объясню по-другому: представь, что у тебя на компе есть 2 (как минимум) операционных системы - допустим, Win7 и WinXP, выбор между которыми ты производишь при загрузке компа. Можешь ли ты из Win7 сделать, скажем, отправку почты или серфинг, в WinXP? А почему?
Ctrl-Tab можешь перехватывать как хочешь, но у самого браузера по этому поводу есть свои соображения, с которыми спорить сложно.
Если все упирается в решение такой задачи, то она делается ну точно не через клиентскую реализацию. Все связанные страницы имеют связь с сервером, откуда должна поступить команда совершить определенные действия. Судя по твоим вопросам, тебе ближайший годик точно не светит решить ее грамотно. Вариант с таймером на N секунд для опроса сервера грамотным вариантом я точно не считаю.
Репутация: нет
Всего: нет
Спасибо за подробное объяснение. Но я как полный ламер все равно мало что понял). А решение нашел. Даже два.
1. Т.к. window - это объект браузера, то можно написать расширение для firefox, которое решит проблему.
2. Более простой вариант. Все вкладки у меня открываются также с помощью скрипта, поэтому я в этом скрипте могу завести массив ссылок на них:
Код |
var myWindows = Array(); mywindows.push (window.open(someUrl)); |
а потом уже работать с ним.
Если есть предложения по первому варианту - написание расширения. Буду рад услышать, как это примерно можно осуществить, т.к. с этим дела еще не имел.
Цитата |
Если все упирается в решение такой задачи, то она делается ну точно не через клиентскую реализацию |
К сожалению, возможности серверной реализации нет, т.к. нет к нему доступа
Проникся идеей нативного js, которую последнее время сильно продвигают в массы и решил попробовать написать хоть что-то без любимого jquery. Поэтому отложил jquery в сторону и написал простую переключалку вкладок на нативном js. И встал в ступор.
Вот html
А вот что я написал на js
Для меня было диким удивлением, что addEventListener не хотел работать с querySelectorAll, ну и я решил написать цикл, что бы клик работал для всех элементов коллекции! Но как написал это, испугался, чет каким-то говнокодом пахнет)). Смирившись я дошел до того, как добавляю ссылке активный класс, но заступорился, а как удалить у всех других ссылок и табов класс act? Тоже нужно писать цикл для всех элементов в коллекции?
- Вопрос задан более трёх лет назад
- 4654 просмотра
Ну потом вам это может надоесть, тогда вы оформите все в виде функции (а то и объектами разбрасываться начнете) и потихоньку у вас это будет выливаться в очередную jQuery-подобную библиотеку.
Дима Турков, я имел в виду, что работая постоянно с подобным, однажды надоест писать однообразные циклы, например, или просто куски кода. И может даже начать вырисовываться библиотека, заменяющая jQuery. С функциями для работы с классами, обработки массивов и т.д.
Хотя стоит заметить, что нынче и ванильный JS имеет уже много возможностей, которые позволяют не тянуть jQuery для любого чиха.
В jQuery много синтаксического сахара, но в ванильном js нет ничего особо страшного.
Такой код нежизнеспособен, ибо хотя бы нет повторного использования кода и Вы будете повторять сами себя, это неизбежно. это если не касаться самого "компонента" ибо это только заготовка.
Абстракцию все ровно придется писать, придется писать минимальный базис для работы с DOM.
Тут у здешних две крайности на эту тему:
1) JQuery везде, JQuery всегда, JQuery любит папа, мама и я. (с) =)
2) Vanilla JS - так давайте же все напишем без абстракций, ядра , библиотек. чем больше сдадим-тем лучше
Писать на "чистом" не освобождает от необходимости грамотно строить код, придерживаться ООП, модульности, юзания библиотек и любых методик позволяющих не повторяться. Да, это приведет к появлению собственных библиотечных функций, возможно микрофеймворка, если не взяли готовый перед этим, но так и должно же быть.
Можно повесить обработчик на какой-нибудь родительский элемент, к примеру, body. А в обработчике уже проверять target, и если он является одной из вкладок - делать нужное действие. Такой подход хорош тем, что можно будет в рантайме добавлять новые вкладки и не заботиться о том, что придётся снова обработчик на каждую новую вешать.
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Всплывающее окно («попап» – от англ. Popup window) – один из старейших способов показать пользователю ещё один документ.
В этой статье мы рассмотрим открытие окон и ряд тонких моментов, которые с этим связаны.
…При запуске откроется новое окно с указанным URL.
Большинство браузеров по умолчанию создают новую вкладку вместо отдельного окна, но чуть далее мы увидим, что можно и «заказать» именно окно.
Блокировщик всплывающих окон
Рекламные попапы очень надоели посетителям, аж со времён 20-го века, поэтому современные браузеры всплывающие окна обычно блокируют. При этом пользователь, конечно, может изменить настройки блокирования для конкретного сайта.
Всплывающее окно блокируется в том случае, если вызов window.open произошёл не в результате действия посетителя.
Как же браузер понимает – посетитель вызвал открытие окна или нет?
Для этого при работе скрипта он хранит внутренний «флаг», который говорит – инициировал посетитель выполнение или нет. Например, при клике на кнопку весь код, который выполнится в результате, включая вложенные вызовы, будет иметь флаг «инициировано посетителем» и попапы при этом разрешены.
А если код был на странице и выполнился автоматически при её загрузке – у него этого флага не будет. Попапы будут заблокированы.
Полный синтаксис window.open
Функция возвращает ссылку на объект window нового окна, либо null , если окно было заблокировано браузером.
url URL для загрузки в новое окно. name Имя нового окна. Может быть использовано в параметре target в формах. Если позднее вызвать window.open() с тем же именем, то браузеры (кроме IE) заменяют существующее окно на новое. params Строка с конфигурацией для нового окна. Состоит из параметров, перечисленных через запятую. Пробелов в ней быть не должно.
Значения параметров params .
Координаты верхнего левого угла относительно экрана. Ограничение: новое окно не может быть позиционировано за пределами экрана.
Ширина/высота нового окна. Минимальные значения ограничены, так что невозможно создать невидимое окно с нулевыми размерами.
Если координаты и размеры не указаны, то обычно браузер открывает не окно, а новую вкладку.
- Свойства окна:
- Ещё есть небольшое количество не кросс-браузерных свойств, которые обычно не используются. Вы можете узнать о них в документации, например MDN: window.open.
Браузер подходит к этим параметрам интеллектуально. Он может проигнорировать их часть или даже все, они скорее являются «пожеланиями», нежели «требованиями».
- Если при вызове open указан только первый параметр, параметр отсутствует, то используются параметры по умолчанию. Обычно при этом будет открыто не окно, а вкладка, что зачастую более удобно.
- Если указана строка с параметрами, но некоторые yes/no параметры отсутствуют, то браузер выставляет их в no . Поэтому убедитесь, что все нужные вам параметры выставлены в yes .
- Когда не указан top/left , то браузер откроет окно с небольшим смещением относительно левого верхнего угла последнего открытого окна.
- Если не указаны width/height , новое окно будет такого же размера, как последнее открытое.
Доступ к новому окну
Вызов window.open возвращает ссылку на новое окно. Она может быть использована для манипуляции свойствами окна, изменения URL, доступа к его переменным и т.п.
В примере ниже мы заполняем новое окно содержимым целиком из JavaScript:
А здесь модифицируем содержимое после загрузки:
Обратим внимание: сразу после window.open новое окно ещё не загружено. Это демонстрирует alert в строке (*) . Поэтому в примере выше окно модифицируется при onload . Можно было и поставить обработчик на DOMContentLoaded для newWin.document .
Связь между окнами – двухсторонняя.
Родительское окно получает ссылку на новое через window.open , а дочернее – ссылку на родителя window.opener .
Оно тоже может его модифицировать.
Если запустить пример ниже, то новое окно заменит содержимое текущего на 'Test' :
Большинство действий, особенно получение содержимого окна и его переменных, возможны лишь в том случае, если URL нового окна происходит из того же источника (англ. – «Same Origin»), т.е. совпадают домен, протокол и порт.
Иначе говоря, если новое окно содержит документ с того же сайта.
Больше информации об этом будет позже, в главе Кросс-доменные ограничения и их обход.
События
Наиболее важные события при работе с окном браузера:
- onresize – событие изменения размера окна.
- onscroll – событие при прокрутке окна.
- onload – полностью загрузилась страница со всеми ресурсами.
- onfocus/onblur – получение/потеря фокуса.
Методы и свойства
window.closed Свойство window.closed равно true , если окно закрыто. Может быть использовано, чтобы проверить, закрыл ли посетитель попап. window.close() Закрывает попап без предупреждений и уведомлений. Вообще, метод close() можно вызвать для любого окна, в том числе, текущего. Но если окно открыто не с помощью window.open() , то браузер может проигнорировать вызов close или запросить подтверждение.
Перемещение и изменение размеров окна
Существует несколько методов для перемещения/изменения размеров окна.
win.moveBy(x,y) Перемещает окно относительно текущего положения на x пикселей вправо и y пикселей вниз. Допускаются отрицательные значения. win.moveTo(x,y) Передвигает окно в заданную координатами x и y точку экрана монитора. win.resizeBy(width,height) Изменяет размер окна на заданную величину width/height (ширина/высота). Допускаются отрицательные значения. win.resizeTo(width,height) Изменяет размер окна на заданное значение.
Чтобы предотвратить использование этих методов с плохими целями, браузеры часто блокируют их выполнение. Как правило, они работают, если окно win открыто вызовом window.open из JavaScript текущей страницы и в нём нет дополнительных вкладок.
Заметим, что JavaScript не может ни свернуть ни развернуть ни «максимизировать» (Windows) окно.
Эти функции операционной системы от Frontend-разработчиков скрыты. Вызовы, описанные выше, в случае свёрнутого или максимизированного окна не работают.
Прокрутка окна
Прокрутка окна требуется, пожалуй, чаще всего. Мы уже говорили о ней в главе Размеры и прокрутка страницы:
win.scrollBy(x,y) Прокрутка окна на заданное число пикселей вперёд или назад. Допускаются отрицательные значения. win.scrollTo(x,y) Прокручивает окно к заданным координатам. elem.scrollIntoView(top) Этот метод прокрутки вызывается на элементе. При этом окно прокручивается так, чтобы элемент был полностью видим. Если параметр top равен true или не задан, то верх элемента совпадает с верхом окна. Если он равен false , то окно прокручивается так, чтобы нижний край элемента совпал с нижним краем окна.
Итого
- Всплывающее окно открывается с помощью вызова window.open(url, name, params) .
- Метод window.open возвращает ссылку на новое окно или null , если окно было заблокировано.
- Современные браузеры блокируют окна, если window.open вызвано не в результате действия посетителя.
- Обычно открывается вкладка, но если заданы размеры и позиция – то именно окно.
- Новое окно имеет ссылку на родительское в window.opener .
- Окна могут общаться между собой как угодно, если они из одного источника. Иначе действуют жёсткие ограничения безопасности.
Всплывающие окна используются нечасто. Ведь загрузить новую информацию можно динамически, с помощью технологии AJAX, а показать – в элементе , расположенным над страницей ( z-index ). Ещё одна альтернатива – тег .
Но в некоторых случаях всплывающие окна бывают очень даже полезны. Например, отдельное окно сервиса онлайн-консультаций. Посетитель может ходить по сайту в основном окне, а общаться в чате – во вспомогательном.
Если вы хотите использовать всплывающее окно, предупредите посетителя об этом, так же и при использовании target="_blank" в ссылках или формах. Иконка открывающегося окошка на ссылке поможет посетителю понять, что происходит и не потерять оба окна из поля зрения.
На протяжении многих лет возможности браузеров постоянно увеличивались в ответ на растущие потребности веб-приложений. И теперь у нас есть множество способов получения одной и той же (или схожей) функциональности. На такую особенность браузеров, как возможность обмена данными между вкладками, редко обращают внимание. Рассмотрим несколько сценариев, в которых она может потребоваться:
- Изменение темы (например, тёмная или светлая тема) приложения распространяется на уже открытые вкладки браузера.
- Получение последнего токена для аутентификации и использование его во всех вкладках браузера.
- Синхронизация состояния приложения во всех вкладках браузера.
На момент написания этой статьи существовало несколько достойных внимания подходов, в соответствии с которыми осуществляется обмен данными между вкладками браузеров. У каждого из этих подходов свои сильные и слабые стороны, поэтому остановимся на них подробнее, чтобы вы могли найти подходящий для вас вариант.
Возможно, вы уже использовали LocalStorage , который доступен на разных вкладках в рамках одного и того же приложения-источника. Но знаете ли вы, что LocalStorage поддерживает события? Эту функцию можно использовать для обмена данными между вкладками браузера: хранилище обновляется, после чего событие получат другие вкладки.
Например, в одной вкладке выполняется следующий код JavaScript:
И другие, прослушивающие событие вкладки получат это событие:
Но здесь есть несколько ограничений:
- Событие не срабатывает для вкладки, на которой выполняется действие по вводу значений в хранилище.
- Этот подход имеет негативные последствия для большого объёма данных: из-за синхронности выполняемых в LocalStorage действий основной поток пользовательского интерфейса может быть заблокирован.
API широковещательного канала позволяет осуществлять обмен данными между вкладками, окнами, фреймами, Iframes и веб-воркерами. Одна вкладка создаёт что-то и опубликовывает это на канале:
А другие вкладки прослушивают канал:
И таким образом происходит обмен данными между контекстами браузера (окнами, вкладками, фреймами или Iframes). Такой способ обмена данными между вкладками браузера очень удобен. Тем не менее safari и IE его не поддерживают. Более подробная информация содержится в разделе «BroadcastChannel» документации MDN.
Подсказка: выкладывайте на Bit (Github) переиспользуемые компоненты для своих проектов. Здесь очень просто размещать, документировать и организовывать независимые компоненты из любого проекта.
Задействуйте этот ресурс для максимально многократного использования кода и совместной работы над независимыми компонентами, а также для создания масштабируемых приложений.
Bit поддерживает Node, TypeScript, React, Vue, Angular и много других инструментов.
А принимающий воркер на другой вкладке браузера прослушивает это событие:
А целевое окно прослушивает события:
Одно из преимуществ этого подхода перед другими — возможность поддержки обмена данными между разными источниками. Но есть и ограничение: необходима ссылка на другую вкладку браузера. Поэтому этот подход только для вкладок браузера, открытых через window.open() или document.open() . Более подробная информация содержится в документации MDN.
Надеюсь, статья была для познавательной и рассмотренные в ней подходы будут полезны для ваших веб-приложений. Каждый подход уникален и имеет свои варианты использования.
Кроме этих четырёх подходов, для обмена данными между вкладками браузера и даже между устройствами в режиме реального времени применяются Websockets («веб-сокеты») и Server-Sent Events («события, посылаемые сервером»). Но для этого понадобится веб-сервер. А вот рассмотренные в статье подходы не зависят от веб-сервера, и их применение позволяет осуществлять обмен данными в браузере без него и делать это быстро.
С тех пор прошло 2 года, я набрался определенного опыта в работе с jQuery, и вышеуказанный скрипт превратился в абсолютно новый скрипт, написанный мною полностью с нуля. Перед этим был еще один вариант данного скрипта, которым я пользовался, наверное, год. О нем я нигде не писал, да и сейчас уже нет смысла это делать, т.к. он потерял свою актуальность.
Почему я называю свой новый скрипт для jQuery-вкладок универсальным:
- он позволяет создавать неограниченное количество вкладок в пределах одного блока, при этом нет необходимости нумеровать вкладки с помощью CSS-классов, как это было сделано в старом варианте;
- можно создать сколько угодно таких блоков с вкладками опять же без необходимости нумеровать эти блоки через CSS-классы;
- содержимое jQuery-скрипта, реализующего вкладки, остается неизменным (всего 0,3 килобайта), т.е. не разрастается в зависимость от количества блоков или вкладок, как это было в старом варианте, при этом размер нового варианта скрипта не больше размера скрипта для одного блока с вкладками из старого варианта.
Что ж, хватит сухих слов, переходим к сути.
Код jQuery-скрипта для переключаемых блоков с вкладками
Не забывайте в первую очередь подключить сам фреймворк jQuery (если он еще не подключен на вашем сайте), например, так (вставляется между тегами
и ):Я предпочитаю «брать» его с Гугла, поскольку, во-первых, велика вероятность, что у посетителя, который зайдет на сайт, jQuery уже закэширован в браузере (значит страница загрузится быстрее), во-вторых, скорость серверов Гугла стабильна и быстра, в-третьих, Гугл отдает его в сжатом виде (gzip), и, например, для версии 1.4.2 размер составляет всего 24 килобайта по сравнению с несжатым файлом (70 Кб).
Вот такой у меня получился скрипт:
Добавлено 07.03.2010 (обновлено 09.04.2015)
В комментариях подсказали еще более сокращенный вариант этого скрипта (обратите внимание, что для него нужно использовать jQuery не ниже версии 1.7):
Для тех, кто еще не знает, как подключать этот скрипт — создать файл с расширением .js , вставить в него код скрипта и подключить по аналогии c jQuery (см. выше), естественно, заменив ссылку на адрес скрипта.
Универсальный jQuery-скрипт для блоков с вкладками
Если вы желаете отблагодарить автора финансово, воспользуйтесь следующей формой, указав произвольную сумму рублей:
HTML-код, который нужно использовать для скрипта
Обратите внимание, что структура HTML-кода строго привязана к скрипту, поэтому, если вы пожелаете изменить названия используемых классов, не забывайте их поменять и в скрипте.
Обязательные CSS-стили для вышеуказанного HTML-кода
Если, например, необходимо, чтобы по умолчанию отображался второй блок, тогда нужно переместить класс .active во второй блок div.tabs__content , а также переместить класс .active во второй элемент в списке вкладок.
Примеры
-
. , в котором запоминается активная вкладка после перезагрузки страницы (с помощью cookie). , в котором запоминается активная вкладка после перезагрузки страницы (с помощью localStorage, меньше кода по сравнению с cookie). , в котором при переходе по ссылке с якорем, указывающим на номер таба, активируется соответствующий таб.
P.S. Мне в твиттере как-то сказали, что я «изобретаю колесо», что такой скрипт уже есть в jQuery UI. Ну и пусть, пусть я «изобрел колесо», главное, что я получаю большое удовольствие от данного процесса и одновременно повышаю свой опыт в jQuery. Разве это плохо? =)
Читайте также: