Maison  >  Questions et réponses  >  le corps du texte

Écouteur d'événements de défilement ajouté à l'élément mais ne se déplace correctement que si scrollTop n'est pas égal à 0

J'ai donc écrit ce petit script dans lequel j'ai deux listes - Tâches terminées/actives, vous pouvez changer de liste de tâches en cliquant sur le bouton, et vous pouvez lire plus d'informations sur la tâche en cliquant sur "Plus d'informations". Lorsque l'on clique sur plus d'informations, un nouvel élément div est créé et je souhaite suivre la position Y de son élément hôte, et cela fonctionne à mi-chemin. Voici à quoi cela ressemble : Entrez la description de l'image ici

Il s'agit d'un bug qui, j'en suis presque sûr, se produit lorsque l'élément déroulant scrollTop n'est pas 0 (il est créé de la bonne manière, chaque fois que je commence à faire défiler, il saute immédiatement et écrase la tâche elle-même) : Entrez la description de l'image ici.

C'est la partie de mon code qui est chargée d'identifier la quantité de px de défilement, la direction de défilement et le déplacement de l'élément div "plus d'informations", et la partie responsable de sa création, je ne sais pas où est le problème car Je suis en train de coder le tout. C'est encore nouveau et je ne connais pas très bien le css/html.

createTooltip() {
    const tooltipElement = document.createElement('div');
    tooltipElement.className = 'card';
    const toolTipTemplate = document.getElementById('tooltip');
    const tooltipBody = document.importNode(toolTipTemplate.content, true);
    tooltipBody.querySelector('p').textContent = this.text;
    tooltipElement.append(tooltipBody);

    const hostElPosLeft = this.hostElement.offsetLeft;
    const hostElPostop = this.hostElement.offsetTop;
    const hostElHeight = this.hostElement.clientHeight;
    const parentElementScrolling = this.hostElement.parentElement.scrollTop;

    const x = hostElPosLeft + 20;
    const y = hostElPostop + hostElHeight - parentElementScrolling - 10;
    tooltipElement.style.position = 'absolute';
    tooltipElement.style.left = x + 'px';
    tooltipElement.style.top = y + 'px';

    const scrollHandler = () => {
      ulElement.addEventListener('scroll', yLogger);
    };
    tooltipElement.addEventListener('click', this.closeToolTip);
    tooltipElement.addEventListener('click', scrollHandler);
    this.element = tooltipElement;
    const ulElement = this.hostElement.parentElement;
    console.log(ulElement);

    let pxPosition = [0];
    let currentY = y;

    const yLogger = () => {
      let scrollDirection;
      let pxScrolled = 0;
      if (pxPosition.length <= 1) {
        pxPosition.push(ulElement.scrollTop);
      } else {
        pxPosition.push(ulElement.scrollTop);
        pxPosition.shift(ulElement);
      }
      console.log(pxPosition);
      if (pxPosition[1] < pxPosition[0]) {
        scrollDirection = 'up';
        pxScrolled = pxPosition[0] - pxPosition[1];
      } else if (pxPosition[0] < pxPosition[1]) {
        scrollDirection = 'down';
        pxScrolled = pxPosition[1] - pxPosition[0];
      }
      console.log(pxScrolled);
      console.log(scrollDirection);

      if (scrollDirection === 'down') {
        currentY = currentY - pxScrolled;
        console.log(currentY);
        tooltipElement.style.top = currentY + 'px';
      } else {
        scrollDirection === 'up';
        currentY = currentY + pxScrolled;
        console.log(currentY);
        tooltipElement.style.top = currentY + 'px';
      }
    };

    this.hostElement.closest('ul').addEventListener('scroll', yLogger);
  }
}

J'ajoute les extraits HTML et CSS, même si je ne pense pas qu'ils soient nécessaires puisqu'ils ont été rédigés par le professeur du cours que je suis.

