Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как заставить барадатер открывать картинки-ссылки с js отправкой POST в новой вкладке (https://javascript.ru/forum/dom-window/71479-kak-zastavit-baradater-otkryvat-kartinki-ssylki-s-js-otpravkojj-post-v-novojj-vkladke.html)

Nikifor 22.11.2017 12:16

Как заставить барадатер открывать картинки-ссылки с js отправкой POST в новой вкладке
 
Выносите.
Cледующий мозг...


Всем хорошего дня, да и жизни вообще... Короче, у меня вынос мозга. Полный ) хоть и не окончательный пока, есть ещё надежда на ваш форум.

Ладно: по существу:
барадатер - т.е. браузер (созвучно, ассоциация).

У меня картинка в качестве кнопки.
При щелчке переходит на другую страницу.

....Но, т.к. перед этим необходимо подправить некоторые скрытые поля формы и потом её отправить, чтобы на той странице данные получить, то всё это прописано в событии addEventListener('click',function(){...}); для id кнопки.
....Поэтому для неё в контекстном меню эксплорера (слово браузер не охото говорить) не появляется команда "открыть в новой вкладке", т.к. это ссылка такая - не явная и барадатер не распознаёт.
Но очень нужна возможность в новой вкладке открытия их (таких ссылок).

Уже много чего пробовал (и в <a с разными href> заворачивать и onClick на <a> вешать и return false; ) и команда в конт. меню появляется, но в новой вкладке открывает текущую страницу, а не целевую - очевидно, что форму не отправляет, а срабатывает ссылка <a>, иначе подгружались бы данные формы.

Вот большая просьба может кто знает, как такие ссылки заставить правильно открываться в новой вкладке по желанию пользователя, как заставить браузер считать их ссылками и выводить в конт. меню команду и как сделать чтобы эта команда инициировала событие onClick по которому срабатывал бы js код и отправлял форму.

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

Nikifor 22.11.2017 14:35

Может не очень конкретно написал:

есть ссылка:
<img src="img_knopka.gif" id="id_knopki">

в коде JS обработчик, задающий значения некоторым скрытым полям формы и отправляющий форму:
var id = document.getElementById('id_knopki');
id.addEventListener('click',function() {
   document.myform.atr1.value='aaaa';
   document.myform.atr2.value='bbbb';
   document.myform.submit();
});

картинка, конечно не воспринимается браузером как ссылка и поэтому в конт. меню мышки нет пункта "открыть в новой вкладке". Но это у меня кнопки основного меню, они должны передавать определённые данные методом POST при переходе.
Кажется должен быть способ сделать, чтобы команда в конт. меню была и на такую кнопку, чтобы был у человека выбор как ему загрузить страницу, в текущей вкладке или другой.

Dilettante_Pro 22.11.2017 15:19

Nikifor,
document.myform.submit();

Цитата:

Синтаксис
<form target="имя окна">...</form>
Значения
В качестве значения используется имя окна или фрейма, заданное атрибутом name. Если установлено несуществующее имя, то будет открыто новое окно. В качестве зарезервированных имен можно указывать следующие.

_blank
Загружает страницу в новое окно браузера.
_self
Загружает страницу в текущее окно.
_parent
Загружает страницу во фрейм-родитель, если фреймов нет, то это значение работает как _self.
_top
Отменяет все фреймы и загружает страницу в полном окне браузера, если фреймов нет, то это значение работает как _self.

Nikifor 22.11.2017 16:34

