HTML5,draggable和contentEditable不能一起工作

时间:2011-06-18 21:58:28

标签: javascript html5

在父元素(draggable)上启用<li>属性时,我无法使contenteditable处理其子元素(<a>)。

焦点转移到子元素(<a>),但我根本无法编辑它。

请查看此示例

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

编辑:我可以在draggable

上停用<li>时修改内容

4 个答案:

答案 0 :(得分:7)

我今天遇到了同样的问题,并找到了一个解决方案[使用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

答案 1 :(得分:4)

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

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

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

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

答案 2 :(得分:1)

注意:这是一种解决方法,因为我认为这两个功能无法协同工作存在于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对象,您将看到所有数据都使用localStorage['test']

作为对象保存在JSON.stringify()

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

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

{
    "shopping list":{
         1:"Milk",
         2:"Eggs",
         3:"Bread"
    }
}

这可以将该列表呈现出来:

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/

<小时/> 我希望这个答案有所帮助。

答案 3 :(得分:1)

使用html5sortable和更新的JQuery事件(委托已被弃用,在初始问题后3年回答),bug仍会影响Chrome 37.可疑的跨度和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
});