jQuery UI's Position Function (plus, MagicZoom von Grund auf)

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Zu wissen, wie man Elemente positioniert, wo man sie haben möchte, ist eines der wichtigsten Werkzeuge im Werkzeugkasten eines Webdesigners. Das Verständnis des Seitenflusses, das Verständnis, dass alles eine Box ist, das Verständnis von Floats usw. Sobald die Grundlagen erlernt sind, ist eine häufige Frage für fortgeschrittene Designer, wie man Elemente relativ zu anderen Elementen positioniert. Die Standard-CSS-Lösung dafür ist die altbewährte absolute Positionierung innerhalb relativer Positionierung. Kurz gesagt, Sie können eine relative Positionierung (oder eigentlich jede nicht standardmäßige statische Positionierung) auf ein Element anwenden und dann Kindelemente davon innerhalb dieses Kontexts absolut positionieren. Oft funktioniert das wunderbar, aber es ist tatsächlich ziemlich eingeschränkt.

  • Man ist gezwungen, einen anderen Positionierungswert als statisch zu verwenden, auch wenn er sonst nicht benötigt wird.
  • Elemente, die basierend auf anderen positioniert werden sollen, müssen Kindelemente sein.
  • Wenn das übergeordnete Element einen Überlaufwert benötigt, kann es umständlich werden.

Die jQuery UI bietet nun eine Funktion namens Position Utility, die das Positionieren von Elementen relativ zu anderen Elementen köstlich einfach macht! Schauen wir sie uns an.

Zuerst die Grundlagen

Wir werden hier jQuery und jQuery UI verwenden, daher gehen wir davon aus, dass Sie die jQuery- und jQuery-UI-Bibliotheken auf Ihrer Website laden.

<head>
  ...
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
  ...
  <script type="text/javascript">
    $(function() {
      // do stuff, yay!
    });
  </script>
</head>

Die Grundlagen

Eines der schönen Dinge an jQuery und jQuery UI ist die fast satzartige Syntax. Ein-Wort-Funktionsnamen und Parameter, die wirklich verdeutlichen, was vor sich geht. Hier ist ein einfaches Beispiel.

$("#move-me").position({
  "my": "right top",
  "at": "left bottom",
  "of": $("#thing")
});

Vielleicht hilft eine kleine Grafik.

Das Coolste hierbei ist, dass es keine Voraussetzungen gibt, damit dies funktioniert. Das zu positionierende Element benötigt keinen speziellen CSS-Positionierungswert (oder muss kein Kindelement sein), das Element, gegen das positioniert wird, benötigt keinen speziellen CSS-Positionierungswert (oder irgendetwas anderes).

Alle Optionen

Hier ist die vollständige Liste. Nur noch ein paar Optionen mehr.

$('.positionable').position({
  "my": "right top"       //  Horizontal then vertical, missing values default to center
  "at": "left bottom"     //  Horizontal then vertical, missing values default to center
  "of": $('#parent'),     //  Element to position against 
  "offset": "20 30"       //  Pixel values for offset, Horizontal then vertical, negative values OK
  "collision": "fit flip" //  What to do in case of 
  "bgiframe": true        //  Uses the bgiframe plugin if it is loaded and this is true
});

Wir haben "my", "of" und "at" in den Grundlagen behandelt, aber die vollständige Palette von Parametern umfasst das Setzen eines Offsets, die Verwendung des bgiframe-Plugins (behebt einige IE z-index-Probleme) und Kollisionserkennung, die ich später behandeln werde.

Magic Zoom!

