it-swarm.com.de

Verschieben Sie die aggregierte JS-Datei in die Fußzeile

Gibt es eine Methode zum Verschieben der aggregierten JS-Dateien in die Fußzeile? Ich habe mir hook_js_alter angesehen, aber das gibt mir nur Zugriff auf die einzelnen Dateien, nicht auf die aggregierten.

Ich würde es vorziehen, die Variable $ scripts nicht an den unteren Rand von html.tpl.php zu verschieben

Alle Tipps wäre dankbar.

5
Paul Sheldrake

Es gibt ein Modul namens Magic , das all dies für Sie erledigt, anstatt Ihren eigenen Ansatz zu entwickeln.

0
Paul Sheldrake

Fand dieses ausgezeichnete Code-Snippet für Drupal 7: https://Gist.github.com/pascalduez/1418121

Es bietet eine Möglichkeit, $ script und $ head_scripts zu verwenden, damit Sie angeben können, welche JS-Dateien in den Kopf aufgenommen werden müssen. Beispiel: Modernizr sollte in die Head-Skripte gehen.

Ich kopiere das Einfügen unter der Lösung in den Link, um die Antwort zukunftssicher zu machen.

Prost.

html.tpl.php

<!DOCTYPE html>
<html<?php print $html_attributes; ?>>
<head>
<?php print $head; ?>
<title><?php print $head_title; ?></title>
<?php print $styles; ?>
<?php print $head_scripts; ?>
</head>

<body<?php print $body_attributes;?>>
<?php print $page_top; ?>
<?php print $page; ?>
<?php print $scripts; ?>
<?php print $page_bottom; ?>
</body>
</html>

template.php

// Used in conjunction with https://Gist.github.com/1417914

/**
* Implements hook_preprocess_html().
*/
function THEMENAME_preprocess_html(&$vars) {
// Move JS files "$scripts" to page bottom for perfs/logic.
// Add JS files that *needs* to be loaded in the head in a new "$head_scripts" scope.
// For instance the Modernizr lib.
$path = drupal_get_path('theme', 'THEMENAME');
drupal_add_js($path . '/js/modernizr.min.js', array('scope' => 'head_scripts', 'weight' => -1, 'preprocess' => FALSE));
}

/**
* Implements hook_process_html().
*/
function THEMENAME_process_html(&$vars) {
$vars['head_scripts'] = drupal_get_js('head_scripts');
}
6
Mario Awad

Alle diese Beispiele sind falsch.  Bearbeiten: Die Antwort von TwoD, die nach meiner veröffentlicht wurde, ist ebenfalls legitim, obwohl es am einfachsten ist, AdvAgg- oder Magic-Module zu verwenden.

Ändern Sie Ihre Vorlagen nicht und erstellen Sie keine neuen. Erstellen Sie keine neuen Variablen wie $head_scripts. Dies ist nicht mit Contrib-Modulen kompatibel, da diese Ihre Anpassungen nicht kennen. Die API Drupal API hat seit Drupal 6 wurde 2008 veröffentlicht) eine Lösung zum Platzieren von Skripten im Fußzeilenbereich.

Der einzig richtige Weg, dies zu tun, ist die Verwendung der Einstellung scope in drupal_add_js(), über die Sie in den Drupal 7 API-Dokumenten lesen können:

scope : Der Speicherort, an dem Sie das Skript platzieren möchten. Mögliche Werte sind "Kopf-" oder "Fußzeile". Wenn Ihr Thema verschiedene Regionen implementiert, können Sie diese auch verwenden. Der Standardwert ist "Header".

Um es noch einmal zu wiederholen, ist dies die einzig richtige Möglichkeit , Skripte in die Fußzeile zu verschieben. Jeder andere Weg ist ein Hack und wird möglicherweise Module beschädigen. Verschieben Sie die Variable $scripts Nicht in Ihrer Vorlage html.tpl.php. Das ist falsch.

Insbesondere für Modernizr können Sie das Modul Modernizr Drupal) verwenden, um die JavaScript-Bibliothek ordnungsgemäß am Anfang Ihres Header-JS-Stacks zu platzieren ... außer wenn Sie dies tun Ich habe $scripts an die falsche Stelle in der Vorlage verschoben.

Wenn Sie ein Code-Snippet sehen möchten, das ausführlich beschreibt, wie Sie richtig Ihre gesamte JS in die Fußzeile einfügen, lesen Sie diesen Blog-Beitrag:

http://pixel-whip.com/drupal-load-scripts-last.html

Dieses Muster wurde von der Community übernommen und mehrere Module und Themen berücksichtigen diese Einstellungen. Verwenden Sie ein Modul wie Magic oder AdvAgg , um die verbleibenden Skripte sicher in den Bereich footer der JS-Ausgabe von Drupal zu verschieben. Wichtige Basisthemen wie Omega und Aurora berücksichtigen auch diese Einstellungen.

5
Chris Ruppel

Jede Methode zum Verschieben von Skripten muss die Art und Weise berücksichtigen, in der Skripte angeordnet und somit geladen und ausgeführt werden, da sie möglicherweise Aufgaben ausführen, die nicht verschoben werden können, bis das DOM geladen ist.

Das Verschieben der Variablen $scripts Auf knapp über $page_bottom Ist eine schnelle Möglichkeit, dies zu erreichen. Sie sollte sicher sein, lässt Sie jedoch keine Skripte einfach im Header behalten.

Das Snippet unter http://pixel-whip.com/drupal-load-scripts-last.html ist zwar ein beliebter Weg, zeigt diesen Fehler jedoch sehr deutlich. Jedes Skript, das voraussichtlich ausgeführt wird, bevor die Seite geladen ist, aber nachdem Drupal.settings Festgelegt wurde, kann nicht ordnungsgemäß funktionieren, da die Einstellungen immer am unteren Rand des Skriptstapels landen.

Die Dokumentation zu drupal_add_js () zeigt, wie Skripte angeordnet sind. Beachten Sie, dass der Bereich wichtiger ist als alles andere, aber drupal_sort_css_js () berücksichtigt den Bereich nicht. Dies liegt daran, dass Skripte aus verschiedenen Bereichen normalerweise separat angefordert werden, sodass Sie nicht zuerst danach gruppieren müssen. Durch einfaches Mischen aller Skripte in den Bereich "Fußzeile" wird "Gruppe" zum wichtigsten Sortierkriterium. Bei Skripten in verschiedenen Bereichen kann jedoch dieselbe Gruppe festgelegt werden, während immer noch eine Ladung vor der anderen geladen werden muss.

Das auf dem Server generierte und als JSON-Objekt an den Client übergebene Einstellungsobjekt verursacht hier ein kleines Problem, da drupal_get_js () normalerweise "hart codiert" es direkt nach den Header-Skripten und ignoriert daher Dinge wie Gruppierung oder Gewichtung für das erstellte Inline-Skript.

Eine Möglichkeit, Skripte aus einer template.php-Datei in die Fußzeile zu verschieben, während die relative Reihenfolge beibehalten und die Einstellungen korrekt positioniert werden, ähnelt der folgenden Hook-Implementierung. Der Code könnte wahrscheinlich ein wenig optimiert werden, insbesondere wenn Sie nur Bereiche für Kopf- und Fußzeilen haben, aber dennoch schnell genug ausgeführt werden.

/**
 * Implements hook_js_alter()
 *
 * Moves scripts from the header scope (and others) to the footer, maintaining
 * their relative positions by adjusting script groups while also making
 * sure settings are positioned just after the original header scripts.
 */
function MYTHEME_js_alter(&$javascript) {
  // List the scripts we want in to remain in their original scope.
  $untouched_scripts = array(
//   'sites/all/libraries/modernizr/modernizr.min.js',
  );

  $scopes = array(
    'header' => array(),
    'other' => array(),
    'footer' => array(),
  );
  // Scope group weights.
  $header_max = NULL;
  $other_min = NULL;
  $other_max = NULL;
  $footer_min = NULL;

  foreach ($javascript as $key => &$script) {
    // Categorize scripts by original scope.
    switch ($script['scope']) {
      case 'header':
        // Find the last header group weight.
        if (!isset($header_max) || $script['group'] > $header_max) {
          $header_max = $script['group'];
        }

      case 'footer':
        // Find the first footer group weight.
        if (!isset($footer_min) || $script['group'] < $footer_min) {
          $footer_min = $script['group'];
        }
        $scopes[$script['scope']][] = &$script;
        break;

      // It's impossible for to know in which order scopes defined by a
      // theme will be rendered, so just put them all together for now.
      // Ordering these scopes, if needed, is left as an exercise for the reader.
      default:
        // Find the first other group weight.
        if (!isset($other_min) || $script['group'] < $other_min) {
          $other_min = $script['group'];
        }
        // Find the last other group.
        if (!isset($other_max) || $script['group'] > $other_max) {
          $other_max = $script['group'];
        }
        $scopes['other'][] = &$script;
    }
    // Move scripts to footer.
    if ($script['scope'] !== 'footer' && !in_array($script['data'], $untouched_scripts)) {
      $script['scope'] = 'footer';
    }
  }
  if (!isset($header_max)) {
    // Just in case there were no header scripts.
    $header_max = -1;
  }

  $last_max = $header_max + 1;

  // Add settings as an inline script after the last header group.
  if (isset($javascript['settings'])) {
    $inline_settings = array(
      'type' => 'inline',
      'scope' => 'footer',
      'data' => 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($javascript['settings']['data'])) . ");",
      'group' => $last_max,
      'every_page' => TRUE,
      'weight' => 0,
    ) + drupal_js_defaults();
    // No need for drupal_get_js() to do this again.
    unset($javascript['settings']);

    $javascript['inline_settings'] = $inline_settings;
  }

  // If there are other scopes, Push them all down below the header scripts.
  if (isset($other_min) && $other_min <= $last_max) {
    $diff = $last_max - $other_min + 1;
    foreach ($scopes['other'] as $key => &$script) {
      $script['group'] += $diff;
    }
    $last_max = $other_max + $diff;
  }
  if (!isset($footer_min)) {
    // Just in case there were no footer scripts.
    $footer_min = $last_max;
  }
  // Finally Push footer scripts down below everything else.
  if ($footer_min <= $last_max) {
    $diff = $last_max - $footer_min + 1;
    foreach ($scopes['footer'] as $key => &$script) {
      $script['group'] += $diff;
    }
  }
}

Dadurch werden keine zusätzlichen Module mehr benötigt, und wenn Sie drupal_get_js() von einer beliebigen Stelle aus aufrufen, wird die korrekt geordnete Ausgabe zurückgegeben.

Dies funktioniert auch, wenn die JavaScript-Aggregations-/Optimierungseinstellung von Drupal aktiviert ist.

4
TwoD

Das Verschieben von print $scripts An das Ende der Seite ist der richtige Weg, dies zu tun. Tatsächlich bezweifle ich ernsthaft, dass es einen anderen Weg gibt.

Normalerweise mache ich das jetzt auf allen meinen Websites. Sie müssen nach Modulen Ausschau halten, die dem Inhalt Elemente hinzufügen, und nicht mit der Javascript-API. Die benutzerdefinierte Google-Suche ist ein Modul, das dies in den Sinn bringt.

Auf einer Drupal 6-Site, die wir vor einigen Jahren erstellt haben, mussten wir einige ältere JS auf Drupal portieren) und haben schließlich die Funktion drupal_get_js() um das JS für die Seite zu erhalten, teilen Sie es über reguläre Ausdrücke auf, bauen Sie $scripts1, $scripts2, $scripts3 usw. auf und fügen Sie dann hinzu sie über ein template_preprocess_page() zum Drucken in der Seitenvorlage an $variables senden. Dies war ein sehr benutzerdefiniertes Thema, aber es endete als unordentliche Lösung. Ich kann mich nicht erinnern, wie wir mit der Aggregation umgegangen sind.

Ähnliches wäre Ihre einzige echte Lösung und würde viel kundenspezifische Arbeit erfordern.

1
mpdonadio