Sideovergang

rimby

Medlem
Hvordan fungerer log kommandoen der? hvor lagres informasjonen?

Uansett. Side3 ligger nå oppå side 2
Dersom jeg skriver dette:
Kode:
$("#side3").hide();
...blir alt normalt.
Hvordan kan jeg plassere side3 "under" side2, gjerne slik at jeg kan bruke easing igjen
når et bilde trykkes
 

adeneo

Medlem
Når du skriver noe til konsollen, lagres det i .... wait for it .... konsollen.

Du åpner konsollen i de fleste nye nettlesere ved å trykke F12 og trykke på "console" e.l.

hide() er i utgangspunktet omtrent det samme som display:none, slik at det skjuler elementet.

Alle elementer begynner livet med position static, og som static kan man ikke sette avstander slik som top eller left, til det må vi normalt endre til position relative.
Relativ gjør selvfølgelig at elementene kommer naturlig etter hverandre, skal man ha to elementer på samme sted, er det ofte enklest å sette de til position absolute og samme top, left, height, width osv.
 

rimby

Medlem
ok, loggen viste hva som var feil.
bilde nr1 - index 0
bilde nr2 - index 2
bilde nr3 - index 4
bilde nr4 - index 6

Kode:
	$("#side2 dt").on('click', function() { 
		$("#side2").hide();
        $("#side3").show().children('div').eq($(this).index()).show().siblings().hide();		
		console.log($(this).index()); 
    });
Nedenfor er lista. Jeg må nesten ha det slik for å plassere teksten riktig i fohold til bildene.
Av en eller annen grunn teller indexen også med "<dd>"
Kode:
		<dl>
			<dt>"Bilde"</dt>
				<dd>"tekst"</dd>
			<dt>"Bilde"</dt>
				<dd>"tekst"</dd>
			<dt>"Bilde"</dt>
				<dd>"tekst"</dd>
			<dt>"Bilde"</dt>
				<dd>"tekst"</dd>
		</dl>
