首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >精确的拖放在可满足的范围内

精确的拖放在可满足的范围内
EN

Stack Overflow用户
提问于 2018-05-09 01:27:45
回答 2查看 0关注 0票数 0

设置

因此,我有一个可满足的div--我正在制作一个WYSIWYG编辑器:粗体、斜体、格式,以及最近的:插入花哨的图像(在花哨的框中加上标题)。

代码语言:txt
复制
<a class="fancy" href="i.jpg" target="_blank">
    <img alt="" src="i.jpg" />
    Optional Caption goes Here!
</a>

用户使用我提供的对话框添加这些花哨的图像:它们填写详细信息,上传图像,然后就像其他编辑器函数一样,我使用document.execCommand('insertHTML',false,fancy_image_html);在用户选择时将其插入。

首先,我建立了我的幻想<a>带有可拖放属性的标记,并禁用了Contentedable(不确定这是否必要,但它似乎也可能是OFF):

代码语言:txt
复制
<a class="fancy" [...] draggable="true" contenteditable="false">

然后,因为用户仍然可以将图像从幻想中拖出来。<a>盒子,我得做些CSS。我在Chrome工作,所以我只给你看-webkit前缀,虽然我也用了其他的。

代码语言:txt
复制
.fancy {
    -webkit-user-select:none;
    -webkit-user-drag:element; }
    .fancy>img {
        -webkit-user-drag:none; }

HTML 5的JavaScript拖放API

这个拖放的东西似乎比需要的更复杂。

因此,我开始深入研究DNDAPI文档,现在我陷入了困境。

代码语言:txt
复制
$('.fancy')
    .bind('dragstart',function(event){
        //console.log('dragstart');
        var dt=event.originalEvent.dataTransfer;
        dt.effectAllowed = 'all';
        dt.setData('text/html',event.target.outerHTML);
    });

$('.myContentEditable')
    .bind('dragenter',function(event){
        //console.log('dragenter');
        event.preventDefault();
    })
    .bind('dragleave',function(event){
        //console.log('dragleave');
    })
    .bind('dragover',function(event){
        //console.log('dragover');
        event.preventDefault();
    })
    .bind('drop',function(event){
        //console.log('drop');      
        var dt = event.originalEvent.dataTransfer;
        var content = dt.getData('text/html');
        document.execCommand('insertHTML',false,content);
        event.preventDefault();
    })
    .bind('dragend',function(event){ 
        //console.log('dragend');
    });

我找不到正确的放置位置,也找不到插入的任何方法。我一直希望能找到某种“落点”对象将我的花哨盒倒入其中,类似于dropEvent.dropLocation.content=myFancyBoxHTML;或者,至少是某种位置值,可以用来找到我自己的方法将内容放在那里?我得到什么了吗?

我做错了吗?我是不是完全错过了什么?

Farrukh发表了一个很好的建议---使用:

代码语言:txt
复制
console.log( window.getSelection().getRangeAt(0) );

查看选择插入符实际位于何处。我把这个塞进了拖把机事件,它是指选择插入符号明显地在可内容中的可编辑内容之间跳来跳去。

我在读,并发现:

当然,可能还需要在Dragover事件周围移动插入标记。可以像其他鼠标事件一样使用事件的clientX和clientY属性来确定鼠标指针的位置。

EN

回答 2

Stack Overflow用户

发布于 2018-05-09 09:52:30

这不是一个强有力的或完整的解决方案;我可能永远不会想出一个解决方案。如果有人有更好的解决方案,我会全神贯注--我不想这样做,但这是我到目前为止能找到的唯一途径。下面的jsFiddle,以及我将要吐出来的信息,在我的特定Wamp安装程序和计算机上与我的Firefox和Chrome的特定版本一起为我工作。

HTML 5的拖放API乍一看也是可怕的.然后,当你开始理解和接受它的方式时,你几乎会对它热身。

所以,我是怎么做到的任意HTML元素的精确拖放在多个可内容的内部、周围和之间。

我的解决方案

  • 首先,我将CSS应用于可拖式(FancyBox)--我们需要user-select:none; user-drag:element;在花哨的盒子上,然后user-drag:none;在图片中的花式框(和任何其他元素,为什么不呢?)不幸的是,对于Firefox来说,这还不够,因为Firefox需要属性draggable="false"在图像上显式设置以防止其被拖放。
  • 接下来,我应用了属性draggable="true"dropzone="copy"在内容上。

我们将dataTransfer设置为复制HTML‘’的空字符串--因为我们需要欺骗它,让它以为我们要拖动HTML,但是我们正在取消任何默认行为。

代码语言:txt
复制
DD.$draggables.off('dragstart').on('dragstart',function(event){
    var e=event.originalEvent;
    $(e.target).removeAttr('dragged');
    var dt=e.dataTransfer,
        content=e.target.outerHTML;
    var is_draggable = DD.$draggables.is(e.target);
    if (is_draggable) {
        dt.effectAllowed = 'copy';
        dt.setData('text/plain',' ');
        DD.dropLoad=content;
        $(e.target).attr('dragged','dragged');
    }
});

Chrome和Firefox有不同的获取范围对象的方法,因此,在DROP事件中,每个浏览器都必须付出不同的努力才能做到这一点。Chrome基于鼠标坐标(是的,没错),但是Firefox在事件数据中提供了它。document.execCommand('insertHTML',false,blah)结果就是我们如何处理掉的。哦,我忘了-我们不能用dataTransfer.getData()在Chrome上得到我们的拖动启动设置HTML-它似乎是规范中的某种奇怪的错误。

代码语言:txt
复制
DD.$dropzones.off('dragleave').on('dragleave',function(event){
    var e=event.originalEvent;

    var dt=e.dataTransfer;
    var relatedTarget_is_dropzone = DD.$dropzones.is(e.relatedTarget);
    var relatedTarget_within_dropzone = DD.$dropzones.has(e.relatedTarget).length>0;
    var acceptable = relatedTarget_is_dropzone||relatedTarget_within_dropzone;
    if (!acceptable) {
        dt.dropEffect='none';
        dt.effectAllowed='null';
    }
});
DD.$dropzones.off('drop').on('drop',function(event){
    var e=event.originalEvent;

    if (!DD.dropLoad) return false;
    var range=null;
    if (document.caretRangeFromPoint) { // Chrome
        range=document.caretRangeFromPoint(e.clientX,e.clientY);
    }
    else if (e.rangeParent) { // Firefox
        range=document.createRange(); range.setStart(e.rangeParent,e.rangeOffset);
    }
    var sel = window.getSelection();
    sel.removeAllRanges(); sel.addRange(range);

    $(sel.anchorNode).closest(DD.$dropzones.selector).get(0).focus(); // essential
    document.execCommand('insertHTML',false,'<param name="dragonDropMarker" />'+DD.dropLoad);
    sel.removeAllRanges();

    // verification with dragonDropMarker
    var $DDM=$('param[name="dragonDropMarker"]');
    var insertSuccess = $DDM.length>0;
    if (insertSuccess) {
        $(DD.$draggables.selector).filter('[dragged]').remove();
        $DDM.remove();
    }

    DD.dropLoad=null;
    DD.bindDraggables();
    e.preventDefault();
});
票数 0
EN

Stack Overflow用户

发布于 2018-05-09 11:24:01

  1. 事件拖放启动;dataTransfer.setData("text/html", "<div class='whatever'></div>");
  2. 事件删除:var me = this; setTimeout(function () { var el = me.element.getElementsByClassName("whatever")[0]; if (el) { //do stuff here, el is your location for the fancy img } }, 0);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档