将jQuery UI可拖动排序元素嵌入iframe中

4

我在将JQuery UI可拖动排序元素放入iframe中遇到了一些问题。

参考这里,有些代码可以正常运行。

但是我的情况略有不同。事实上,我想将一些单词拖到由JavaScript创建的所见即所得编辑器中的iframe中。代码如下:

<script type='text/javascript'>
$(document).ready(function(){
    $("#input").cleditor();
    setInterval(function(){
    $('.draggable').draggable({
        appendTo:'body',
        helper:'clone',
        iframeFix: true,
        revert:'invalid',
        connectToSortable:$('#w-edit').contents().find('#sortable').sortable({
            iframeFix: true,
            cursorAt:{top:0,left:0} 
        }),
        cursorAt:{top:0,left:0} 
    });
    },1000);
}); 
</script>
<body id="my-body">
<ul>
  <li class="draggable">Drag me</li>
  <li class="draggable">Drag me 2</li>
  <li class="draggable">Drag me 3</li>
</ul>
<textarea id="input" name="input"></textarea>
</body>

在线测试代码在此处

但是我将可拖动的可排序元素放入了创建的iframe中。怎样才能做到正确的方法呢?谢谢。

2个回答

3

更新 3

以下解决方案在 Chrome、Firefox 和 Safari 中比较稳定:

var $editor = $("#input").cleditor()[0];
var focused = false;
var isFirefox = typeof InstallTrigger !== 'undefined';
var text = '';
$('.draggable').draggable({
        appendTo:'body',
        helper:'clone',
        iframeFix: true,
        revert:'invalid',
        cursorAt:{top:0,left:0} 
});

$("#w-edit").droppable({
    drop: function (event, ui) {
        text = ui.draggable.text();
        if(!focused && !isFirefox)
            $editor.focus();
        else
            $editor.focused(); 
    }
});

$editor.focused(function(){
    if(text != ''){
        $editor.execCommand('inserthtml',text, false);
        text = '';
    }
    focused = true;
});

$editor.blurred(function(){
    focused = false;    
});

$editor.change(function(){
    if(!$('#w-edit').hasClass('ui-droppable')){
        focused = false;
        $("#w-edit").droppable({
            drop: function (event, ui) {
                text = ui.draggable.text();
                if(!focused && !isFirefox)
                    $editor.focus();
                else
                    $editor.focused();
           }
        });    
    }
});

http://jsfiddle.net/C3cFk/

我发现的唯一问题是,如果你重新调整窗口大小,然后拖动一个项目,可能无法预测新拖动的项目在文本区域中显示的位置。老实说,我不知道该如何解决这个问题,而且因为 IE 的问题,我有些心力憔悴,尝试使其正常工作。

IE 问题

