【问题标题】:JavaScript: array values are automatically getting deletedJavaScript:数组值会自动被删除
【发布时间】:2020-12-29 02:41:34
【问题描述】:

我正在制作图像滑块/轮播。如果拖动它,图像将获得动力,并会继续移动一段时间。很少有问题,其中之一是经常收到以下错误:“glide.js:104 Uncaught TypeError: Cannot read property '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>

【问题讨论】:

  • (lastMousePositions[lastMousePositions.length - 1])[1] 上面的代码表明lastMousePositions 是一个数组数组(二维数组)。是这样吗?
  • 是的,子数组里面有mouseposition,以及插入位置的时间
  • 在 mousedown 事件监听器中检查第 44 行:lastMousePositions.push(e.clientX) 你推送的不是数组。会不会是这个问题?
  • 感谢您指出,这可能会增加错误的频率,不幸的是,我在用pushToMousePositions(e.clientX)替换它后遇到了错误

标签: javascript html css undefined typeerror


【解决方案1】:

问题是这样的:

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;
          }
  }

【讨论】:

  • 非常感谢!好几个星期以来我一直在研究这个问题,但还是想不通
猜你喜欢
  • 2012-08-18
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多