Milos Novakovic
Milos Novakovic

Reputation: 1

How to fix SCRIPT5007: Unable to get property 'parentNode' of undefined or null reference in Internet Explorer 11?

my code works fine on other browsers but on Internet Explorer 11 I get SCRIPT5007: Unable to get property 'parentNode' of undefined or null reference. Does anyone know how to fix that bug? Here is my code:

var selected

function dragOver(e) {
  if (isBefore(selected, e.target)) e.target.parentNode.insertBefore(selected, e.target)
  else e.target.parentNode.insertBefore(selected, e.target.nextSibling)
}

function dragEnd() {
  selected = null
}

function dragStart(e) {
  e.dataTransfer.effectAllowed = "move"
  e.dataTransfer.setData("text/plain", null)
  selected = e.target
}

function isBefore(el1, el2) {
  var cur;
  if (el2.parentNode === el1.parentNode) {
    for (cur = el1.previousSibling; cur; cur = cur.previousSibling) {
      if (cur === el2) return true
    }
  } else return false;
}
<div class="sequence">
  <div draggable="true" ondragend="dragEnd()" ondragover="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="3">Yellow</div>
  <div draggable="true" ondragend="dragEnd()" ondragover="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="5">Red</div>
  <div draggable="true" ondragend="dragEnd()" ondragover="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="2">Green</div>
  <div draggable="true" ondragend="dragEnd()" ondragover="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="1">Blue</div>
  <div draggable="true" ondragend="dragEnd()" ondragover="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="4">Orange</div>
</div>

Upvotes: 0

Views: 877

Answers (2)

Yu Zhou
Yu Zhou

Reputation: 12961

I tested your code and the error occurred firstly in e.dataTransfer.setData("text/plain", null) with argument being not valid. There're two errors in this line:

  1. IE only accepts text and URL as valid data types. You could refer to this article for explanation:

    Even though Internet Explorer started out by introducing only "text" and "URL" as valid data types, HTML5 extends this to allow any MIME type to be specified. The values "text" and "URL" will be supported by HTML5 for backwards compatibility, but they are mapped to "text/plain" and "text/uri-list".

  2. We should use a concrete value as data instead of null in IE. We can use the event target's id for the data.

So this line should be changed into: e.dataTransfer.setData("text", e.target.id).

After this, we need to change ondragover events to ondragenter as I find that ondragover won't be fired in IE. So the final code should be like below which can work well in IE 11:

var selected

function dragOver(e) {
  if (isBefore(selected, e.target)) e.target.parentNode.insertBefore(selected, e.target)
  else e.target.parentNode.insertBefore(selected, e.target.nextSibling)
}

function dragEnd() {
  selected = null
}

function dragStart(e) {
  e.dataTransfer.effectAllowed = "move"
  e.dataTransfer.setData("text", e.target.id)
  selected = e.target
}

function isBefore(el1, el2) {
  var cur;
  if (el2.parentNode === el1.parentNode) {
    for (cur = el1.previousSibling; cur; cur = cur.previousSibling) {
      if (cur === el2) return true
    }
  } else return false;
}
<div class="sequence">
  <div draggable="true" ondragend="dragEnd()" ondragenter="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="3">Yellow</div>
  <div draggable="true" ondragend="dragEnd()" ondragenter="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="5">Red</div>
  <div draggable="true" ondragend="dragEnd()" ondragenter="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="2">Green</div>
  <div draggable="true" ondragend="dragEnd()" ondragenter="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="1">Blue</div>
  <div draggable="true" ondragend="dragEnd()" ondragenter="dragOver(event)" ondragstart="dragStart(event)" class="choice 2" id="4">Orange</div>
</div>

Online demo

Upvotes: 1

Cornholio
Cornholio

Reputation: 33

Try something like this in your event handlers:

function dragOver( e ) {
  if (!e) e = window.event;
  if ( isBefore( selected, e.target ) ) e.target.parentNode.insertBefore( selected, e.target )
  else e.target.parentNode.insertBefore( selected, e.target.nextSibling )
}

Reference: https://docstore.mik.ua/orelly/webprog/jscript/ch19_03.htm (19.3.2. The IE Event Object as a Global Variable)

Upvotes: 0

Related Questions