在一个页面上,我有一个iframe。在这个iframe中,我需要对可排序的项目进行收集。所有Javascript都在父页面上运行。我可以访问iframe文档中的列表,并使用上下文创建sortable:
var ifrDoc = $( '#iframe' ).contents();
$( '.sortable', ifrDoc ).sortable( { cursor: 'move' } );
然而,当试图对物品进行实际排序时,我会遇到一些异常行为。单击某个项目后,脚本的目标将更改为外部文档。如果您将鼠标移离iframe,则可以移动项目并通过单击将其放回,但您无法在iframe中与其进行交互。
示例:http://robertadamray.com/sortable-test.html
那么,有没有办法实现我想做的事情 - 最好不必在jQuery UI代码中进行黑客攻击?
答案 0 :(得分:9)
动态地将jQuery和jQuery UI添加到iframe(demo):
$('iframe')
.load(function() {
var win = this.contentWindow,
doc = win.document,
body = doc.body,
jQueryLoaded = false,
jQuery;
function loadJQueryUI() {
body.removeChild(jQuery);
jQuery = null;
win.jQuery.ajax({
url: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js',
dataType: 'script',
cache: true,
success: function () {
win.jQuery('.sortable').sortable({ cursor: 'move' });
}
});
}
jQuery = doc.createElement('script');
// based on https://gist.github.com/getify/603980
jQuery.onload = jQuery.onreadystatechange = function () {
if ((jQuery.readyState && jQuery.readyState !== 'complete' && jQuery.readyState !== 'loaded') || jQueryLoaded) {
return false;
}
jQuery.onload = jQuery.onreadystatechange = null;
jQueryLoaded = true;
loadJQueryUI();
};
jQuery.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
body.appendChild(jQuery);
})
.prop('src', 'iframe-test.html');
更新: Andrew Ingram is correct jQuery UI保存并使用window
和document
的引用作为加载jQuery UI的页面。通过将jQuery / jQuery UI加载到iframe中,它具有正确的引用(对于iframe,而不是外部文档)并按预期工作。
更新2:原始代码段有一个微妙的问题:无法保证动态脚本代码的执行顺序。我已经更新了它,以便在jQuery准备就绪后加载jQuery UI。
我还将getify的代码合并到load LABjs dynamically,因此不需要轮询。
答案 1 :(得分:5)
稍微使用了他们的javascript,Campaign Monitor通过基本上拥有自定义版本的jQuery UI来解决这个问题。他们修改了ui.mouse和ui.sortable来替换对文档和窗口的引用,并使用获取相关元素的文档和窗口的代码。 document
变为this.element[0].ownerDocument
他们有一个名为window()的自定义jQuery函数,它允许用window
或类似代替this.element.window()
。
答案 2 :(得分:3)
我不知道为什么你的代码不起作用。看起来应该是这样。
也就是说,以下是实现此功能的两种替代方法:
如果您可以修改iframe
将JavaScript从父文档移动到iframe-test.html
。这可能是最干净的方式,因为它将JavaScript与其实际执行的元素耦合在一起。
http://dl.dropbox.com/u/3287783/snippets/rarayiframe/sortable-test.html
如果您只控制父文件
使用jQuery .load()方法获取内容而不是HTML iframe。
http://dl.dropbox.com/u/3287783/snippets/rarayiframe2/sortable-test.html
答案 3 :(得分:1)
不是在iFrame中加载jQuery和jQueryUI,而是在父级和子级中评估jQueryUI交互 - 您可以简单地将鼠标事件冒泡到父级文档中:
var ifrDoc = $( '#iframe' ).contents();
$('.sortable', ifrDoc).on('mousemove mouseup', function (event) {
$(parent.document).trigger(event);
});
这样您就可以在父文档上下文中评估所有Javascript。