Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Требуется совет в реализации. (https://javascript.ru/forum/dom-window/3448-trebuetsya-sovet-v-realizacii.html)

cker 20.04.2009 20:07

Требуется совет в реализации.
 
В своем приложении мне необходимо по нажатию на кнопку открывать перетаскиваемое окошко посередине окна броузера, а то, что под окном затемнять и делать не кликабельным. Кто сталкивался с fckeditor - в нем это реализовано при нажатии на инструмент "вставить картинку", вставить ссылку". Вот то же самое нужно мне.
В принципе у меня все не плохо получилось с исполозованием createElement('iframe'), но немогу сделать его перетаскиваемым. А так же позиционирование посередине экрана по оси Х вызывает затруднения.
В то же время могу сделать div-элемент перетаскиваемым. Но внутри этого дива есть переходы и переделать под аякс проблематично. Опять же проблема с позиционированием. Вот пока такие результаты, чего удалось добиться. Кто что подскажет, посоветует?

hogart 21.04.2009 17:56

А в чем проблема с позиционированием посередине экрана? Вам всего лишь нужно найти, насколько пикселей документ проскроллен и прибавить половину видимой части документа.

ZoNT 21.04.2009 18:21

Ось Х - горизонтальная, а не вертикальная...

cker 21.04.2009 19:13

Ну позиционирование допустим сделаю. А можно-ли сделать перетаскивание iframe-а по окну броузера? Или только див?

idler 21.04.2009 21:03

а кто мешает сделать <div><iframe/></div>
Так точно будет работать.

cker 21.04.2009 22:07

Тоже думал об этом. Но как-то не красивый код получается. То, чего хочется добиться можно посмотреть вот здесь: http://www.fckeditor.net/demo
если нажать на пиктограмму "вставить изображение"

idler 22.04.2009 00:57

<iframe frameborder="0" style="border: 0pt none ; margin: 0pt; padding: 0pt; background-color: transparent; background-image: none; position: fixed; top: 26px; left: 279px; width: 450px; height: 405px; z-index: 11001;" src="http://www.fckeditor.net/fckeditor/2.6.4/editor/fckdialog.html"/>

вот такой там код генерится
видимо через свойство window.parent в родительском окне изменяются свойства top и left для этого элемента iframe.

cker 22.04.2009 11:14

Да, это понятно. Но как они сделали его перетаскивание? И как они блокируют все окно броузера от кликов?
В принципе я уже реализовал схему div+iframe, но хочется понять, как это сделано в fckeditor.

hogart 22.04.2009 11:52

Цитата:

Сообщение от cker
И как они блокируют все окно броузера от кликов?

Очень просто, накрывают все видимое прозрачным или полупрозрачным div'ом:)

cker 22.04.2009 11:54

А как это "полупрозрачный див"?

cker 22.04.2009 12:04

Я попробовал разместить див. Указываю ему ширину 100% и высоту 100%.
Див появляется только в области видимости в броузере. А если проскроллить ниже, то там див уже не накрывает собой окно.

Riim 22.04.2009 12:06

Абсолютно с позиционированный див, перекрывающий весь документ. z-index на 1 меньше чем у перетаскиваемого блока.

AzriMan 22.04.2009 12:19

Цитата:

Сообщение от cker (Сообщение 17334)
А как это "полупрозрачный див"?

http://htmlbook.ru/css/opacity.html

а для разных браузеров можно сделать так:
/* Функция кроссбраузерной установки прозрачности
Пример: setElementOpacity(document.body, 0.5); //сделать документ прозрачным на половину
*/
function setElementOpacity(oElem, nOpacity)
{
	var p = getOpacityProperty();
	(setElementOpacity = p=="filter"?new Function('oElem', 'nOpacity', 'nOpacity *= 100;	var oAlpha = oElem.filters["DXImageTransform.Microsoft.alpha"] || oElem.filters.alpha;	if (oAlpha) oAlpha.opacity = nOpacity; else oElem.style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity="+nOpacity+")";'):p?new Function('oElem', 'nOpacity', 'oElem.style.'+p+' = nOpacity;'):new Function)(oElem, nOpacity);
}


// Функция getOpacityProperty() возвращает свойство которое используется для смены прозрачности или undefined, и может использоваться для проверки возможности изменения прозрачности браузером
function getOpacityProperty()
{
	var p;
	if (typeof document.body.style.opacity == 'string') p = 'opacity';
	else if (typeof document.body.style.MozOpacity == 'string') p =  'MozOpacity';
	else if (typeof document.body.style.KhtmlOpacity == 'string') p =  'KhtmlOpacity';
	else if (document.body.filters && navigator.appVersion.match(/MSIE ([\d.]+);/)[1]>=5.5) p =  'filter';
	
	return (getOpacityProperty = new Function("return '"+p+"';"))();
}


или в стилях:
Цитата:

<style type="text/css">
img {
filter:alpha(opacity=30);
-moz-opacity: 0.3;
-khtml-opacity: 0.3;
opacity: 0.3;
}
</style>
(c) http://www.tigir.com/opacity.htm
(сам использую этот скрипт. удобно)

Kolyaj 22.04.2009 12:20

И у дива должен быть установлен фон, иначе в ИЕ он не будет ничего перекрывать.

cker 23.04.2009 12:01

Я немогу сделать див на всю высоту броузера с учетом прокрутки. Ниже прокрутки у меня див уже не раширяется. Стоит абсолют; ширина, высота по 100%

Riim 23.04.2009 14:10

Цитата:

Сообщение от cker
Стоит абсолют; ширина, высота по 100%

Определение размеров документа:
http://javascript.ru/forum/misc/1166...j-chastyu.html

----

А разве стоит еще беспокоиться о MozOpacity и KhtmlOpacity? Вроде браузеры их, использующие, давно умерли или перешли на opacity.

idler 23.04.2009 14:12

А как это "полупрозрачный див"?
{
-moz-opacity: 0.5;
opacity: 0.5;
filter: alpha(opacity=50);
}

а вообще они наверное ставят обработчик только в окне iframe, а при попытке перетаскивания передают комманду в родительское окно, где срабатывает функция, которая позиционирует iframe

cker 23.04.2009 14:51

Вложений: 1
Да, с высотой окна все получилось, спасибо.
Только вот обнаружил, что при перетаскивании моего дива по окну броузера иногда в броузере происходит выделение текста =( Использовал пример как здесь: Вложение 91
Может есть лучше реализация перетаскивания? У меня ж в этом диве еще ифрейм.

AzriMan 23.04.2009 14:55

Цитата:

Сообщение от Riim (Сообщение 17430)
А разве стоит еще беспокоиться о MozOpacity и KhtmlOpacity? Вроде браузеры их, использующие, давно умерли или перешли на opacity.

это из серии "Ниже IE6 жизни нет"? :)

Kolyaj 23.04.2009 15:08

Цитата:

Сообщение от cker
Только вот обнаружил, что при перетаскивании моего дива по окну броузера иногда в броузере происходит выделение текста =(

В обработчике mousedown, запускающим перетаскивание, останавливайте обработку события.

Riim 23.04.2009 15:08

Цитата:

Сообщение от AzriMan
это из серии "Ниже IE6 жизни нет"?

Ну и отлично :)

Цитата:

Сообщение от AzriMan
Только вот обнаружил, что при перетаскивании моего дива по окну броузера иногда в броузере происходит выделение текста

if (e.preventDefault) {
	e.preventDefault();
	e.stopPropagation();
} else {
	e.returnValue = false;
	e.cancelBubble = true;
}

cker 27.04.2009 00:28

if (e.preventDefault) {
	e.preventDefault();
	e.stopPropagation();
} else {
	e.returnValue = false;
	e.cancelBubble = true;
}


А куда это?

Riim 27.04.2009 00:48

В начало обработчика.

cker 27.04.2009 16:36

не получается :(

Артем Шалхаков 27.04.2009 18:35

Чтобы замутить drag'n'drop, самый простой способ это реализовать конечный автомат о трех состояниях:
- начальное (ничего не перетаскивается)
- перетаскиваем (поступило событие mousedown, теперь перехватываем все события mousemove)
- "бросаем" (поступило событие mouseup)

Реализацию этой идеи можешь посмотреть на сайте Flapjax. Другие библиотеки тоже предоставляют такую функциональность, но там все плохо с точки зрения комбинирования этого кода с твоим (compositionality).

Полупрозрачный div это div с CSS-свойством opacity < 1.0 (для IE хаки нужны).

ADD: блин, ответил на вопросы с первой страницы %)

Kolyaj 27.04.2009 18:44

Цитата:

Сообщение от Артем Шалхаков
Чтобы замутить drag'n'drop, самый простой способ это реализовать конечный автомат о трех состояниях

Делать автомат с двумя состояниями и с элементарными переходами между ними лишнее, не находите?

Артем Шалхаков 27.04.2009 19:11

Цитата:

Сообщение от Kolyaj (Сообщение 17722)
Делать автомат с двумя состояниями и с элементарными переходами между ними лишнее, не находите?

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

Kolyaj 27.04.2009 19:22

Для чего реализовывать автомат, если обработка mousemove зависит только от того, нажата в данный момент кнопка мыши или нет, и больше ни от чего?

Илья Кантор 27.04.2009 20:29

Прошу - сегодня выложил http://javascript.ru/ui/draganddrop

Ответы на все ваши вопросы в ней есть.

Артем Шалхаков 28.04.2009 08:00

Цитата:

Сообщение от Kolyaj (Сообщение 17724)
Для чего реализовывать автомат, если обработка mousemove зависит только от того, нажата в данный момент кнопка мыши или нет, и больше ни от чего?

Так это... конечный автомат и будет зависеть только от этих событий (скопипасчено с flapjax-lang.org/demos/drag.html и заботливо откомментировано):

// dragE(element) -> EventStream { left: int, top: int }
function dragE(target) {
  // начинаем в состоянии покоя

  // moveEe :: EventStream (EventStream { left: int, top: int })
  var moveEe = extractEventE(target,'mousedown').mapE(function(md) {
    // переходим из начального состояния в состояние переноса
    var startX = md.layerX;
    var startY = md.layerY;
    // в состоянии переноса отлавливаем все события mousemove
    // и сохраняем в особый объект
    return extractEventE(document,'mousemove').mapE(function(mm) {
      mm.preventDefault(); // отменяем выделение текста

      return { element: target, // ради удобства
               left: mm.clientX - startX,  
               top: mm.clientY - startY };
    });
  });
  // терминирующее состояние
  // dropEe :: EventStream (EventStream 'a)
  var dropEe = extractEventE(document,'mouseup').mapE(function() {
    return zeroE();
  });
  // switchE "смешивает" перемещение и окончание, то есть,
  // когда поступает mouseup, то mousemove нас уже не интересуют,
  // и мы на этом заканчиваем
  return switchE(mergeE(moveEe,dropEe));
}


(беспроблемно расширяется до http://flapjax-lang.org/try/index.ht...=listdrag.html)

Этот подход таки лучше указанного в статье, потому что callback'ов нету, а есть потоки событий, с которыми можно обращаться также, как и с переменными (передавать в функции, возвращать из функций, "изменять", etc.).

Еще раз повторю: сначала спецификация, затем код. Иначе не будет четкого понимания, что и зачем делаем, лапша получится.

cker 04.05.2009 19:59

В общем-то получилось у меня сделать drag & drop. Всем большое спасибо! Но одна проблема еще есть: как было решено из дискуссии мой перетаскиваемый элемент на странице представляет из себя див, в который вставлен фрейм с другой html-страничкой. Так вот если БЫСТРО перетаскиваю этот слой вниз он может остановится где нибудь и не тащится дальше. Пока к нему мышкой не вернешься. Влево, вправо, вверх все отлично быстро работает. И только вниз вот такие скачки происходят. Что это может быть?

cker 09.05.2009 22:50

Все получилось с прозрачностью и остальными вопросами. Растраивает только проблема, описанная мной в предыдущем посте. Кто что посоветует?

x-yuri 10.05.2009 07:37

http://javascript.ru/forum/events/36...html#post18565

cker 10.05.2009 18:53

А можно-ли как-то ограничить область в броузере, в которой можно диву "ездить"? Чтобы он не мог сдвигаться влево вправо дальше видимости окна броузера.

x-yuri 11.05.2009 01:51

Измерения окна, документа и элементов - тут есть определение размеров окна браузера

cker 12.05.2009 20:55

Вложений: 1
Вот собрал в кучу все свое "творчество": Вложение 98. Не могу исправить две вещи:
1. при перетаскивании всплывающего дива вниз возникают затыки. В другие стороны все хорошо.
2. Немогу ограничить область разрешенного перетаскивания этого дива.
:help:

x-yuri 12.05.2009 21:21

1) в ie когда мышь становится над iframe, события начинает принимать как раз он
2) что тебе для этого не хватает

cker 13.05.2009 16:12

1. Добавил в свой код после создания ифрейма такое:
Код:

document.getElementById('myPopup').onmousemove = function() { return false };
но результат тот же =(
2. Пытался при движении проверять значение по оси X и если достигает какого-то значения возвращал false. Работало но как-то странно. Правая граница все-время менялась при разных сеансах перетаскивания. Т.е. и не выезжала за пределы окна, но иногда и рано останавливался move.

x-yuri 13.05.2009 16:44

Цитата:

но результат тот же =(
пальцем в небо тыкаешь? мне приходит в голову только передавать событие из iframe в основной документ

2) попробуй еще раз и покажи код

cker 13.05.2009 22:36

Вложений: 1
по первому пункту если чесно не понимаю, что нужно сделать :(
По второму пункту вот исходники: Вложение 102
Правил функцию mouseMove. Вот если схватится за синюю полосу и двигать окно то влево то вправо видно, что крайние границы меняются с каждым передвижением :(


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