target конечно есть, но он не даёт пользователю выбор где открыть - в текущей или новой вкладке, а нужно чтобы он сам выбирал. Все привыкли пользоваться мышкиным меню, это всем удобно и здесь нужно так же. Но вот только как ссылку он не воспринимает. а если воспринимает (обернуть в <a>, то руководствуется атрибутом href вместо того чтобы по событию сlick обработать мой код.

Nikifor 23.11.2017 11:57

Чего удалось достичь пока:
Люди по разному открывают в новых вкладках, через ctrl, колёсиком и правой кнопкой, но, на планшетах ведь нет колёс и ctrl-а, там только контекстное меню. И событием contextmenu можно отловить его вызов на планшетах и компьютере. По этому событию сразу вызываю событие click() со своим кодом:
<img src="img_knopka.gif" id="id_knopki">

var id = document.getElementById('id_knopki');
id.addEventListener('click',function() {
   document.myform.atr1.value='aaaa';
   document.myform.atr2.value='bbbb';
   document.myform.submit();
});
id.addEventListener('contextmenu',function() {
   document.myform.target='_blank';
   id.click();
   document.myform.target='_self';
});

вот так здорово, универсально, но проклятый барадатер верещит что это всплывающее окно и п.у. блокирует. И ещё этим хвастается. Конечно пользователь легко может запретить блокировку вспл. окон на сайте и будет всё в порядке, но ему тоже лишние сложности, да и не все это умеют.

есть правда ещё вариант отлавливать нажатие именно правой кнопки мыши, но не знаю как это на планшетах, там удерживание пальца - то же событие или другое. Да и тоже может назвать всплывающим окном.

Nikifor 25.11.2017 15:20

мозг вернулся в голову, барадатер сдался
 
Выражаясь словами известного поэта (которого не помню)
"Ну вот и всё - настал ему конец"
Удалось запрограммировать самым в принципе известным и удобным способом.

Были разные варианты, иногда, может быть, некоторые из них подошли бы лучше в каких-то ситуациях:
1) например поделить кнопку на две части, если нажать правую меньшую, то откроется в новом окне, если левую - в текущем.
2) Или с помощью абсолютного позиционирования (свойство css - position:absolute; - только родителю тогда надо задать position:relative; чтобы абсолютное позиционирование работало от угла контейнера а не от левого верхнего края страницы) можно в углу кнопки сделать некоторого размера значок, символизирующий открытие в новом окне, и с помощью css свойства opacity задать прозрачность (opacity:0; ) чтобы скрыть его, а при наведении мыши opacity:1; - проявлять, тогда нажатием тоже открывать в новом окне - это тоже как отдельная кнопка поверх существующей, но более интересно.
Оба способа довольно кроссбарадатерные, правда если кнопка изменяется при наведении мышью, то сложно это сохранить при наведении на другую часть или наложенную сверху. - Неудобно.

3) Третий способ недостатков вроде бы не имеет, не совсем уверен в его кроссбарадатости (мне не было нужно), хотя он вроде бы давно известный и в более-менее не старых всех точно должен работать.
Такой:
Суть его в том, что просто блокируется контекстное меню, которое с правой мышки выводится по умолчанию, чтобы оно не показывалось. А делается своё меню, у меня оно из одной команды "Открыть в новом окне", с широкими кнопками, чтобы и на планшете не промазали.
Выводится оно по универсальному событию contextmenu, поэтому должно везде работать.

Ну и вот: блокируем меню бородатого [этого козла], причём, чем хорошо, не обязательно на всей странице, достаточно в пределах одного элемента - у меня оно заблокировано только в пределах контейнера с моими кнопками - одной ячейки таблицы:
<td id="td_id">
<img src="img/mybutton1.gif" id="id_1knopki">
<!--и далее все мои остальные кнопки-->
</td>

в JS для этой ячейки написал:
document.getElementById('td_id').oncontextmenu = function (){return false};

оно теперь не покажется в пределах этой ячейки. И я могу там вывести своё вместо него, т.к. если меню не спрятать то моё выйдет под ним, будет не удобно.

на странице есть ещё форма с данными:
<form name="myform" method="post" action="index.php">
  <input type="hidden" name="pagename" value="">
  <input type="hidden" name="any" value="">
</form>

которые надо отправлять при нажатии на кнопку.
а в js обработчик нажатия:
//получаем id кнопки
var b1 = document.getElementById('id_1knopki');
//обработчик для щелчка по ней, в котором нужным полям
// формы присваиваются значения перед отправкой
b1.addEventListener('click',function(){ 
   document.myform.pagename.value='myneedpagename'; 
   document.myform.any.value='какое-то нужное значение параметра'; 
   document.myform.submit(); });
