我正在尝试使用knockout将html绑定到iframe。
主页面包含一个可拖动的页面,iframe包含一个droppable。我遇到的问题是该物品在错误的地方掉落,例如:
绿色是我希望掉落的地方,但是红色是实际出现下降的位置 - 它似乎位于正确的坐标处,但没有考虑主页面上的iframes位置。
我尝试将iframefix应用于draggable和droppable,但它没有帮助:
iframe.find('.sim-row').droppable({
iframeFix: true,
drop: function (event, ui) {
console.log("dropped");
}
});
$('#drag').draggable({
iframeFix: true,
helper: "clone"
});
有人想知道是否有一些基于iframes位置创建'偏移'并将其传递给draggable以便它可以计算出它的位置?
一些小提琴: 主页 - http://jsfiddle.net/D26CQ/1/
iFrame - http://jsfiddle.net/cMfMq/
答案 0 :(得分: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 };
答案 1 :(得分:2)
我无法发表评论,但是...... @ kiwijus的回答对我们来说非常合适。丢失的一个文档是在调用draggable时必须指定iframeOffset。
$('.your-draggable-content').draggable({
helper: "clone",
iframeFix: true,
iframeOffset: $('#your-iframe').offset()
});
答案 2 :(得分:1)
我在bootstrap中使用iframe时遇到了类似的问题,我通过修改droppable类来修复iframe并存储对它的引用并更新了交叉函数来检测拖拽何时在iframe上并调整相交以匹配iframe的滚动和偏移。
在这里演示:https://dl.dropboxusercontent.com/u/10953135/droppable/index.html
经过测试:Chrome,Firefox和IE10
请参阅以下内容以了解我的更改。
提交
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":
答案 3 :(得分:0)
此代码对我有用
$.ui.ddmanager.frameOffsets = {};
// Override the native `prepareOffsets` method. This is almost
// identical to the un-edited method, except for the last part!
$.ui.ddmanager.prepareOffsets = function (t, event) {
var i, j,
m = $.ui.ddmanager.droppables[t.options.scope] || [],
type = event ? event.type : null, // workaround for #2317
list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(),
doc, frameOffset;
droppablesLoop: for (i = 0; i < m.length; i++) {
//No disabled and non-accepted
if (m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0], (t.currentItem || t.element)))) {
continue;
}
// Filter out elements in the current dragoged item
for (j = 0; j < list.length; j++) {
if (list[j] === m[i].element[0]) {
m[i].proportions().height = 0;
continue droppablesLoop;
}
}
m[i].visible = m[i].element.css("display") !== "none";
if (!m[i].visible) {
continue;
}
//Activate the droppable if used directly from draggables
if (type === "mousedown") {
m[i]._activate.call(m[i], event);
}
// Re-calculate offset
m[i].offset = m[i].element.offset();
// Re-calculate proportions (jQuery UI ~1.10 introduced a `proportions` cache method, so support both here!)
proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
typeof m[i].proportions === 'function' ? m[i].proportions(proportions) : (m[i].proportions = proportions);
/* ============ Here comes the fun bit! =============== */
// If the element is within an another document...
if ((doc = m[i].document[0]) !== document) {
// Determine in the frame offset using cached offset (if already calculated)
frameOffset = $.ui.ddmanager.frameOffsets[doc];
if (!frameOffset) {
// Calculate and cache the offset in our new `$.ui.ddmanager.frameOffsets` object
frameOffset = $.ui.ddmanager.frameOffsets[doc] = $(
// Different browsers store it on different properties (IE...)
(doc.defaultView || doc.parentWindow).frameElement
).offset();
}
// Add the frame offset to the calculated offset
m[i].offset.left += frameOffset.left;
m[i].offset.top += frameOffset.top;
}
}
};
答案 4 :(得分:-1)
我找到的最佳解决方案是在这里:http://maxazan.github.io/jquery-ui-droppable-iframe/
只需链接js文件,它就可以绝对完美地工作