jquery ui可拖动的可排序元素到iframe中

时间:2014-01-26 08:20:27

标签: jquery jquery-ui iframe draggable jquery-ui-sortable

我在jquery ui可拖动的可排序元素中遇到麻烦。

部分代码有效here

但我的情况有点不同。实际上我想将一些单词拖到WYSIWYG编辑器中,该编辑器通过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>

在线测试代码here

但是我可以将可排序的元素拖放到创建的iframe中。如何做正确的方法?感谢。

2 个答案:

答案 0 :(得分:3)

更新3

以下解决方案在Chrome Firefox and 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'在IE中效果不佳。我修改了代码以使用IE支持的pasteHTMl,但仍然存在问题,例如,如果单击编辑器然后拖动项目,有时它会替换所有文本。或者,如果您重新调整页面大小,然后在其上拖动更多项目,则会将项目附加到页面顶部而不是编辑器,除非您先在编辑器中单击。我不相信这个解决方案适用于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();
                   }
                });    
            }
        });
    });

答案 1 :(得分: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
    }
});