Jeg har prøvd å lage en class="bilde" til vært bilde og endre koden slik:
Kode:
$("#side2 .bilde").on('click', function() {
Men det fungerte ikke..
Noen ideer om hvordan jeg skal få den kun til å telle <dt> ?

*nvm fikset: index() / 2) gjorde susen
 
Sist redigert:

adeneo

Medlem
Jepp, alle elementer har naturlig nok en index.
Og dele den fungerer, og i mer innviklede tilfeller kan modulus brukes.

PHP:
$(this).index() % 9 == 1;

eller css nth-child med index/odd/even

PHP:
$("div:nth-child(3n+1)")

det er til og med mulig å filtrere med bitwise operatører eller regex ved bruk av et filter();

PHP:
$('div').filter(function() {
    return this.value.match(/\d+/):
}).hide();

Mye fiffige løsninger man kan bruke for å finne elementer, det er nesten uendelige muligheter.
 

rimby

Medlem
Hvis jeg går til side2 og oppdaterer siden, vil den vise alle diver, ikke bare den jeg er på.
Dersom du ser på MEGA ser du at det ikke er slik. Der er det også mulig å bruke fram og tilbake knappen mellom sidene, pga at sidene har forskjellig url.
Hvordan kan dette gjøres?
 

adeneo

Medlem
På MEGA brukes HTML5 history API'en, da det er eneste måte å endre URL'en på uten å laste siden på nytt (utover å bare endre hashen).

Det fungerer slik at man "dytter" adresser inn i nettleserens historie med history.pushstate osv. men det er litt kronglete å både forklare og bruke.

Det var en plugin for dette som het history.js, se om du finner den, så er nok det enklest.
 

rimby

Medlem
Har du brukt history.js før? virket komplisert og som noe det tar tid å sette seg inn i.
hadde vært greit med et veldig enkelt eksempel :p
 

adeneo

Medlem
Det er jo ikke bare å bare og sette opp et "enkelt" eksempel på hvordan history API'en virker, og jeg har faktisk aldri brukt history.js da jeg som regel gjør det fra bunnen av selv.
Det er ikke mulig å bruke ting som jsFiddle til dette heller ettersom det ikke virker å endre URL'en der?

Et veldig kjapt eksempel kan jeg alltids skrive, men det må bli i object literal, da det er slik jeg som regel skriver javascript:

PHP:
var site = {
    init: function() {
         this.binds();
    },
    supportsHistory: function() { //sjekk om nettleseren har støtte
         return history.pushState; 
    },
    vars: {  //sett opp noen variabler
        startPop: false,
        currentPage: document.location.pathname
    },
    binds: function() { //bind noen "events" med jQuery osv
        $(window).on({
            load: function() {
                site.vars.startPop=true; //unngå å fyre av popstate på vanlige sidelastninger
            },
            popstate:function(e) {
                if (!site.vars.startPop) { //bruk en funksjon til å oppdatere sidens innhold
                    site.updatePage(e.originalEvent.state!=null?e.originalEvent.state.page:document.location.pathname, true);
                }else{
                    site.vars.startPop=false;
                }
            }
        });
    },
    updatePage: function(page, type) {
        if (this.vars.currentPage != page) { //sjekk at siden har endret seg siden sist
            if (this.supports.history()) { //sjekk at nettleseren har History API
                if (!type) { //hvis ikke det var window.popstate
                    history.pushState({ page: page }, page, page); //bytt URL i nettleseren
                }
                switch (page) {
                    case '/side1/': //bytt innholdet ettersom hvilken side det er
                        $('.sider').hide(); //hjem alle sidene (div'er)
                        $("#side1").show(); //vis side1 div'en
                        break;
                    case '/side2/':
                        $('.sider').hide(); //hjem alle sidene (div'er)
                        $("#side2").show(); //vis side2 div'en
                        break;
                    default: 
                        $('.sider').hide(); //hjem alle sidene (div'er)
                        $("#startsiden").show(); //vis startside for alle andre adresser
                }
            }
            this.vars.currentPage = page; //oppdater variable for side
        }
        return this;
    }
}

$(function() {
    site.init(); //start javascript for nettsiden når jQuery er klar
});

Det er bare et kjapt eksempel, det er en hel del mer som skal til og som man ofte må prøve seg frem til i hvert tilfelle, slik som å gå forover / bakover med history.back() osv, det står noe på MDN om hvilke valg som finnes, og diveintohtml5 har noen eksempler med blant annet å hente innhold via ajax.
 

rimby

Medlem
Skjedde ingen verdens ting når jeg la til dette.
url-en endret seg ikke og "nettsideurl-en"/side1/ sente meg heller ikke til #side1 :(
Det er egentlig ikke en del av pensum å lære å lage slike dynamski sider. Jeg synes det er greit å lære det uansett, men dette er en del utenom det jeg kan.

Jeg ser for meg at dette kan gjøres enklere ved å bruke #tags. Problemet er at jeg kun får nettleseren til å vise #side1 og #side2, ikke #innhold1 osv, som er en under-div av #side2, som i demoen din. #side2 det blir også vist feil. menyen vises ikke.
 

adeneo

Medlem
Det var bare et kjapt eksempel på hvordan en slags mal for History API'en kunne sett ut, og det virker nok ikke bare ved å sette det inn, men må tilpasses mer.

Det er enklere med en hash selvfølgelig, ofte kan man bare sette eller hente hashen med document.location.hash, og man kan binde en event til hver gang hashen endres, og endring av hashen vil ikke laste siden på nytt osv. :

PHP:
<ul id="menu">
   <li><a href="side1">side 1</a></li>
   <li><a href="side2">side 2</a></li>
<ul>

<div id="side1"></div>
<div id="side2"></div>

$('#menu li a').on('click', function(e) {
    e.preventDefault();
    document.location.hash = $(this).attr('href');
});

$(window).on('hashchange', function() {
    $(document.location.hash).show();
});
 

rimby

Medlem
abh.. ble bare krasj da jeg prøvde å kombinere det der med scrolling scriptet som ligger inne frafør :(
 

rimby

Medlem
haha så sant så sant. Du har vært til stor hjelp :)
Nå begynner ting å fungere. Men har fortsatt to problemer, dersom jeg oppdater siden vises alle divene oppå hverandre. Er det mulig å få den til å vise siste siste side jeg var innpå ved page onload?
Det andre problemet er at den ikke fjerner classen "selected" fra tabbene lenger når du trykker på en ny tab. Dette skjedde etter at jeg gjorde om menyen til en liste med linker istedenfor bare tabell.

Kode:
$(function() { 															
    $(".menu dt").on('click', function() {    										
        var h = $(window).height() - 120; 																							
        $('#menu dt a').on('click', function(e) { 
		e.preventDefault(); 
		document.location.hash = $(this).attr('href'); 
	}); 

	$(window).on('hashchange', function() { 
		$(document.location.hash).show().siblings().hide();
		$("#side1").show()
	}); 
        $('body, html').stop().animate({scrollTop: h},800, "easeInOutBack"); 	
        $('#top').fadeIn(500); 														// Fader inn top (Forside knappen)
		$(this).addClass('selected').siblings('dt').removeClass('selected');	
    });  

    $('#top').on('click', function() { 										
        $('body, html').stop().animate({scrollTop: 0},800, "easeInOutBack"); 	
        $('#top').fadeOut(500);													
		$('dt').removeClass('selected');										
    });
});
 
Sist redigert:

rimby

Medlem
Har gjort om en del i html og nå ser det slik ut:
Kode:
$(function() { 	
	$(document.location.hash).show().siblings().hide();

	$(window).on('hashchange', function() { 
		$(document.location.hash).show().siblings().hide();
		$("#side1").show();
	});	

    $(".menu a").on('click', function() {    										
        var h = $(window).height() - 120; 

		$('body, html').stop().animate({scrollTop: h},2000, "easeInOutBack"); 	
		$('#top').fadeIn(500); 		
	}); 	

    $('#top').on('click', function() { 										
        $('body, html').stop().animate({scrollTop: 0},1000, "easeInOutBack"); 	
        $('#top').fadeOut(500);																							
    });	

});
Det eneste som kan være litt irriterende nå er at dersom man trykker på en tab ganske raskt etter at siden er lastet, blir easing animasjon laggy og man kan noen gangen se alt innholdet oppå hverandre i 1 sec før det retter seg. Er det mulig å ordne det slik at den kun utfører animasjon etter at alt er på plass?

En ting til.. Jeg har to textfelter som det skal fylles inn en "fra dato" og en "til dato"
For å fylle inn dato har jeg brukt denne pluginen Datepicker | jQuery UI
Hvordan kan man ordne slik at "til dato" kan max være 14 dager etter "fra dato"?
Prøvde dette, men fungerte tydeligvis ikke.
Kode:
		var date1 = (document.getElementById('dato1').value);
		var date2 = (document.getElementById('dato2').value);
		if(((date2*1) - (date1*1)) > 14) {
			errormelding += "bla bla bla bla";
		}
 

adeneo

Medlem
For å ordne datepicker'en så setter du den opp med de rette options osv.
Det hjelper ikke å prøve å overstyre datepicker'en, selv om en feilmelding kanskje hadde virket. Det enkleste er å begrense valgene rett i datepickeren, noe sånt:

PHP:
/* Norsk språk */
$.datepicker.regional['no'] = {
    closeText: 'Lukk',
    prevText: 'Forrige måned',
    nextText: 'Neste måned',
    currentText: 'I dag',
    monthNames: ['Januar', 'Februar', 'Mars', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Desember'],
    monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'],
    dayNamesShort: ['Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'],
    dayNames: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag'],
    dayNamesMin: ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø'],
    weekHeader: 'Uke',
    dateFormat: 'dd.mm.yy',
    firstDay: 1,
    isRTL: false,
    showMonthAfterYear: false,
    yearSuffix: ''
};
$.datepicker.setDefaults($.datepicker.regional['no']);

/* Sett opp "fra" slik at den oppdaterer "til" til kun 14 dager etter */
$("#from").datepicker({
    showWeek: false,
    hideIfNoPrevNext: true,
    firstDay: 1,
    minDate: 0,
    showOtherMonths: true,
    onSelect: function(selectedDate) {
        var minDate = $(this).datepicker('getDate'),
            maxDate = $(this).datepicker('getDate');
        maxDate.setDate(minDate.getDate() + 14);
        $("#to").datepicker("option", "maxDate", maxDate);
        $("#to").datepicker("option", "minDate", minDate);
    }
});

/* og sett maxdate til 14 dager ved start */
$("#to").datepicker({
    showWeek: false,
    hideIfNoPrevNext: true,
    firstDay: 1,
    minDate: 0,
    showOtherMonths: true,
    maxDate: "+14D"
});
DEMO

Du kan også style den akkurat slik du vil med CSS, men det er litt komplisert CSS som ligger bak slik at dersom du ikke trenger noe spesielt kan du bruke themerolleren til jQuery UI for å få et annet utseende.

Når det kommer til å vente på at alt innholdet er lastet inn, så kan man bruke window.onload, eller dersom det er noen bilder eller noe som gjør at det tar litt tid kan man vente på de bildene, men akkurat hvordan man skal gjøre det er litt vanskelig å forklare da det kan variere veldig hva som er den beste løsningen.

Normalt holder
PHP:
$(function() { ... });
for å vente til DOM'en er klar, og jeg ville nok brukt den, men det er selvfølgelig mulig å bytte den ut med
PHP:
window.onload = function() { ... }
eller å sette en timeout på DOM ready som venter et sekund før knappene begynner å virke osv.
 
Sist redigert:
Topp