Ich dachte, ich baue ein kleines "Real-World"-Beispiel, wo das nützlich sein könnte. Haben Sie jemals ein Plugin oder einen anderen JavaScript-Effekt gesehen, bei dem Sie auf ein Bild klicken und es "in place wächst"? Ich nenne es Magic Zoom, weil ich gerne lahme Namen für Dinge vergebe. So könnte es funktionieren.

  1. Haben Sie ein Gitter von Thumbnail-großen Bildern (hält die Ladezeit der Seite gering).
  2. Wenn ein Thumbnail angeklickt wird...
  3. Laden Sie das Vollbildbild direkt über das Thumbnail, skaliert auf die exakt gleiche Größe.
  4. Animieren Sie das neue Vollbildbild auf seine ursprüngliche Größe hoch.
  5. Halten Sie während der Animation das Bild zentriert über dem Thumbnail.
  6. Klicken zum Schließen.

Die Galerie besteht einfach aus Anker-Tags, die zur großen Version verlinken, und darin Bild-Tags der Thumbnails. Ohne JavaScript ist sie immer noch voll funktionsfähig.

<div class="gallery">

	<a href="http://farm4.static.flickr.com/3329/4556228155_7ce08c45a3.jpg">
	  <img src="//farm4.static.flickr.com/3329/4556228155_7ce08c45a3_m.jpg" alt="" />
	</a>
	
	<!-- More... -->
	
</div>

jQuery JavaScript

$(function () {
  var $el;

  $(".gallery a").live("click", function () {
    $el = $(this);

    $("<img>", {
      src: $el.attr("href"),
      class: "larger"
    }).load(function () {
      $(this)
        .appendTo("body")
        .width($el.find("img").width())
        .position({
          of: $el.find("img"),
          my: "center center",
          at: "center center"
        })
        .animate(
          {
            width: 500 // width of large image
          },
          {
            duration: 1000, // 1000 = 1 second
            easing: "easeOutQuad",
            step: function (i) {
              $(this).position({
                of: $el.find("img"),
                my: "center center",
                at: "center center",
                collision: "fit"
              });
            }
          }
        );
    });

    return false;
  });

  $(".larger").live("click", function () {
    $el = $(this);
    $el.fadeOut(400, function () {
      $el.remove();
    });
  });
});

Das interessante Konzept hier ist der Parameter "step" für die animate-Funktion. Sie können diesem Parameter eine Funktion übergeben, und diese Funktion wird bei jedem einzelnen Keyframe der Animation ausgeführt. Für uns bedeutet das, dass wir die Positionierungsfunktion verwenden werden, um sicherzustellen, dass das große Bild immer noch über seinem Thumbnail zentriert ist.

Ja... das Wachsen der Bilder ist etwas wackelig. Wenn jemand Ideen dazu hat, lasst es mich wissen.

Kollisionserkennung!

Elemente mit einer so einfachen Syntax und wenig Code relativ zu anderen Elementen positionieren zu können, ist großartig, aber was diese Positionierungs-Utility wirklich auszeichnet, ist die Kollisionserkennung.

Was ist, wenn das Element, wo wir es sagen, platziert werden soll, außerhalb des Browserfensters liegt? Das könnte je nach Situation ein Problem sein. Nehmen wir unser Magic-Zoom-Beispiel. Theoretisch ist der Grund, warum Leute auf die Bilder klicken, um eine größere Version zu sehen, dass sie tatsächlich am Foto interessiert sind und es größer und detaillierter sehen wollen. Es hilft ihnen nicht, wenn das Bild am linken Rand der Seite liegt und beim Wachsen abgeschnitten wird.

Dieses Problem ist mit der Positionierungsfunktion extrem einfach zu lösen. Alles, was wir tun müssen, ist den Kollisionsparameter mit dem Wert "fit" hinzuzufügen, und die Positionierungsfunktion stellt sicher, dass das, was sie positioniert, niemals außerhalb des Fensters liegt.

Standardmäßig versuchen die größeren Bilder, vergrößert und zentriert über dem Thumbnail zu bleiben.
Sollte das Vergrößern des größeren Bildes dazu führen, dass es außerhalb des Browserfensters gerät, erkennt das Positionierungs-Utility dies und vergrößert das Bild stattdessen nach innen.