Voici l'extrait HTML :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Project Board</title>
    <link rel="stylesheet" href="assets/styles/app.css" />
    <script src="assets/scripts/app.js" defer></script>
  </head>
  <body>
    <template id="tooltip">
      <h2>More Info</h2>
      <p></p>
    </template>
    <header id="main-header">
      <h1>Project Planner</h1>
    </header>
    <section id="active-projects">
      <header>
        <h2>Active Projects</h2>
      </header>
      <ul>
        <li
          id="p1"
          data-extra-info="Got lifetime access, but would be nice to finish it soon!"
          class="card"
          draggable="true"
        >
          <h2>Finish the Course</h2>
          <p>Finish the course within the next two weeks.</p>
          <button class="alt">More Info</button>
          <button>Finish</button>
        </li>
        <li
          id="p2"
          data-extra-info="Not really a business topic but still important."
          class="card"
          draggable="true"
        >
          <h2>Buy Groceries</h2>
          <p>Don't forget to pick up groceries today.</p>
          <button class="alt">More Info</button>
          <button>Finish</button>
        </li>
      </ul>
    </section>
    <section id="finished-projects">
      <header>
        <h2>Finished Projects</h2>
      </header>
      <ul>
        <li
          id="p3"
          data-extra-info="Super important conference! Fictional but still!"
          class="card"
          draggable="true"
        >
          <h2>Book Hotel</h2>
          <p>
            Academind conference takes place in December, don't forget to book a
            hotel.
          </p>
          <button class="alt">More Info</button>
          <button>Activate</button>
        </li>
      </ul>
    </section>
    <footer>
      <button id="im-done-btn">I'm Done!</button>
    </footer>
  </body>
</html>

Voici l'extrait CSS pertinent :

* {
  box-sizing: border-box;
}

html {
  font-family: sans-serif;
}

body {
  margin: 0;
}

#main-header {
  width: 100%;
  height: 6rem;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #ff0062;
}

#main-header h1 {
  color: white;
  margin: 0;
}

footer {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  text-align: center;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

li {
  margin: 1rem 0;
}

section {
  margin: 1rem auto;
  width: 40rem;
  max-width: 90%;
}

section ul {
  padding: 1rem;
  max-height: 20rem;
  overflow: scroll;
}

section > h2 {
  color: white;
  margin: 0;
}

button {
  font: inherit;
  background: #ff0062;
  color: white;
  border: 1px solid #ff0062;
  padding: 0.5rem 1.5rem;
  cursor: pointer;
}

button.alt {
  background: white;
  color: #ff0062;
}

button:focus {
  outline: none;
}

button:hover,
button:active {
  background: #ff2579;
  border-color: #ff2579;
  color: white;
}

.card {
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
  padding: 1rem;
  background: white;
}

.droppable {
  background: #ffe0ec
}

#active-projects {
  border: 1px solid #870099;
}

#active-projects > header {
  background: #870099;
  padding: 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

#active-projects header h2 {
  color: white;
  margin: 0;
}

#finished-projects {
  border: 1px solid #535353;
}

#finished-projects > header {
  background: #535353;
  padding: 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

#finished-projects header h2 {
  color: white;
  margin: 0;
}

P粉427877676P粉427877676181 Il y a quelques jours342

répondre à tous(1)je répondrai

  • P粉885035114

    P粉8850351142024-04-02 00:20:03

    Ce problème peut être résolu avec CSS, vous pouvez supprimer les éléments suivants de votre code Javascript :

    tooltipElement.style.position = 'absolute';
    tooltipElement.style.left = x + 'px';
    tooltipElement.style.top = y + 'px';

    Modifiez plutôt le CSS en ajoutant ce qui suit :

    li.card {
        position: relative;
    }
    div.card {
        position: absolute;
        top: 0; /* or some other value, experiment until you find the one which works for you */
        left: 0; /* same as above */
        z-index: 1;
    }

    Pour cela, créez un élément enfant de l'élément div.card 元素必须是相应 li.card que vous créez en code Javascript. J'ai également (probablement à tort) supposé que votre code d'origine était similaire au code que j'ai trouvé plus tôt et je l'ai publié dans les commentaires de votre question car je ne pouvais pas exécuter votre code d'origine.

    Le vôtre position:absolute 最初不起作用,因为 li.card 父级的位置未明确设置,默认为 static.

    EDITJ'ai oublié de mentionner le bit z-index. Ceci est obligatoire car votre infobox ne sera pas entièrement visible (elle sera sous l'élément li.card suivant).

    répondre
    0
  • Annulerrépondre