我是JavaScript的初学者。我为我创建了一些有趣的项目来练习JavaScript并享受乐趣。虽然我遇到了一些奇怪的情况。我有Windows 10 PC和MacBook Pro。有了我在PC普通鼠标和MBP上我也有魔术鼠标2.我在Chrome上测试了所有(请使用chrome)。当我使用触控板滚动时,悬停不会触发。它转到onHover函数但在if语句处失败。我用魔法鼠标2或用鼠标在PC上试试这个,它的效果非常好。只是你知道,当你滚动以便面板堆叠时,当你用鼠标悬停它们时,它们会移动(窥视)。 但这是另一个错误(我不知道如何调试或解决它)。如果你快速滚动一些面板会很奇怪(保持原位或移动不同于其他面板)。
你能帮帮我吗?TL; DR:为什么触控板不会像鼠标一样触发悬停,为什么快速滚动的某些面板表现得很奇怪?
编辑:因为我不知道这件事是否会在这里工作,我发布了ZIP文件的链接,所以你可以下载并在本地查看。
const boxes = Array.from(document.querySelectorAll(".box"));
const wrapper = document.querySelector(".wrapper");
const body = document.querySelector("body");
const box = document.querySelectorAll(".box");
const hoverMargin = 100; //px
let leftMargin = 60; //px
let hoverExtendFlag = false; // flag to update if on hover panels are extended
let boxesFlagArray = []; // flag for stacked panels
for(var i = 0; i < boxes.length; i++){
boxesFlagArray.push({"isStacked": false, "isExpanded": false});
}
function scrollWrap(e) {
boxes.forEach((box, index) => {
let leftMarginStop = (index) * leftMargin; // calculation for left margin stop (60, 120, 180,...)
const boxCoord = box.getBoundingClientRect();
const leftSideOfCurrent = boxCoord.left; // coordinarion of left side of panel
const rightSideOfCurrent = boxCoord.right; // coordinarion of right side of panel
const leftSideOfNextItem = (index < boxes.length - 1) ? box.nextElementSibling.getBoundingClientRect().left : 0; // coordinarion of left side of NEXT panel (when index is 8, the next sibling is 0 if it is less than 8 than it is next sibling)
box.style.left = `${leftMarginStop}px`;
// do not apply shadow to last element
if (index < boxes.length-1) {
// controll shadow of all 0+ elements
if (leftSideOfCurrent <= leftMarginStop) {
box.nextElementSibling.classList.add("shadow");
}
// controll removal of shadow of all 0+ elements
if (leftSideOfNextItem === rightSideOfCurrent) {
box.nextElementSibling.classList.remove("shadow");
}
// when panel 5 reach left margin, left margin change from 60 to 30 to all panels
if (index > 4 && leftSideOfCurrent <= leftMarginStop) {
leftMargin = 20;
} else if (index < 6 && leftSideOfCurrent > leftMarginStop && !boxes[index].classList.contains('shadow')) {
leftMargin = 60;
}
// setting flag (true/false) to stacked panels (reached leftMarginStop)
if(leftMarginStop == leftSideOfCurrent && index > 0){
if(!boxesFlagArray[index].isStacked){
boxesFlagArray[index-1].isStacked = true;
}
}
if(leftMarginStop != leftSideOfCurrent && index > 0){
if(boxesFlagArray[index-1].isStacked){
boxesFlagArray[index-1].isStacked = false;
}
}
}
});
}
function onHover(event) {
const indexedElement = boxes.indexOf(this);
const isPanelStacked = boxesFlagArray[indexedElement].isStacked;
const fromBoxIndex = boxes.indexOf(event.fromElement);
const toBoxIndex = boxes.indexOf(event.toElement);
const boxCoordFrom = (fromBoxIndex >= 0) ? boxes[fromBoxIndex].getBoundingClientRect() : "";
const boxCoordTo = boxes[toBoxIndex].getBoundingClientRect();
if (event.fromElement == null) return; // fix error: Cannot read property 'classList' of null
// controll if we hover from body to box and if panel is stacked and it is not expanded yet
if((event.fromElement == body || event.fromElement == wrapper) && event.toElement.classList.contains("box") && isPanelStacked && !hoverExtendFlag) {
// when from body to box, extend all pannels from hover + 100px
for (let i = indexedElement + 1; i < boxes.length; i++) {
const iCoord = boxes[i].getBoundingClientRect();
boxes[i].style.left = `${iCoord.left + hoverMargin}px`;
boxesFlagArray[i].isExpanded = true;
}
hoverExtendFlag = true;
}
// controll if we hover from box to box and if panel is stacked
if (event.fromElement.classList.contains("box") && event.toElement.classList.contains("box") && isPanelStacked) {
if (!hoverExtendFlag) {
for (let i = indexedElement + 1; i < boxes.length; i++) {
const iCoord = boxes[i].getBoundingClientRect();
boxes[i].style.left = `${iCoord.left + hoverMargin}px`;
boxesFlagArray[i].isExpanded = true;
}
hoverExtendFlag = true;
}
// From box to box hover controll, move panels
if (fromBoxIndex > toBoxIndex && hoverExtendFlag) {
event.fromElement.style.left = `${boxCoordFrom.left + hoverMargin}px`;
boxesFlagArray[fromBoxIndex].isExpanded = true;
} else if (fromBoxIndex < toBoxIndex && hoverExtendFlag) {
event.toElement.style.left = `${boxCoordTo.left - hoverMargin}px`;
boxesFlagArray[toBoxIndex].isExpanded = true;
}
}
}
function onHoverLeave(event) {
const indexedElement = boxes.indexOf(this);
const isPanelStacked = boxesFlagArray[indexedElement].isStacked;
const toBoxIndex = boxes.indexOf(event.toElement);
if (event.toElement == null) return; // fix error: Cannot read property 'classList' of null
if((event.toElement == body || event.toElement == wrapper) && event.fromElement.classList.contains("box") && hoverExtendFlag) {
// controll the mouse from box to body when left margin is narrow or extended
if (leftMargin === 20) {
for (let i = 0; i < boxes.length; i++) {
boxes[i].style.left = `${20 * i}px`; // set all panels back to left margin multiply 20px
boxesFlagArray[i].isExpanded = false;
}
} else if (leftMargin === 60) {
for (let i = 0; i < boxes.length; i++) {
boxes[i].style.left = `${60 * i}px`; // set all panels back to left margin multiply 60px
boxesFlagArray[i].isExpanded = false;
}
}
hoverExtendFlag = false;
}
// controll from box to box hover out, to return to initial state
if (event.fromElement.classList.contains("box") && event.toElement.classList.contains("box") && (isPanelStacked === false || (isPanelStacked === true && boxesFlagArray[toBoxIndex].isStacked === false )) ) { // checks if the from is true and to is false (first false element)
for (let i = indexedElement+1; i < boxes.length; i++) {
const iCoord = boxes[i].getBoundingClientRect();
boxes[i].style.left = `${iCoord.left - hoverMargin}px`;
boxesFlagArray[i].isExpanded = false;
}
hoverExtendFlag = false;
}
}
wrapper.addEventListener("scroll", scrollWrap);
boxes.forEach(box => box.addEventListener("mouseenter", onHover));
boxes.forEach(box => box.addEventListener("mouseleave", onHoverLeave));
&#13;
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
min-height: 100%;
}
.wrapper, .box1, .box2, .box3, .box4, .box5, .box6, .box7, .box8 {
height: 900px;
}
.box0, .box1, .box2, .box3, .box4, .box5, .box6, .box7, .box8 {
position: sticky;
z-index: 1;
-webkit-transition: box-shadow 0.5s linear, left 0.2s;
-moz-transition: box-shadow 0.5s linear, left 0.2s;
-o-transition: box-shadow 0.5s linear, left 0.2s;
transition: box-shadow 0.5s linear, left 0.2s;
}
.wrapper {
width: 1442px;
border-right: 1px solid #f2f2f2;
border-bottom: 1px solid #f2f2f2;
display: flex;
overflow: scroll;
}
.wrapper .box0 {
min-width: 357px;
background-color: #1a1a1a;
}
.wrapper .box1 {
min-width: 357px;
background-color: #333;
}
.wrapper .box2 {
min-width: 702px;
background-color: #4d4d4d;
}
.wrapper .box3 {
min-width: 630px;
background-color: #666;
}
.wrapper .box4 {
min-width: 630px;
background-color: #808080;
}
.wrapper .box5 {
min-width: 357px;
background-color: #999;
}
.wrapper .box6 {
min-width: 630px;
background-color: #b3b3b3;
}
.wrapper .box7 {
min-width: 973px;
background-color: #ccc;
}
.shadow {
box-shadow: -12px 0 24px 0 rgba(0, 0, 0, 0.2);
}
.scroll-limit-box {
min-width: 329px;
height: 900px;
background-color: white;
}
&#13;
<body>
<div class="wrapper">
<div class="box box0"></div>
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
<div class="box box7"></div>
<div class="scroll-limit-box"></div>
</div>
</body>
&#13;