在 IE 中(测试过 IE 10),除非每次都点击编辑器,否则它的效果不好,因为有一半的时间单词会相互覆盖。execCommand('inserthtml' 不起作用或者不太好用。我修改了代码,使用pasteHTMl,这是 IE 支持的,但仍然存在问题,例如如果您在编辑器外面单击并拖动元素,有时会替换所有文本。或者如果您调整页面大小,然后再拖动更多元素,则会将元素附加到页面顶部而不是编辑器,除非您首先在编辑器中单击。我不认为这个解决方案适用于IE8,因为还有更多限制需要处理,而我没有简单的测试或开发 IE8 的方法,所以我将放弃 IE8。

这是我为IE10找到的最佳解决方案:

$(document).ready(function(){
        var $editor = $("#input").cleditor()[0];
        var focused = false;
        var text ='';
        var temp;
        $('.draggable').draggable({
                appendTo:'body',
                helper:'clone',
                iframeFix: true,
                revert:'invalid',
                cursorAt:{top:0,left:0} 
        });

        $("#w-edit").droppable({
            drop: function (event, ui) {
                temp = $(this).contents().find("html body")[0];
                text = ui.draggable.text();
                if(!focused)
                    $editor.focus();
                else
                    $editor.focused(); 
            }
        });

        $editor.focused(function(){
            if(text != ''){
                var doc = document.getElementById("w-edit").contentWindow.document;
                if (doc.selection && doc.selection.createRange) {
                    var range = doc.selection.createRange();
                    if (range.pasteHTML) {
                        range.pasteHTML(text);
                    }
                }
                $editor.updateTextArea();
                text = '';
            }
            focused = true;
        });

        $editor.blurred(function(){
            focused = false;    
        });

        $editor.change(function(){
            if(!$('#w-edit').hasClass('ui-droppable')){
                $("#w-edit").droppable({
                    drop: function (event, ui) {
                        temp = $(this).contents().find("html body")[0];
                        text = ui.draggable.text();
                        if(!focused)
                            $editor.focus();
                        else
                            $editor.focused();
                   }
                });  
            }
        }); 
    });

总的来说,这种东西在所有浏览器中似乎都很难搞定。为了使其正常工作,我不得不针对每个浏览器进行不同的处理。

注意:

我已经在IE8上测试了我的先前回答中的代码(你曾经说它在IE8上无法工作,文本不会出现在光标所在位置),并且对我有效。(请确保您的浏览器模式和文档模式为IE8):

$(document).ready(function(){
        var $editor = $("#input").cleditor()[0];
        $('.draggable').draggable({
                appendTo:'body',
                helper:'clone',
                iframeFix: true,
                revert:'invalid',
                cursorAt:{top:0,left:0} 
        });

        $("#w-edit").droppable({
            drop: function (event, ui) {
                console.log('drop');
                $(this).contents().find("html body").append(ui.draggable.text()+' '); 
                $editor.updateTextArea();
            }
        });

        $editor.change(function(){
            if(!$('#w-edit').hasClass('ui-droppable')){
                $("#w-edit").droppable({
                    drop: function (event, ui) {
                        $(this).contents().find("html body").append(ui.draggable.text()+' '); 
                        $editor.updateTextArea();
                   }
                });    
            }
        });
    });

@Giberno,请您给我反馈,如果这个回答没有解决您的问题,那么我会努力寻找一个对您可接受的解决方案。 - Trevor
感谢更新。现在Chrome可以使用了。但仍有两个问题:1.我能否在任何鼠标光标后拖动单词,而不仅仅是在所见即所得编辑器的末尾?2.IE位置不太好用。谢谢和问候。 - Giberno
@Giberno 我有一个关于 #2 在IE中位置不正确 的问题。你是指它在IE中无法工作吗?你使用的IE版本是什么?即使在IE10中,cleditor也可以正常加载,我可以研究一下,但似乎这是插件本身的问题。 - Trevor
@Giberno 你可以查看我的最新更新,这是我能做到的最好的。当涉及到浏览器兼容性时,使用WYSIWYG编辑器实现拖放功能非常困难。 - Trevor
@revor,现在它可以工作了。顺便问一下,“var $editor = $("#input").cleditor()[0];”是什么意思? - Giberno
@Giberno 我从文档中获取了它,我相信它只是引用第一个编辑器对象。在你的例子中只有一个。然后我就能够调用一些方法,比如 focus 等。 - Trevor

0

解决这个问题的方法:

$("#input").cleditor();
setInterval(function(){
$('.draggable').draggable({
    appendTo:'body',
    helper:'clone',
    iframeFix: true,
    revert:'invalid',
    connectToSortable:$('#w-edit').contents().find('#sortable').sortable({
        iframeFix: true,
        cursorAt:{top:0,left:0} 
    }),
    cursorAt:{top:0,left:0} 
});
},1000);
$( "#w-edit" ).droppable({
   drop: function( event, ui ) {
       $('#w-edit').val(defaultText);//defaultText is dummy parameter,here we can use anyname
    }
});

一旦你拖动了一个项目,就不能再次拖动它了。http://jsfiddle.net/aamir/3PAv9/8/ - Aamir Afridi
1
请查看此链接:http://jsfiddle.net/8Jwxv/42/ -- 可以随意拖动任意次数,没有限制。 - chinnu
@chinnu,你的代码可以将项目拖入iframe,但位置混乱,该项目应插入到所写的WYSIWYG编辑器句子中,而不是任何地方。如果我再次拖动它(在iframe部分),它会复制更多内容,而不是移动。 - Giberno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接