JavaScript: 数组值被自动删除

JavaScript: array values are automatically getting deleted

我正在制作图像滑块/旋转木马。如果拖动它,图像将获得动力并会持续移动一段时间。问题很少,其中之一是经常出现以下错误:“glide.js:104 Uncaught TypeError: Cannot read 属性 '1' of undefined”。 JavaScript 此处应该访问数组内的值,但由于数组为空,所以出现此错误。但是,数组不应该为空,因为清空数组的代码稍后出现。 Project

var projectContainer = document.querySelector(".project-container")
var projects = document.querySelectorAll(".project")

// exProject is declared so that every project has same transalte to refer to instead of referring to their individual transalations
var exProject = projects[0]
var style = window.getComputedStyle(exProject)
exProject.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41

// after dragging, do not add force if mouse has not been moved for pauseTime milliseconds
pauseTime = 40
lastMousePositions = []

//this will set margin to 80, i thought this is better than hardcoding
elementAOffset = projects[0].offsetLeft;
elementBOffset = projects[1].offsetLeft;
elementAWidth = parseInt(getComputedStyle(projects[0]).width)
margin = (elementBOffset - (elementAOffset + elementAWidth))

//projects will teleport to other side if they hit either of the boundary
LeftSideBoundary = -(elementAWidth)
RightSideBoundary = (elementAWidth * (projects.length)) + (margin * (projects.length))

RightSidePosition = RightSideBoundary - elementAWidth;

//how often to update speed (in milliseconds)
intervalTime = 15

//how much speed is lost at every interTime milliseconds
frictionPerMilliseconds = (20 / 1000);
frictionPerMilliseconds *= intervalTime * 5;

mouseInitialPosition = 0;
mouseIsDown = false
startTime = 0;
speed = 0;
mousemoving = false


projectContainer.addEventListener("mousedown", e => {
  mouseInitialPosition = e.clientX
  mouseIsDown = true;
  startDate = new Date();
  startTime = startDate.getTime();
  lastMousePositions.push(e.clientX)
  speed = 0
})


projectContainer.addEventListener("mousemove", e => {
  if (!mouseIsDown) return;
  distanceTravelled = e.clientX - mouseInitialPosition

  if (speed === 0) {
    projects.forEach(project => {
      project.style.transform = 'translateX(' + ((exProject.currentTranslationX) + ((distanceTravelled))) + 'px)';
      shiftPosition(project, distanceTravelled)
    })
  }

  if ((new Date()).getTime() - lastMousePositions[lastMousePositions.length - 1][1] > 50) {
    lastMousePositions = []
  }
  pushToMousePositions(e.clientX)

})


projectContainer.addEventListener("mouseup", e => {
  dragEnd(e);
})

projectContainer.addEventListener("mouseleave", e => {
  dragEnd(e);
})

function dragEnd(e) {
  finalPosition = e.clientX;
  distanceTravelled = finalPosition - mouseInitialPosition
  endDate = new Date();
  endTime = endDate.getTime();

  timeElapsed = (endTime - startTime) / 1000

  mouseIsDown = false;

  tempSpeed = distanceTravelled / timeElapsed
  tempSpeed = (tempSpeed / 1000) * 15

  if (tempSpeed < 0 && speed < 0) {
    if (tempSpeed < speed) {
      speed = tempSpeed
    }
  } else if (tempSpeed > 0 && speed > 0) {
    if (tempSpeed > speed) {
      speed = tempSpeed
    }
  } else {
    speed = tempSpeed
  }

  if (lastMousePositions.length === 0) {
    console.log("error gonna pop up")
  }
  if (endTime - (lastMousePositions[lastMousePositions.length - 1])[1] >= pauseTime) {
    speed = 0
  }
  mouseExit(e)
  intervalFunction = setInterval(move, intervalTime)
}

function mouseExit(e) {
  mouseIsDown = false
  lastMousePositions = []

  var style = window.getComputedStyle(exProject)
  exProject.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41

  projects.forEach(project => {
    project.style.transform = 'translateX(' + (exProject.currentTranslationX) + 'px)'
    shiftPosition(project, 0)
  })
}

function move() {
  if (speed === 0) {
    clearInterval(intervalFunction)

  } else if (Math.abs(speed) <= frictionPerMilliseconds) {
    style = window.getComputedStyle(exProject)
    exProject.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41

    projects.forEach(project => {
      project.style.transform = 'translateX(' + ((exProject.currentTranslationX) + (speed)) + 'px)'
      shiftPosition(project, 0)
    })
    speed = 0
  } else {
    style = window.getComputedStyle(exProject)
    exProject.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41

    projects.forEach(project => {
      project.style.transform = 'translateX(' + ((exProject.currentTranslationX) + (speed)) + 'px)'
      shiftPosition(project, 0)
    })

    speed < 0 ? speed += frictionPerMilliseconds : speed -= frictionPerMilliseconds;

  }
}


function pushToMousePositions(positionToPush) {
  if (lastMousePositions.length < 50) {
    lastMousePositions.push([positionToPush, (new Date()).getTime()])
  } else {
    lastMousePositions.shift();
    lastMousePositions.push([positionToPush, (new Date()).getTime()])
  }
}

function shiftPosition(project, mouseMovement) {

  //projectVisualPosition is relative to the left border of container div
  projectVisualPosition = project.offsetLeft + (exProject.currentTranslationX + mouseMovement)
  tempStyle = window.getComputedStyle(project)

  if (projectVisualPosition < LeftSideBoundary) {
    project.style.left = ((parseInt(tempStyle.left) + RightSidePosition + 350) + 'px')
  }
  if (projectVisualPosition > RightSidePosition) {
    project.style.left = ((parseInt(tempStyle.left)) - (RightSidePosition + elementAWidth)) + 'px'
  }
}
*,
*::before,
*::after {
  margin: 0px;
  padding: 0px;
  box-sizing: border-box;
  font-size: 0px;
  user-select: none;
  font-size: 0;
}

body {
  position: relative;
}

.project-container {
  font-size: 0px;
  position: relative;
  width: 1500px;
  height: 400px;
  background-color: rgb(15, 207, 224);
  margin: auto;
  margin-top: 60px;
  white-space: nowrap;
  overflow: hidden;
  padding-left: 40px;
  padding-right: 40px;
}

.project {
  font-size: 100px;
  margin: 40px;
  display: inline-block;
  height: 300px;
  width: 350px;
  background-color: red;
  border: black 3px solid;
  user-select: none;
  position: relative;
}
<div class="project-container">
  <div class="project">1</div>
  <div class="project">2</div>
  <div class="project">3</div>
  <div class="project">4</div>
  <div class="project">5</div>
  <div class="project">6</div>
  <div class="project">7</div>
  <div class="project">8</div>
</div>

问题是这样的:

projectContainer.addEventListener("mouseleave", (e) => {
        dragEnd(e);
});

您在光标离开 projectContainer 时调用 dragEnd(e)。这可能会在 lastMousePositions 数组仍为空时发生。

选项 1:不要在 mouseleave 事件中调用 dragEnd(e)

选项 2:在 dragEnd(e) 函数内,在尝试访问其元素之前检查数组是否为空:

if (lastMousePositions.length !== 0) {
          if (
            endTime - lastMousePositions[lastMousePositions.length - 1][1] >=
            pauseTime
          ) {
            speed = 0;
          }
  }