usablica / intro.js

Lightweight, user-friendly onboarding tour library
http://introjs.com
Other
22.8k stars 2.59k forks source link

Problem with div inside/below scrollable div #350

Closed jankoc closed 6 years ago

jankoc commented 10 years ago

When IntroJs is used on an element inside a scrollable div, it looks like the position is calculated wrongly. See fiddle here:

http://jsfiddle.net/s9ypgo6c/1/

codinguncut commented 9 years ago

I have the same issue. I am currently fixing it by defining a before-change-callback that does the scrolling manually:

$(container).animate({scrollTop: $elm.offset().top}, "slow");

It would be great if the scroll container could be added as a config option ({scrollContainer: '.asdf'})

mamezito-zz commented 9 years ago

can u plz provide jffidle with your solution to test? thanx

Siegrift commented 7 years ago

Hi, does anyone know how to solve this problem? Scrolling doesn't help as the problem lies in incorrect positioning of element. Problem is with the algorithm used in this function:

function _getOffset(element) {
    var elementPosition = {};

    var body = document.body;
    var docEl = document.documentElement;

    var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
    var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;

    if (element instanceof SVGElement) {
      var x = element.getBoundingClientRect()
      elementPosition.top = x.top + scrollTop;
      elementPosition.width = x.width;
      elementPosition.height = x.height;
      elementPosition.left = x.left + scrollLeft;
    } else {
      //set width
      elementPosition.width = element.offsetWidth;

      //set height
      elementPosition.height = element.offsetHeight;

      //calculate element top and left
      var _x = 0;
      var _y = 0;
      while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) {
        _x += element.offsetLeft;
        _y += element.offsetTop;
        element = element.offsetParent;
      }
      //set top
      elementPosition.top = _y;
      //set left
      elementPosition.left = _x;
    }

    return elementPosition;
  }

I have created a fiddle, which logs position using algorithm from http://stackoverflow.com/a/442474/37596 and using element.getBoundingClientRect()

Fiddle: http://jsfiddle.net/s9ypgo6c/8/

yundlu commented 6 years ago

has anyone solved this issue?

plentylife commented 6 years ago

This or something very similar is happening to me with version 2.9.3

I have to manually change style.top for everything to align properly

46319943 commented 4 years ago

The same problem occurred when using version 2.9.3, and the situation was the same as in the jsfiddle example. When the element exists in a scrollable div, and the element is not visible below the div, after startup, the div does not scroll, and the tip appears in the blank space below the div

Browser version: Microsoft Edge 84.0.522.52

vishwasracharya commented 9 months ago

Experiencing an issue with Intro.js version ^7.2.0. Has this been resolved, or is there an alternative solution? Could someone provide information on this matter? If fixed, do I need to modify my code for proper functionality? Are the latest changes/fixes deployed?

I have attached a video file for the issue which I am getting.

Video Link: https://github.com/usablica/intro.js/assets/84620359/e512faba-d5ae-45de-82f7-13c82785b629

Code:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Basic usage</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Intro.js - Better introductions for websites and features with a step-by-step guide for your projects.">
    <meta name="author" content="Afshin Mehrabani (@afshinmeh) in usabli.ca group">

    <!-- styles -->
    <link href="../assets/css/bootstrap.min.css" rel="stylesheet">
    <link href="../assets/css/demo.css" rel="stylesheet">

    <link href="../assets/css/bootstrap-responsive.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/intro.js@7.2.0/minified/introjs.min.css">

    <style>
      .marketing {
        height: 30px;
        height: 40vh;
        margin-top: 500px;
        margin-top: 40vh;
        overflow: auto;
      }

      /* Additional styling for the table */
      table {
        width: 100%;
        border-collapse: collapse;
        margin-top: 20px;
      }

      th, td {
        border: 1px solid #dddddd;
        text-align: left;
        padding: 8px;
      }
    </style>
  </head>

  <body>

    <div class="container-narrow">

      <div class="masthead">
        <ul class="nav nav-pills pull-right">
          <li><a href="https://github.com/usablica/intro.js/tags"><i class='icon-black icon-download-alt'></i> Download</a></li>
          <li><a href="https://github.com/usablica/intro.js">Github</a></li>
          <li><a href="https://twitter.com/usablica">@usablica</a></li>
        </ul>
        <h3 class="muted">Intro.js</h3>
      </div>

      <hr>

      <div class="jumbotron">
        <h1 data-step="3" data-intro="This is a tooltip!">Works with a Scrollable Element</h1>
        <p class="lead">This is the basic usage of IntroJs, with <code>data-step</code> and <code>data-intro</code> attributes.</p>
        <a class="btn btn-large btn-success" href="javascript:void(0);" onclick="javascript:introJs().start();">Show me how</a>
      </div>

      <hr>

      <div class="marketing">
        <table>
          <tr>
            <th data-step="2" data-intro="Another step.">Section One</th>
            <td>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
            </td>
          </tr>
          <!-- Repeat the structure for other sections -->

          <!-- Example for Section Six with scrolling step -->
          <tr>
            <th data-step="1" data-intro="A scrolling step.">Section Six</th>
            <td>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
            </td>
          </tr>

          <tr>
            <th data-step="3" data-intro="Another scrolling step.">Section Seven</th>
            <td>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
            </td>
          </tr>

          <tr>
            <th data-step="4" data-intro="Another scrolling step.">Section Seven</th>
            <td>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
            </td>
          </tr>

          <tr>
            <th data-step="5" data-intro="Another scrolling step.">Section Seven</th>
            <td>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
            </td>
          </tr>

          <tr>
            <th data-step="6" data-intro="Another scrolling step.">Section Seven</th>
            <td>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
            </td>
          </tr>

          <!-- Repeat the structure for other sections -->
        </table>
      </div>
      <hr>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/intro.js@7.2.0/intro.min.js"></script>
  </body>
</html>