Wie scrolle ich mit jQuery eine Zeile einer Tabelle in die Ansicht (element.scrollintoView)?

74

Ich füge einer Tabelle mithilfe von jQuery dynamisch Zeilen hinzu. Das tableist in einem, divwas overflow:autosomit eine vertikale Bildlaufleiste verursacht hat.

Ich möchte jetzt meinen Container automatisch divin die letzte Zeile scrollen . Was ist die jQuery-Version von tr.scrollintoView()?

Fuxi
quelle
10
Laut dieser Antwort handelt es sich anscheinend um eine integrierte DOM-Funktion, die in allen gängigen Browsern unterstützt wird. element.scrollIntoView()Wird einfach funktionieren.
Kirk Woll

Antworten:

77
var rowpos = $('#table tr:last').position();

$('#container').scrollTop(rowpos.top);

sollte den Trick machen!

Gausie
quelle
4
Ich habe einen Fall gefunden, in dem dies nicht wie erwartet funktioniert hat, und als Antwort unten mit einer etwas anderen Quelle hinzugefügt.
user1338062
Dies fixed scrollingfunktioniert nicht mit der neuen Funktionalität / dem neuen Plugin von datatable.
Lorenz Lo Sauer
85

Das Folgende funktioniert besser, wenn Sie zu einem beliebigen Element in der Liste scrollen müssen (anstatt immer nach unten):

function scrollIntoView(element, container) {
  var containerTop = $(container).scrollTop(); 
  var containerBottom = containerTop + $(container).height(); 
  var elemTop = element.offsetTop;
  var elemBottom = elemTop + $(element).height(); 
  if (elemTop < containerTop) {
    $(container).scrollTop(elemTop);
  } else if (elemBottom > containerBottom) {
    $(container).scrollTop(elemBottom - $(container).height());
  }
}
Abhijit Rao
quelle
8
Dies ist nicht nur eine Antwort, sondern eine Lösung. Vielen Dank.
Witz
1
Sie können das Container-Argument entfernen und durch var container = element.offsetParent ersetzen; ...
Laurens Holst
2
@Laurens: Das funktioniert nur, wenn das scrollbare Element das direkte übergeordnete Element des untergeordneten Objekts ist. Eine robustere Lösung wäre, die Abstammung zu wiederholen, bis ein Element gefunden wird, in dem .css ("Überlauf") "Auto" oder "Bildlauf" zurückgibt.
Robert J. Walker
2
sollte Ihre vierte Zeile nicht var elemTop = element.get (0) .offsetTop sein? Der Code hat nicht funktioniert, bis ich das getan habe.
Jacques
1
Diese Lösung funktioniert zwar fast, weist jedoch schwerwiegende Probleme auf. Einer ist der Tippfehler, aber schwerwiegender ist die Tatsache, dass er sich nicht mit Gegenständen befasst, die irgendeine Höhe haben. Die bessere Lösung ist das Plugin von @Robert Koritnik
Boatcoder
29

Plugin, das nur bei Bedarf (mit Animation) scrollt

Ich habe ein jQuery-Plugin geschrieben , das genau das tut, was es verspricht (und auch genau das, was Sie benötigen ). Das Gute ist, dass der Container nur dann gescrollt wird, wenn das Element tatsächlich deaktiviert ist. Andernfalls wird kein Bildlauf durchgeführt.

So einfach geht das:

$("table tr:last").scrollintoview();

Es findet automatisch den nächsten scrollbaren Vorfahren, der überschüssigen Inhalt hat und Bildlaufleisten anzeigt. Wenn es also einen anderen Vorfahren overflow:autogibt, der nicht scrollbar ist, wird er übersprungen. Auf diese Weise müssen Sie kein scrollbares Element bereitstellen, da Sie manchmal nicht einmal wissen, welches scrollbar ist (ich verwende dieses Plugin auf meiner Sharepoint-Site, auf der Content / Master unabhängig vom Entwickler ist, sodass ich keinen Einfluss darauf habe - HTML kann sich ändern Wenn die Site betriebsbereit ist, können auch scrollbare Container verwendet werden.

Robert Koritnik
quelle
Dieser funktioniert wirklich. Versucht, das von @Abhijit Rao zu beheben, um zu arbeiten, aber es hat viele Probleme. Dieser funktioniert einfach.
Bootscodierer
@ Mark0978: Beachten Sie jedoch, dass ich es aktualisieren muss, damit es ordnungsgemäß mit jQuery 1.8+ funktioniert. Die benutzerdefinierte Auswahldefinition muss mit 1.8+ anders erfolgen.
Robert Koritnik
1
Habe das Plugin von GitHub bekommen und funktioniert reibungslos wie versprochen. Gut gemacht!
Bernoulli IT
vier Jahre seit dem Update und dieses Plugin funktioniert immer noch wie ein Zauber. Ich habe es in einer eckigen Direktive verwendet :)
Shaunak
1
Vier Jahre später funktioniert das Plugin bei mir nicht - manchmal verfehlt es die Marke mit dem Ziel fast, ist aber nicht in Sicht. Unter der Annahme, dass das Ziel nur ein Element ist, verwende ich heute Javascript: var target = $(selector); target.get(0).scrollIntoView();
Subsci
19

viel einfacher:

$("selector for element").get(0).scrollIntoView();

Wenn mehr als ein Element im Selektor zurückgegeben wird, erhält get (0) nur das erste Element.

