2013-12-08 3 views
5

Я пытаюсь использовать нокаут для привязки html к iframe.jquery droppable iframe offset

На главной странице содержится перетаскиваемая и iframe содержит droppable. Проблема заключается в том, что предмет падает не в том месте, например:

Зеленый цвет, где мне бы хотелось, чтобы капля произошла, но красный цвет - это место, где происходит падение, похоже, находится справа координаты, но не принимая во внимание положение iframes на главной странице. green - where I would like to drop, red - actual drop

Я попытался применением iframefix к обеим перетаскиваемым и Droppable однако это не помогло:

iframe.find('.sim-row').droppable({ 
     iframeFix: true, 
     drop: function (event, ui) { 
      console.log("dropped"); 
     } 
}); 

$('#drag').draggable({ 
    iframeFix: true, 
    helper: "clone" 
}); 

Это было интересно, есть ли какое-то образом о создании «смещением» на основе позиции IFrames и передать это через перетаскиваемый, чтобы он мог вычислить свою позицию?

Некоторые фидель: Главная страница - http://jsfiddle.net/D26CQ/1/

IFRAME - http://jsfiddle.net/cMfMq/

ответ

7

Самое простое решение, которое я смог найти, чтобы изменить перетаскиваемую функцию jqueryUI учитывать смещение:

в $ .ui.ddmanager добавить следующие строки:

 m[i].offset.top -= m[i].element.parents().find("html,body").scrollTop(); 
     m[i].offset.left -= m[i].element.parents().find("html,body").scrollLeft(); 

     // iframe positioning 
     if (this.current.options.iframeOffset) { 
      m[i].offset.top += this.current.options.iframeOffset.top; 
      m[i].offset.left += this.current.options.iframeOffset.left; 
     } 

просто будьте передняя:

 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 
+0

Только голова, это разрушает производительность при использовании 'refreshPositions', особенно в Firefox. – Loktar

+2

Это было чудесно для нашего выступления здесь. https://gist.github.com/loktar00/9233624 – Loktar

+0

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

1

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

Демо здесь: https://dl.dropboxusercontent.com/u/10953135/droppable/index.html

Проверено на: Chrome, Firefox и IE10

Пожалуйста, смотрите следующие мои изменения.

Commit

https://github.com/Azerothian/jquery-ui/commit/57456ff345fbd119b63524df2e2ede72502dcf9a

Diff

@@ -53,7 +53,20 @@ $.widget("ui.droppable", { 

     this.isover = false; 
     this.isout = true; 
- 
+  if(o.iframeFix) 
+  { 
+   windowTest = this.window.length && this.window.length > 0 ? this.window[0] : this.window; 
+   if(windowTest !== undefined && windowTest !== null) 
+   { 
+    this.iframe = windowTest.frameElement 
+    if(this.iframe === undefined || this.iframe === null) 
+    { 
+     throw "[Droppable] You are specifing iframe fix for a object that does not exist inside a iframe"; 
+    } 
+   } else { 
+    throw "[IframeFix] Window is not defined.. lets blow up because we are unable to find the iframe."; 
+   } 
+  } 
     this.accept = $.isFunction(accept) ? accept : function(d) { 
      return d.is(accept); 
     }; 
@@ -244,6 +257,25 @@ $.ui.intersect = (function() { 
      t = droppable.offset.top, 
      r = l + droppable.proportions().width, 
      b = t + droppable.proportions().height; 
+ 
+  if (droppable.options.iframeFix) 
+  { 
+  var iframeOffset = $(droppable.iframe).offset(), 
+    iframeWidth = $(droppable.iframe).width(), 
+    iframeHeight = $(droppable.iframe).height(), 
+    iframeScrollTop = $(droppable.iframe).contents().scrollTop(), 
+    iframeScrollLeft = $(droppable.iframe).contents().scrollLeft(); 
+   
+   if (y1 < iframeOffset.top || x1 < iframeOffset.left || x1 + draggable.helperProportions.width > iframeOffset.left + iframeWidth || y1 + draggable.helperProportions.height > iframeOffset.top + iframeHeight) // outside iframe; 
+   { 
+   return false; 
+   } 
+   l = (iframeOffset.left + droppable.offset.left) - iframeScrollLeft; 
+   r = l + droppable.proportions().width; 
+   t = (iframeOffset.top + droppable.offset.top) - iframeScrollTop; 
+   b = t + droppable.proportions().height; 
+  } 
+ 

     switch (toleranceMode) { 
     case "fit": 
+0

Ваша демонстрация смехотворно сломана на Chrome по крайней мере fyi. Он, похоже, даже не учитывает прокрутку. – Loktar

+1

Спасибо, что подобрали это, я обнаружил, что совершил ошибку на пересечении, и я обновил свое решение. – Azerothian

+0

Я исследовал предлагаемое решение здесь, а также предоставленную демонстрационную версию. Хотя демонстрация действительно работает, она несколько надуманна и не может быть адаптирована для работы, как хотелось бы. Этот подход, по-видимому, является основной проблемой, а не реализацией. В этом случае OP имеет специальную оболочку обработки связанных с iframe перетаскивания в обработчике пересечения с разумными результатами. К сожалению, решение не является общим, и в результате нельзя использовать несколько функций droppables. Имеет смысл исправить смещения в методе prepareOffset, чем в специальном случае, таком как imho. – kamelkev

2

Я не могу комментировать, но .... @ ответ kiwijus работал идеально подходит для нас. Отсутствует одна часть документации, так что вам нужно указать iframeOffset при вызове draggable.

$('.your-draggable-content').draggable({ 
     helper: "clone", 
     iframeFix: true, 
     iframeOffset: $('#your-iframe').offset() 
}); 
+0

Спасибо, что указали это! Должно быть, я слишком волнуюсь, когда у меня это работает, и я пропустил это! – kiwijus