//обработчик вызова контекстного меню по правой мыши на той же кнопке.
//в нём вызывается функция с параметрами события,
//длины и ширины меню и кнопки, на которой оно было вызвано.
b1.addEventListener('contextmenu',function(){opennewin_contmenu(event,100,55,b1);});

Вот код этой функции вызывающей меню:
function i_opennewin_contmenu(pp_e,pp_w,pp_h,pp_b) {
  if(!document.getElementById('icme_modalwindow')) { //если окно уже открыто, чтоыб не открывал копии
  //получение вьюпорта (видимой части окна браузера), и координат щелчка мыши
  var i_html = document.documentElement;
  var i_viewport_w=i_html.clientWidth;
  var i_viewport_h=i_html.clientHeight;
  var i_clX=pp_e.clientX;
  var i_clY=pp_e.clientY;
  var i_showX=i_showY=-1;
  //корректировка положения и размеров блока сообщения в зависимости от того где нажато и влезает ли оно
  if(i_viewport_w<(pp_w+20)) {pp_w=i_viewport_w-20; i_showX=10;} //если переданный размер заведомо > (<)
  if(i_viewport_h<(pp_h+20)) {pp_h=i_viewport_h-20; i_showY=10;} 
  if(i_showX==-1) {if(i_clX+pp_w<i_viewport_w) i_showX=i_clX;     //если места хватает, то сообщение выводится с того
                   else {if(i_clX>pp_w) i_showX=i_clX-pp_w;       //места, где щёлкнуто, иначе до него, но тоже, если 
                         else {i_showX=i_viewport_w-pp_w;}}}      //хватит места, иначе с минимальным смещением влево
  if(i_showY==-1) {if(i_clY+pp_h<i_viewport_h) i_showY=i_clY;     //и так же по высоте.
                   else {if(i_clY>pp_h) i_showY=i_clY-pp_h; 
                         else {i_showY=i_viewport_h-pp_h;}}}
  //Создаётся окно сообщения
  var icme_parent=document.getElementsByTagName('body')[0]; //Получим первый элемент тега body
  var icme_obj=icme_parent.firstChild;                       //чтобы вставить наш блокирующий фон в самое начало тега body
  icme_win=document.createElement('div');
  icme_win.id='icme_modalwindow';
  icme_win.style.padding='3px 3px';
  icme_win.style.cssText='position:absolute; background:#eeeeee; border:1px solid #bbbbbb; box-shadow:-1px -1px 3px #000000; z-index:11;';
  icme_parent.insertBefore(icme_win, icme_obj);
  //его длина, высота и общая структура
  icme_win.style.width = pp_w + 'px';   //Установим ширину окна
  icme_win.style.height= pp_h + 'px';  //и высоту
  icme_win.style.display='inline';   //Зададим CSS-свойство
  icme_win.innerHTML='<div style="width:100%; height:'+(pp_h-26)+'px; font:11px/1.2 Verdana,Tahoma,Arial; color:#000000; background:#f9f9f9; padding:2px 2px 2px 2px; text-align:center; vertical-align:top; overflow-y:auto;"><p style="height:100%; width:100%; padding-top:12px; background-color:#eeeeee; cursor:hand; cursor:pointer;" id="icme_fnw">В новом окне?</p></div> \
                      <div style="width:100%; height:24px; font:bold 11px/1 Verdana,Tahoma,Arial; color:#ffffff; background:#bbbbbb; text-align:center; padding-top:6px; cursor:hand; cursor:pointer;" id="icme_x">закрыть</div>'; //Добавим нужный HTML-текст в наше диалоговое окно
  //выравнивание
  icme_win.style.left=i_showX + 'px'; //Позиция по горизонтали
  icme_win.style.top =i_showY + 'px'; //Позиция по вертикали
  //удаляется вместе с фоном по щелчку на кнопку закрытия
  var icme_x=document.getElementById('icme_x');
  icme_x.onclick=function() {icme_parent.removeChild(document.getElementById('icme_modalwindow'));}
  var icme_fnw=document.getElementById('icme_fnw');
  icme_fnw.onmouseover=function() {icme_fnw.style.backgroundColor='#dddddd';}
  icme_fnw.onmouseout=function() {icme_fnw.style.backgroundColor='#eeeeee';}
  icme_fnw.onclick=function() {document.myform.target='_blank'; pp_b.click(); document.myform.target='_self'; }
  }
}