Mor Shemesh
quelle
Dies würde sich auch auf das Scrollen der Seite auswirken. Also würde es nicht funktionieren.
Jacques
Dies führt weder zu Animationen noch zum Scrollen innerhalb eines scrollbaren Div.
Bootscodierer
Dies macht keine Animation, aber ich finde animierte Lösungen, die in meinem speziellen Anwendungsfall fehlschlagen und ein unglaublich langes Element haben. Die animierten Lösungen verfehlen manchmal die Marke um einen kleinen Versatz. @ Mark0978 mein Anwendungsfall ist ein scrollbarer Div - nicht sicher, warum es in meinem Fall funktioniert, aber nicht in
Ihrem
5

Dieses ausführbare Beispiel zeigt, wie scrollIntoView () verwendet wird, das in allen modernen Browsern unterstützt wird: https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView#Browser_Compatibility

Im folgenden Beispiel wird jQuery verwendet, um das Element mit auszuwählen #yourid.

$( "#yourid" )[0].scrollIntoView();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p id="yourid">Hello world.</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>

Barry Staes
quelle
3
var elem=jQuery(this);
elem[0].scrollIntoView(true);
zuckerhut
quelle
18
Wäre nicht this.scrollIntoView(true)viel einfacher?
Felix Kling
Antwort wie gegeben ist das einzige, was für mich funktioniert hat
Slashdottir
2

Wenn Sie nur scrollen möchten, können Sie die scrollTop-Methode von jQuery verwenden. http://docs.jquery.com/CSS/scrollTop

var table = jQuery( 'table' );
table.scrollTop( table.find( 'tr:last' ).scrollTop() );

So etwas vielleicht?

Wilhelm
quelle
2

Ich habe einen Fall gefunden (Überlauf div> table> tr> td), in dem das Scrollen zur relativen Position des tr nicht funktioniert. Stattdessen musste ich den Überlaufcontainer (div) mit scrollTop nach scrollen <tr>.offset().top - <table>.offset().top. Z.B:

$('#container').scrollTop( $('#tr').offset().top - $('#td').offset().top )
user1338062
quelle
2

Gleich von oben mit wenig Modifikation

function focusMe() {
       var rowpos = $('#FocusME').position();
        rowpos.top = rowpos.top - 30;
        $('#container').scrollTop(rowpos.top);
    }
<html>
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<body>
    <input type="button" onclick="focusMe()" value="focus">
    <div id="container" style="max-height:200px;overflow:scroll;">
        <table>
            <tr>
                <td>1</td>
                <td></td>
            </tr>
            <tr>
                <td>2</td>
                <td></td>
            </tr>
            <tr>
                <td>3</td>
                <td></td>
            </tr>
            <tr>
                <td>4</td>
                <td></td>
            </tr>
            <tr>
                <td>5</td>
                <td></td>
            </tr>
            <tr>
                <td>6</td>
                <td></td>
            </tr>
            <tr>
                <td>7</td>
                <td></td>
            </tr>
            <tr>
                <td>8</td>
                <td></td>
            </tr>
            <tr>
                <td>9</td>
                <td></td>
            </tr>
            <tr id="FocusME">
                <td>10</td>
                <td></td>
            </tr>
            <tr>
                <td>11</td>
                <td></td>
            </tr>
            <tr>
                <td>12</td>
                <td></td>
            </tr>
            <tr>
                <td>13</td>
                <td></td>
            </tr>
            <tr>
                <td>14</td>
                <td></td>
            </tr>
            <tr>
                <td>15</td>
                <td></td>
            </tr>
            <tr>
                <td>16</td>
                <td></td>
            </tr>
            <tr>
                <td>17</td>
                <td></td>
            </tr>
            <tr>
                <td>18</td>
                <td></td>
            </tr>
            <tr>
                <td>19</td>
                <td></td>
            </tr>
            <tr>
                <td>20</td>
                <td></td>
            </tr>
        </table>
    </div>
</body>

</html>

Arun Prasad ES
quelle
0

$( "#yourid" )[0].scrollIntoView();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p id="yourid">Hello world.</p>
<p>..</p>
<p>..</p>
<p>..</p>
<p>..</p>

Ajay Ram
quelle
Scrollt die ganze Seite und ist buchstäblich eine Kopie der Antwort von @BarryStaes
Mark Carpenter Jr
0

Ich konnte Abhijit Raos Antwort oben keinen Kommentar hinzufügen, daher sende ich dies als zusätzliche Antwort.

Ich musste die Tabellenspalte in einer breiten Tabelle anzeigen lassen, also fügte ich der Funktion die Funktionen zum Scrollen nach links hinzu. Wie jemand erwähnt hat, springt es beim Scrollen, aber es hat für meine Zwecke funktioniert.

function scrollIntoView(element, container) {
  var containerTop = $(container).scrollTop();
  var containerLeft = $(container).scrollLeft();
  var containerBottom = containerTop + $(container).height();
  var containerRight = containerLeft + $(container).width();

  var elemTop = element.offsetTop;
  var elemLeft = element.offsetLeft;
  var elemBottom = elemTop + $(element).height();
  var elemRight = elemLeft + $(element).width();

  if (elemTop < containerTop) {
    $(container).scrollTop(elemTop);
  } else if (elemBottom > containerBottom) {
    $(container).scrollTop(elemBottom - $(container).height());
  }

  if(elemLeft < containerLeft) {
    $(container).scrollLeft(elemLeft);
  } else if(elemRight > containerRight) {
    $(container).scrollLeft(elemRight - $(container).width());
  }
}
Wuijin
quelle