Contao-Camp 2024
Ergebnis 1 bis 5 von 5

Thema: moo_accordion: bei Klick nach oben scrollen

  1. #1
    Contao-Fan Avatar von Nightwing
    Registriert seit
    29.05.2013.
    Beiträge
    436

    Standard moo_accordion: bei Klick nach oben scrollen

    Hallo miteinander,

    ich habe meinem moo_accordion noch eine zusätzliche Funktion spendiert (nutze eine Kopie als Codewrapper), jedoch scheint die Funktion nicht mehr sauber zu funktionieren, erst beim dritten Klick (= active Status zum zweiten Mal). Hier die Funktion:

    PHP-Code:
      window.addEvent('domready', function() {
        new Fx.Accordion($$('.wrapper'), $$('.code'), {
          opacity: false,
          display: <?php echo $wid?>,
          alwaysHide: true,
          onActive: function(tog, el) {
            tog.addClass('active');
            tog.setProperty('aria-expanded', 'true');
            el.setProperty('aria-hidden', 'false');
            return false;
          },
          onBackground: function(tog, el) {
            tog.removeClass('active');
            tog.setProperty('aria-expanded', 'false');
            el.setProperty('aria-hidden', 'true');
            return false;
          },
          onComplete: function(tog, el){
            request = this.previous;
            if(request >= 0) {
              var open = this.togglers[request].getStyle('margin-top').toInt();
              if(open >= 0) new Fx.Scroll(window, {duration: 2000}).toElement(this.togglers[request]);
            }
          }           
        });
    Es geht um die onComplete Funktion.

    Danke für Hilfe!

    ToM
    Geändert von Nightwing (27.02.2019 um 10:20 Uhr)

  2. #2
    Contao-Fan Avatar von Nightwing
    Registriert seit
    29.05.2013.
    Beiträge
    436

    Standard

    Ich habe mal eine für mich halbwegs brauchbare Teillösung, aber verstehe das merkwürdige Verhalten dennoch nicht (Die Funktion scheint nicht mehr sauber zu funktionieren, erst beim dritten Klick (= active Status zum zweiten Mal)):

    HTML-Code:
      window.addEvent('domready', function() {
        new Fx.Accordion($$('.wrapper'), $$('.code'), {
          opacity: false,
          display: <?php echo $wid; ?>,
          duration: 1500,
          alwaysHide: true,
          onActive: function(tog, el) {
            tog.addClass('active');
            tog.setProperty('aria-expanded', 'true');
            el.setProperty('aria-hidden', 'false');
            
            /* request = this.previous;
            if(request >= 0) {
              var open = this.togglers[request].getStyle('margin-top').toInt();
              if(open >= 0) new Fx.SmoothScroll({duration: this.options.duration}, window).toElement(this.togglers[request]);
            } */
    
          return false;
          },
          onBackground: function(tog, el) {
            tog.removeClass('active');
            tog.setProperty('aria-expanded', 'false');
            el.setProperty('aria-hidden', 'true');
            return false;
          },
          onComplete: function(el){
            if(el.getSize().y > 0) {
              el.setStyle('height','auto');
            }
            el.scrollIntoView({block:'start', behavior:'smooth'}, true);
    
            /* request = this.previous;
            if(request >= 0) {
              var open = this.togglers[request].getStyle('margin-top').toInt();
              if(open >= 0) new Fx.SmoothScroll({duration: this.options.duration}, window).toElement(this.togglers[request]);
            } */
    
          }  
        });
    Der Code, egal ob in der Funktion onActive(); oder onComplete(); , bildet besagtes merkwürdiges Verhalten. In Version 2.11.17 funktionierte das einwandfrei (= siehe hier ):

    HTML-Code:
            request = this.previous;
            if(request >= 0) {
              var open = this.togglers[request].getStyle('margin-top').toInt();
              if(open >= 0) new Fx.SmoothScroll({duration: this.options.duration}, window).toElement(this.togglers[request]);
            }
    Nach längerer Recherche gestern in der Spätschicht hab ich das jetzt so drin, und es funktioniert. Nicht ganz so sauber, wie im Beispiellink, aber es funktioniert:

    HTML-Code:
          onComplete: function(el){
            if(el.getSize().y > 0) {
              el.setStyle('height','auto');
            }
            el.scrollIntoView({block:'start', behavior:'smooth'}, true);
          }  
    Für bessere Ideen bin ich dankbar!

    ToM

  3. #3
    Contao-Fan Avatar von Nightwing
    Registriert seit
    29.05.2013.
    Beiträge
    436

    Standard

    Bessere Funktion gefunden:
    Code:
    new Fx.SmoothScroll({duration:1500}, window).toElement(el);
    Hier das gesamte:

    HTML-Code:
    <?php
    $wid = '-1'; // default all closed
    //$wid = '0'; // default first open
    if (is_numeric($this->Input->get('wid'))) {
      $wid=(int)$this->Input->get('wid');
    }
    ?>
    <script>
      window.addEvent('domready', function() {
        new Fx.Accordion($$('.wrapper'), $$('.code'), {
          opacity: false,
          display: <?php echo $wid; ?>,
          duration: 1500,
          alwaysHide: true,
          onActive: function(tog, el) {
            tog.addClass('active');
            tog.setProperty('aria-expanded', 'true');
            el.setProperty('aria-hidden', 'false');
            new Fx.SmoothScroll({duration:1500}, window).toElement(el);
            return false;
          },
          onBackground: function(tog, el) {
            tog.removeClass('active');
            tog.setProperty('aria-expanded', 'false');
            el.setProperty('aria-hidden', 'true');
            return false;
          } 
        });
        $$('.wrapper').each(function(el) {
          el.setProperty('role', 'tab');
          el.setProperty('tabindex', 0);
          el.addEvents({
            'keypress': function(event) {
              if (event.code == 13 || event.code == 32) {
                this.fireEvent('click');
              }
            },
            'focus': function() {
              this.addClass('hover');
            },
            'blur': function() {
              this.removeClass('hover');
            },
            'mouseenter': function() {
              this.addClass('hover');
            },
            'mouseleave': function() {
              this.removeClass('hover');
            }
          });
        });
        $$('.ce_code').each(function(el) {
          el.setProperty('role', 'tablist');
        });
        $$('.code').each(function(el) {
          el.setProperty('role', 'tabpanel');
        });
      });
    </script>
    Nach Aktivierung pappt mir das Script allerdings einen Anker an die URL dran :#undefined
    wie bekomm ich das lästige Etwas wieder los?

    ToM

  4. #4
    Contao-Fan Avatar von Nightwing
    Registriert seit
    29.05.2013.
    Beiträge
    436

    Standard

    Letztendlich nutze ich es mit einem anderen Scrolleffekt, der mir auch keinen Ankerlink dranpappt:

    HTML-Code:
    <?php
    $wid = '-1'; // default all closed
    //$wid = '0'; // default first open
    if (is_numeric($this->Input->get('wid'))) {
      $wid=(int)$this->Input->get('wid');
    }
    ?>
    <script>
      window.addEvent('domready', function() {
        new Fx.Accordion($$('.wrapper'), $$('.code'), {
          opacity: false,
          display: <?php echo $wid; ?>,
          duration: 2000,
          alwaysHide: true,
          onActive: function(tog, el) {
            tog.addClass('active');
            // alert('add');
            tog.setProperty('aria-expanded', 'true');
            el.setProperty('aria-hidden', 'false');
            new Fx.Scroll( window, { duration: this.options.duration }).toElement(tog);
            // tog.getNext('div').fade('in');
            return false;
          },
          onBackground: function(tog, el) {
            tog.removeClass('active');
            // alert('remove');
            tog.setProperty('aria-expanded', 'false');
            el.setProperty('aria-hidden', 'true');
            // tog.getNext('div').fade('out');
            return false;
          },
          onComplete: function(tog, el) {
            // alert('scroll');
            // new Fx.Scroll( window, { duration: this.options.duration }).toElement(tog);
          }
        });
        $$('.wrapper').each(function(el) {
          el.setProperty('role', 'tab');
          el.setProperty('tabindex', 0);
          el.addEvents({
            'keypress': function(event) {
              if (event.code == 13 || event.code == 32) {
                this.fireEvent('click');
              }
            },
            'focus': function() {
              this.addClass('hover');
            },
            'blur': function() {
              this.removeClass('hover');
            },
            'mouseenter': function() {
              this.addClass('hover');
            },
            'mouseleave': function() {
              this.removeClass('hover');
            }
          });
        });
        $$('.ce_code').each(function(el) {
          el.setProperty('role', 'tablist');
        });
        $$('.code').each(function(el) {
          el.setProperty('role', 'tabpanel');
        });
      });
    </script>
    Live und in Farbe hier.

    ToM

  5. #5
    Contao-Fan Avatar von Nightwing
    Registriert seit
    29.05.2013.
    Beiträge
    436

    Standard

    Ich habe mittlerweile das Script und vor allem das Scrollverhalten nochmal gepimpt, allerdings bleibt noch eine (kleine) Macke, die mir die Perfektion raubt:

    Öffne ich Codebox A, scrollt es ans aktive Element, schliesse ich Codebox A, bleibt es korrekt an Position.
    Sinn und Zweck der Codebox an sich soll ja sein, langen Code auf der Seite auszublenden, um es bei Interesse einzublenden.
    Scrolle ich also bei geöffneter Box A nach unten, möchte ich ja nun durch Klick auf Box B den Effekt erreichen, das nun die aktive B nach oben scrollt, während A schliesst.
    Genau bei diesem Mischmasch verhackt sichs aber noch und scrollt zu weit nach oben (= Beispiel hier )...
    Hat mir jemand DIE Lösung dazu?

    Code:
    <?php
      $wid = '-1'; // default all closed
      //$wid = '0'; // default first open
      if (is_numeric($this->Input->get('wid'))) {
        $wid=(int)$this->Input->get('wid');
      }
    ?>
    <script>
      window.addEvent('domready', function() {
        new Fx.Accordion($$('.wrapper'), $$('.code'), {
          opacity: false,
          display: <?php echo $wid; ?>,
          duration: 1000,
          alwaysHide: true,
          onActive: function(tog, el) {
            el.setProperty('aria-hidden', 'false');
            tog.addClass('active');
            tog.setProperty('aria-expanded', 'true');
            tog.getNext('div').fade(1);
            new Fx.Scroll(window,{duration: this.options.duration}).toElement(tog.getNext('div'));
            return false;
          },
          onBackground: function(tog, el) {
            el.setProperty('aria-hidden', 'true');
            tog.removeClass('active');
            tog.setProperty('aria-expanded', 'false');
            tog.getNext('div').fade(0.35);
            return false;
          }
        });
        $$('.wrapper').each(function(el) {
          el.setProperty('role', 'tab');
          el.setProperty('tabindex', 0);
          el.addEvents({
            'keypress': function(event) {
              if (event.code == 13 || event.code == 32) {
                this.fireEvent('click');
              }
            },
            'focus': function() {
              this.addClass('hover');
            },
            'blur': function() {
              this.removeClass('hover');
            },
            'mouseenter': function() {
              this.addClass('hover');
            },
            'mouseleave': function() {
              this.removeClass('hover');
            }
          });
        });
        $$('.ce_code').each(function(el) {
          el.setProperty('role', 'tablist');
        });
        $$('.code').each(function(el) {
          el.setProperty('role', 'tabpanel');
        });
      });
    </script>
    Generell einmal die Frage an die Entwickler hier: wäre das ein Feature Request wert?
    Schliesslich wird Code + Syntaxhighlightning im Contao angeboten, und oft hat man ja langen Code stehen (= bestes Beispiel hier im Forum ).
    Für mich habe ich das ce_code.html5 Template umgestrickt und verdoppelt, sodas ich sowohl wenige Codezeilen ohne Box aber viele versteckt in der Box anzeigen kann (= Beispiel hier ).
    Zwei Templates, etwas CSS und eben das Script (= abgewandeltes moo_accordion.html5)

    ToM

    PS: Die Idee wäre imho auch im Forum ganz nett, ich selbst kenne es seit langem so, da es unser fleissiges Kellerkind so einen Codeschnipfel damals ins wbb2 eingebaut hat. Bei Call of Duty Problemen entsteht mindestens soviel Code wie hier bei den Logfiles...

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •