Показать сообщение отдельно
  #6 (permalink)  
Старый 25.11.2017, 15:20
Интересующийся
Отправить личное сообщение для Nikifor Посмотреть профиль Найти все сообщения от Nikifor
 
Регистрация: 22.11.2017
Сообщений: 10

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

Были разные варианты, иногда, может быть, некоторые из них подошли бы лучше в каких-то ситуациях:
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, вместо некрасивых стандартных (у меня на сайте это тоже есть, я и делал из него). Нужно будет только убрать последний параметр и последние несколько строчек в функции и добавить два параметра Содержимое и Выравнивание (как то их назвать) и тогда можно будет выводить всплывающую подсказку с любым содержимым, красивую с любой разметкой.

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

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