с моими комментариями, которые может не везде быть правильными.
Извиняюсь, нет времени слишком всё подробно расписать, но думаю, кому будет очень надо - всё поймут.

Главное что это меню работает, как и нужно, правой кнопкой вызывается, по кнопке "закрыть" закрывается и, как видите параметр target формы переопределяется в конце, а потом возвращается обратно, чтобы в новом окне открывалось только при нажатии на команду меню, а потом было всё как раньше.

Этот код так же следит за тем, чтобы окно меню правильно располагалось на видимой части экрана. Если пытается вылезти за край (т.к. было вызвано рядом с ним), то его положение корректируется самым удобным на мой взгляд образом.

Кстати этот код можно немного переделать, и превратить его в окошко для вывода сообщений title, вместо некрасивых стандартных (у меня на сайте это тоже есть, я и делал из него). Нужно будет только убрать последний параметр и последние несколько строчек в функции и добавить два параметра Содержимое и Выравнивание (как то их назвать) и тогда можно будет выводить всплывающую подсказку с любым содержимым, красивую с любой разметкой.

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

Ну вот, может кому-то пригодится, хотя мне и жутко лень было это писать.
Ну ладно, всем всего хорошего ) Тему можно считать закрытой. Надеюсь она будет полезной.

Sigizmund2012 25.11.2017 19:02

Цитата:

Сообщение от Nikifor
Оба способа довольно кроссбарадатерные

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

Nikifor 27.11.2017 04:25

Ну вот, хоть один человек написал, а то я уж думал - меня вообще все игнорируют ) (шутка)
Тааак, напишем ответ:
я думаю так: ) тревожный звоночек - это негативные эмоции. Когда они становятся больше, то человек идет к психиатру. А просто говорить, что думаешь, шутить, без плохого отношения к кому-то, разве это не нормально? ) Если вы потренируетесь, то и у вас тоже может получиться что-нибудь полезное.
Вы человек! у вас есть мозг! (довольно умный), во всяком случае на аватарке вверху справа он виден отчётливо в виде шестерёнки, а у кого есть мозг, тот не безнадёжнен ))
Но мозг всё же лучше когда в виде мозгов, или, хотя бы микросхемы. Шестерёнка - механика - это как бы уже прошлый век )
Да слово "браузер" ломает язык.. барадатер - хотя бы веселее звучит. Понормальней как-то. Вообще, лучше бы стандартом было "эксплорер" - означает оно ровно то же самое - "обозреватель". Но почему-то кто-то решил сказать "браузер" и все теперь должны говорить это, довольно кривое слово. Почему нельзя придумать новое, получше? ) я так думаю, но это не самая большая проблема человечества, браузер, эксплорер. Просто не очень удобно изъясняться на русском с помощью таких слов, сделанных из кривой пластмассы с примесями железа. Представляете все слова были бы такими в нашем языке - это сразу повеситься можно, или уехать в другую страну.
Есть ещё куча таких - бэбиситтер, брэнд, трэнд, мерчандайзер, краудсорсинг,... тфу,..
если говорить всё время такими словами то точно пойдёшь к психиатору.

laimas 27.11.2017 06:20

Nikifor,
вы на форуме о программировании, а не в одноклассниках, извольте выражать свои технические проблемы без эмоций, шуток и иносказаний. Иначе все верно вам сказано, начинаешь читать ваше и почти сразу останавливаешься, потому как впечатление, что это бред душевнобольного.

Представьте себе, что в таком же ключе вам и ответ дадут, вряд ли вы его даже читать станете.

Nikifor 27.11.2017 06:27

Цитата:

Сообщение от laimas (Сообщение 471298)
Nikifor,
извольте выражать свои технические проблемы без эмоций, шуток и иносказаний.

вряд ли вы его даже читать станете.

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

Оо!
Тема набирает просмотры. Людям интересно, чем же закончится обсуждение.. А вы говорите, будто это плохо ) Разве плохо, когда людям интересно?


Часовой пояс GMT +3, время: 02:28.