Linuchs: top.location im iframe abfragen

Moin,

ich drucke Liederbücher.

Das Dokument besteht aus mehreren div, in denen das jeweilige Textdokument per iframe erscheinen soll.

Das Textdokument muss wissen, in welchem Format A4, A5, A6 es anzuzeigen ist.

Deshalb hänge ich dem Liederbuch die Info *.htm?a6 an und frage sie in den Einzelliedern ab:

  alert( "top.location.href=[" +top.location.href +"]" );
  if( top.location.href.indexOf ("a5") != -1 ) {
    document.writeln( '<link rel=stylesheet  href="css/basis_a5.css">' );
  } else if( top.location.href.indexOf ("a6") != -1 ) {
    document.writeln( '<link rel=stylesheet  href="css/basis_a6.css">' );
  }

Das hat in der Vergangenheit mit dem Firefox funktioniert, doch nun kommt die Fehlermeldung

Uncaught DOMException: Permission denied to get property "href" on cross-origin object

Die Dateien sind lokal in den Ordnern "liederbuecher" und "liedertexte", was ist das für eine Schikane und wie umgehe ich sie?

Gruß, Linuchs

  1. Eine provisorische Lösung habe ich. Den Textdokumenten hänge ich ?a6 an.

  2. @@Linuchs

    Deshalb hänge ich dem Liederbuch die Info *.htm?a6 an

    Wenn du das Format nicht als Key, sondern als Wert anhängst – also .htm?format=a6 –, dürfte das vorteilhafter sein.

      alert( "top.location.href=[" +top.location.href +"]" );
      if( top.location.href.indexOf ("a5") != -1 ) {
        document.writeln( '<link rel=stylesheet  href="css/basis_a5.css">' );
      } else if( top.location.href.indexOf ("a6") != -1 ) {
        document.writeln( '<link rel=stylesheet  href="css/basis_a6.css">' );
      }
    

    Das hat in der Vergangenheit mit dem Firefox funktioniert

    Die Vergangenheit sieht man dem Code an. alert(), document.writeln().

    Was hat du eigentlich so die letzten 10 Jahre gemacht?

    🖖 Живіть довго і процвітайте

    --
    Ad astra per aspera
    1. Die Vergangenheit sieht man dem Code an. alert(), document.writeln().

      alert ist natürlich nur zum Testen drin, damit es auffällig aufpoppt.

      writeln gibt bewusst nur dann Text und Schaltflächen aus, wenn js aktiv ist. Ich finde es frustrierend, man klickt und es passiert nichts.

      Gut, kann man auch mit verborgenem Text machen und den dann freischalten. Was wäre der Vorteil? Einfach nur anders, oder?

      Habe ich überlesen, dass du top.location kommentiert hast?

      1. Lieber Linuchs,

        Was wäre der Vorteil? Einfach nur anders, oder?

        die uralten Methoden document.write und document.writeln schreiben direkt in das Dokument. Sie schreiben also Quellcode, damit der anschließend vom Browser geparst werden soll. Das widerspricht dem Konzept des live-im-Browser-ändern, weil nach dem Parsen ja nicht mehr der Quelltext maßgeblich ist, sondern das Datenmodell, welches der Browser aus dem Quelltext erstellt hat, das sogenannte DOM.

        Wenn Du jetzt einen EventListener irgendwo drangepappt hast, dann klebt der ja nicht im Quelltext, sondern an einem im Speicher befindlichen Datenkonstrukt, einem Objekt. Wenn Du dieses dadurch zerstörst, dass Du mit document.write die Grundlage für das Objekt veränderst, was soll dann im Anschluss gelten? Das neue DOM nach dem erneuten Parsen des veränderten Quelltextes? Dann ist aber Dein EventListener verloren, weil es das alte Objekt ja nicht mehr geben kann.

        Deshalb hat es einen Sinn, aus JavaScript heraus mit dem DOM und seinen Methoden zu arbeiten und document.write und Konsorten in den Giftschrank zu stellen.

        Liebe Grüße

        Felix Riesterer

        1. Hallo Felix,

          ich glaube, das ist nicht das Argument. Document.write macht man, um irgendwo während der Parse-Phase das HTML erweitern zu können, und solange ein HTML Element nicht fertig ist, kann man keine Eventlistener anhängen.

          Das Argument ist, dass document.write aus der Zeit vor dem DOM stammt und es dem HTML Parser Knüppel vor die Füße wirft. Er muss dann nämlich aufhören und nach Ende des Scripts sozusagen von vorn anfangen, weil der Text, den er bisher schonmal vorbereitet hatte, nun ungültig sein kann. Das hemmt die Performance beim Seitenladen. Und die HTML Spec schreibt:

          And to make matters even worse, the exact behavior of this method can in some cases be dependent on network latency, which can lead to failures that are very hard to debug. For all these reasons, use of this method is strongly discouraged.

          Korrekte Lösung wäre, am Ende des <head> Bereichs ein Scriptlein unterzubringen, das mit document.createElement ein link-Element passend erzeugt und dieses dann mit document.head.append an den Head anzuhängen.

          Besser noch wäre - wie ich schon schrub - mit Media-Abfragen zu arbeiten.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Lieber Rolf,

            document.head.append

            ich habe nicht mitbekommen, seit wann das im Standard fest verankert wurde. TIL, dass man auch document.head verwenden kann.

            Liebe Grüße

            Felix Riesterer

            1. @@Felix Riesterer

              ich habe nicht mitbekommen, seit wann das im Standard fest verankert wurde. TIL, dass man auch document.head verwenden kann.

              Bei jenem Thread warst du doch dabei‽

              🖖 Живіть довго і процвітайте

              --
              Ad astra per aspera
              1. Lieber Gunnar,

                Bei jenem Thread warst du doch dabei‽

                ja, aber habe ihn damals noch vor Deinem Posting auf ausblenden gesetzt. Viele Threads blende ich aus, wenn sie mich nicht (mehr) interessieren. Und html>head habe ich bisher mit einem querySelector ermittelt. Jetzt kann ich das auch gleich richtig notieren.

                Liebe Grüße

                Felix Riesterer

  3. Hallo Linuchs,

    das Problem heißt "cross origin" Zugriff. Bei Dokumente auf file:/// hat sozusagen jedes seinen eigenen Origin und deswegen darfst Du aus dem iframe nicht auf Eigenschaften des Elterndokuments zugreifen.

    Das ist schon länger so, aber der FF hat das bisher wohl zugelassen. Ggf. gibt's auch ein Firefox-Flag, womit Du Cross-Origin Zugriffe für wieder erlauben kannst, google mal danach.

    Deine Idee, der URL des iframe-Dokuments das Format anzuhängen, ist eine Möglichkeit.

    Du kannst das aber auch mit CSS machen. Zum einen hat das <link> Element ein Media-Attribut, wo Du CSS-Dateien nur für den Druck festlegen kannst.

    <link rel="stylesheet" href="noten.css" media="print">
    

    Steht auch im Wiki

    Was da noch nicht steht, dafür aber bei MDN, ist die Möglichkeit, hier auch Medienfeatures und nicht nur Medientypen abzufragen. Als Range-Abfrage, was Chromia und Feurios seit einem Jahr können, wird das eigentlich ganz schick:

    <link rel="stylesheet" href="noten_a5.css"
          media="print and (14cm <= width <= 15cm)">
    

    Diese Abfrage basierend jetzt auf A5 Hochformat (14,85cm breit). Welchen Wert Du genau bekommst, mag aber auch von Randgrößen abhängen, das weiß ich beim Print CSS jetzt nicht genau, ob die Feature-Queries die Seitengröße oder die Größe des bedruckbaren Bereichs abfragen. Ich theoretisiere hier, ich habe das noch nicht selbst gemacht.

    Welche Werte Du genau abfragen musst, hängt wohl auch von deiner Seitenausrichtung ab. Dafür weiß ich jetzt zu wenig über deine Liederbücher. Aber, die Ausrichtung an sich kann man auch abfragen. Wie das beim Drucken einer Seite mit iframes genau funktioniert, musst Du vermutlich experimentell erkunden. Kannst ja Dummy-Seiten machen, wo Du in divs ein ::after Element einsetzt und dieses Element je nach Media-Ergebnis mit unterschiedlichem content befüllst. Oder je nach Media-Ergebnis das eine oder andere div ein- und ausblendest. Dadurch kann dann "A4 Querformat" oder "A6 Hochformat" als Text erscheinen

    Je nach dem, wie sehr sich die Stylesheets für die Seitengrößen unterscheiden, kannst Du auch die unterschiedlichen Formate zu einer CSS Datei zusammenfassen und nur die Unterschiede in @media-Abfragen packen.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Danke dir für die Tipps, muss ich in Ruhe lesen und austesten.

  4. @@Linuchs

    ich drucke Liederbücher.

    Die Antwort auf all deine Fragen ist wohl: Verlass dich nicht auf den Ausdruck von Webseiten vom Browser aus. Erstelle aus deinen Inhalten PDFs, deren Formatierung zu kontrollieren kannst.

    🖖 Живіть довго і процвітайте

    --
    Ad astra per aspera