2013-06-03 6 views
10

मैं कुछ ड्रैगगेबल तत्व (टोकन) बनाने की कोशिश कर रहा हूं जिसे एक संतोषजनक div के अंदर खींच लिया जा सकता है। ऐसा लगता है कि सबकुछ इसके अलावा काम कर रहा है ... जब मैं एक तत्व खींचता हूं और इसे छोड़ देता हूं, तो मैं इसे फिर से खींच नहीं सकता। ऐसा लगता है कि मैं इसे ड्रैगस्टार्ट ईवेंट से फिर से बांध नहीं सकता।एचटीएमएल 5 सामग्रीग्रस्त div के भीतर खींचने योग्य तत्व - पहली बूंद के बाद काम करना बंद कर देता है - क्यों?

किसी भी विचार क्यों ऐसा होता है और मैं इसे कैसे ठीक कर सकते हैं?

यहाँ मेरी बेला के लिए एक लिंक है: http://jsfiddle.net/gXScu/1/

HTML:

<div id="editor" contenteditable="true"> 
    Testime siinkohal seda, et kuidas<br /> 
    on võimalik asja testida. 
    <span class="draggable" draggable="true" contenteditable="false">Token</span> 
</div> 
<span class="draggable" draggable="true" contenteditable="false">Token 2</span> 

जावास्क्रिप्ट (jQuery)

var bindDraggables = function() { 
    console.log('binding draggables', $('.draggable').length); 
    $('.draggable').off('dragstart').on('dragstart', function(e) { 
     if (!e.target.id) 
      e.target.id = (new Date()).getTime(); 
     e.originalEvent.dataTransfer.setData('text/html', e.target.outerHTML); 
     console.log('started dragging'); 
     $(e.target).addClass('dragged'); 
    }).on('click', function() { 
     console.log('there was a click'); 
    }); 
} 

$('#editor').on('dragover', function (e) { 
    e.preventDefault(); 
    return false; 
}); 

$('#editor').on('drop', function(e) { 
    e.preventDefault(); 
    var e = e.originalEvent; 
    var content = e.dataTransfer.getData('text/html'); 
    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); 
    } 
    console.log('range', range) 
    var sel = window.getSelection(); 
    sel.removeAllRanges(); sel.addRange(range); 

    $('#editor').get(0).focus(); // essential 
    document.execCommand('insertHTML',false, content); 
    //$('#editor').append(content); 
    sel.removeAllRanges(); 
    bindDraggables(); 
    console.log($('[dragged="dragged"]').length); 
    $('.dragged').remove(); 
}); 

bindDraggables(); 

सीएसएस:

#editor { 
    border: 2px solid red; 
    padding: 5px; 
} 
.draggable { 
    display: inline-block; 
    padding: 3px; 
    background: yellow; 
    cursor: move !important; 
} 
+0

यह फ़ायरफ़ॉक्स पर पूरी तरह से ठीक काम करता है, इसलिए संभवतः यह क्रोम की बग है। और यह तब होता है जब आप 'insertHTML' कमांड का उपयोग करते हैं। जब मैंने इसे '$ (' # editor ') के साथ बदल दिया। संलग्न करें (सामग्री)' सब कुछ ठीक काम करता है ... – Reinmar

उत्तर

8

मैंने कुछ हैक्स भी कोशिश की लेकिन उनमें से कोई भी काम नहीं कर रहा है। मैं HTML निरीक्षण किया गया था और मैंने पाया कि अपने उदाहरण में नव डाला सामग्री किसी भी contenteditable विशेषता सौंपा नहीं है और जब मैं मैन्युअल रूप से तो यह करने के लिए आवंटित यह काम कर रहा ठीक शुरू कर दिया।

यहाँ मेरी कोड http://jsfiddle.net/gXScu/8/

मैं सिर्फ bindDraggables विधि में इस लाइन

$('.draggable').attr("contenteditable", false); जोड़ा है।

मैं सामग्री पर रेनमार स्पष्टीकरण के साथ सहमत हूं।

+0

+1। ध्यान दिया जाना चाहिए :) :)। – Reinmar

+1

@ रेनमार: :-)। तो ऐसा लगता है कि अगर हम 'दस्तावेज़ के माध्यम से' insertHTML 'करते हैं।execCommand 'तो क्रोम चुपचाप' contenteditable 'विशेषता को हटा रहा है :-)। –

+0

फ़ायरफ़ॉक्स और क्रोम दोनों 'document.execCommand (' insertHTML ', false, content) का उपयोग करने के साथ असंगत परिणाम दे सकते हैं;'। इसे ठीक करने के लिए, इसे 'pasteHtmlAtCaret (सामग्री)' में बदलें। फ़ंक्शन यहां पाया जा सकता है: http://stackoverflow.com/questions/6690752/insert-html-at-caret-in-a-contentitable-div/6691294#6691294 – castt

1

जाहिर क्रोम एक बग है(आश्चर्य नहीं - contenteditable सभी ब्राउज़रों में सबसे छोटी गाड़ी सुविधा है)। आपका कोड फ़ायरफ़ॉक्स पर पूरी तरह से ठीक काम करता है, लेकिन कुछ कारणों से insertHTML कमांड के साथ संपादन योग्य में डाला गया तत्व अब और नहीं खींचा जा सकता है।

मैं कुछ हैक्स कोशिश की, लेकिन केवल एक ही काम किया - अन्य तत्व सम्मिलित करके और फिर जगह।

बजाय:

document.execCommand('insertHTML', false, content); 

कुछ इस तरह का प्रयोग करें:

var spanId = 'temp-' + (new Date()).getTime(); 

// Insert span with zero-width space (so it isn't visible and it isn't empty). 
document.execCommand('insertHTML', false, '<span id="' + spanId + '">\u200b</span>'); 
// Replace that span with our dragged content. 
$('#' + spanId).replaceWith(content); 

आप इस यहाँ की कोशिश कर सकते हैं: http://jsfiddle.net/gXScu/5/। मैंने इसके गलत क्रम को भी सही किया:

$('.dragged').remove(); 
bindDraggables(); 
+1

यह एक पूरी तरह से वैध उत्तर और एक अच्छी व्याख्या है, धन्यवाद! मैंने इमरान के जवाब को चुना है हालांकि यह थोड़ा अधिक सरल है और इसे अतिरिक्त तत्व बनाने की आवश्यकता नहीं है। – ragulka

+0

आईएमओ गायब होने वाली एकमात्र चीज यह दिखाने के लिए कैरेट सूचक है कि माउसअप के बाद आइटम कहां रखा जा रहा है। क्या यह किसी भी तरह से संभव है? – displayname

संबंधित मुद्दे

 संबंधित मुद्दे