NoModificationAllowedError in Firefox when using DnD events
Asked Answered
L

1

9

Using some basic drag'n'drop features and i keep getting this message in Firefox, works well in Chrome though.

NoModificationAllowedError: Modifications are not allowed for this document

This happens when i try to use the clearData() function on the event when the ondrop event is fired.

HTML:

<!-- draggable element -->
<div draggable="true" ondragstart="onDragStart(event);">
<!-- dropzone element -->
<div ondragover="onDragOver(event);" ondragenter="onDragEnter(event);" ondrop="onDrop(event);"></div>

JS:

function onDragStart(event) {
    event
        .dataTransfer
        .setData('text/plain', 'test');
}
function onDragOver(event) {
    event.preventDefault();
}
function onDragEnter(event) {
    event.preventDefault(); // polyfill fix
}
function onDrop(event) {
    event.preventDefault();
    event
        .currentTarget
        .parentNode
        .classList.add("dropped");
    event
        .dataTransfer
        .clearData(); //<---- This is where it fails
}

So yeah no idea how to fix this, and i need to clear the data as i set/reset some variable and internal params using it (code omitted). Works well in chrome (even IE)

Lipkin answered 2/10, 2019 at 12:12 Comment(2)
DataTransfer.clearData(): "This method can only be used in the handler for the dragstart event, because that's the only time the drag operation's data store is writeable."Trophy
Yes unfortunately you are right, thanks.Lipkin
G
5

Use Cleardata() method in OnDragStart and not use it in OnDrop() Method.

onDragStart(event) {
    event.dataTransfer.clearData();
    event
        .dataTransfer
        .setData('text/plain', event.target.dataset.item);
}

Must user text/plain. Must use preventDefault() while dropping.

onDragOver(event) {
        event.preventDefault();
    }

Must use preventDefault inside onDrop Method like that.

 onDrop(event) {
        const id = event
            .dataTransfer
            .getData('text');
        const draggableElement = '';
        event.preventDefault();
        this.template.querySelectorAll('.example-draggable').forEach(element => {
            if (element.innerHTML == id) {
                this.draggableElement = element;
            }
        });;
        if ((!event.target.innerText.includes('Drag From Here')) && (!event.target.innerText.includes('Drop Here'))) {
            const bar = event.target.parentElement;
            bar.appendChild(this.draggableElement);
        }
        else {

            const bar = event.target;
            bar.appendChild(this.draggableElement);

        }


    }

here i use preventdefault in middle of the code that will prevent reloading of the page while appending element.

Gerhardine answered 7/6, 2022 at 8:58 Comment(1)
Note that "Must user text/plain" advice is good if you want to be able to drag from one website to another, but that it is not exactly necessary within a single site/application (and it is useful to exclude to prevent dragging from one website to another). See developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/…Leslie

© 2022 - 2025 — McMap. All rights reserved.