繁体   English   中英

HTML5,draggable和contentEditable不能一起工作

[英]HTML5,draggable and contentEditable not working together

当在父元素( <li> )上启用了draggable属性时,我无法对其子元素( <a> )进行contenteditable工作。

重点是子元素( <a> ),但我根本无法编辑它。

请检查此样本

http://jsfiddle.net/pavank/4rdpV/11/

编辑:当我在<li>上禁用draggable时,我可以编辑内容

我今天遇到了同样的问题,并找到了一个解决方案[使用jQuery]

$('body').delegate('[contenteditable=true]','focus',function(){
    $(this).parents('[draggable=true]')
            .attr('data-draggableDisabled',1)
            .removeAttr('draggable');
    $(this).blur(function(){
        $(this).parents('[data-draggableDisabled="1"]')
                .attr('draggable','true')
                .removeAttr('data-draggableDisabled');
    });
});

$('body')可以被更具体的东西取代。

如果未在运行时添加新的contenteditable元素,则可以使用bind而不是delegate

有意义的是, draggabledraggable contenteditable属性会发生碰撞。 与任何文本字段一样, contenteditable元素将专注于mousedown(而不是单击)。 draggable元素基于mousemove进行操作,但在contenteditable元素中选择文本也是如此,那么浏览器将如何确定您是在尝试拖动元素还是选择文本? 由于属性不能在同一元素上共存,因此您需要一个javascript解决方案。

尝试将这两个属性添加到锚标记:

onfocus="this.parentNode.draggable = false;"
onblur="this.parentNode.draggable = true;"

如果我将它添加到你的jsFiddle中的<a>标签,这对我有用。 如果它比获取parentNode更复杂,你也可以使用jQuery。

注意:这是一种解决方法,因为我认为这两个功能无法协同工作存在于HTML规范本身(即,由于浏览器无法确定您是否要关注或拖动mousedown,因此无法合作的事情是故意的事件)


我注意到你明确设置'没有库',所以我将提供一个原始的javascript / HTML5答案

http://jsfiddle.net/4rdpV/26/

这是我对它的破解。

首先,最好将数据包含在一个localStorage项中,而不是将其分散。

 storage={ '1.text':'test 1', '2.text':'test 2' } if(localStorage['test']){ storage=JSON.parse(localStorage['test']) } 

这创建了这种能力,使用JSON在对象和字符串之间进行转换。 对象确实可以嵌套

我还添加了(edit)项目旁边的链接,单击这些链接时,这些链接会将项目转换为input元素,因此您可以编辑文本。 点击进入后,它会将其转换回来并保存数据。 同时,列表项仍然可以拖动。

保存后,在chrome中点击F12,找到控制台,然后查看localStorage对象,您将看到所有数据都使用JSON.stringify()作为Object保存在localStorage['test']

我尽力将它设计成可扩展的,我认为我成功了; 你只需要用容器替换HTML并使用javascript for循环来写出几个项目,使用你选择的迭代器来填充edit()的参数。 例如:

假设您更改了存储以保存列表的“范例”,并且您有一个名为“购物清单”的存储。 并说存储对象看起来像这样:

for(i in storage['shopping list']){
    _item = storage['shopping list'][i];
    container.innerHTML+='<li draggable=true><a id="item'+i+'">'+_item+'</a><a href="#" onclick="edit('+i+')"> (edit)</a></li>'
}

这可能会导致列出:

 for(i in storage['shopping list']){ _item = storage['shopping list'][i]; container.innerHTML+='<li draggable=true><a id="item'+i+'">'+_item+'</a><a href="#" onclick="edit('+i+')"> (edit)</a></li>' } 

当然,如果要编辑存储对象的结构,则还需要编辑这些函数。

输出看起来像这样:

 Milk (edit) Eggs (edit) Bread (edit) 

如果您担心,请不要担心输入元素; CSS可以很容易地修复它看起来不仅仅是改变。

例如,如果您不希望(edit)链接可见,则可以在CSS中执行此操作:

 a[href="#"]{ display:none; } li[draggable="true"]:hover a[href="#"]{ display:inline; } 

现在只有将鼠标悬停在列表项上时才会显示编辑链接,如此版本:

http://jsfiddle.net/4rdpV/27/


我希望这个答案有所帮助。

使用html5sortable和更新的JQuery事件(委托已被弃用,在初始问题后3年回答),bug仍然影响Chrome 37. Contenteditable spans和html5sortable似乎在其他浏览器中表现不错。 我知道这只是部分相关,只是记录我注意到的变化。

$(document).on('focus', 'li span[contenteditable]', function() {
    $(this).parent().parent().sortable('destroy'); // removes sortable from the whole parent UL
});

$(document).on('blur', 'li span[contenteditable]', function() {
    $(this).parent().parent().sortable({ connectWith: '.sortable' }); // re-adds sortable to the parent UL
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM