顯示具有 網頁設計 標籤的文章。 顯示所有文章
顯示具有 網頁設計 標籤的文章。 顯示所有文章

2018/12/27

各家瀏覽器的使用比例

一陣子沒有開 Google Analytics 看資料分析了,無意間發現瀏覽器市場有急大的改變:Google 瀏覽器變成主流。


敝站流量不多,但是跟十年前來比較,瀏覽器的市場的確有很大的改變。

ps. 以後可以不用考慮 IE 系列瀏覽器了 (逃)

2014/09/14

Post/Redirect/Get Pattern

Post/Redirect/Get (PRG) pattern 是一種處理表單資料的流程,可以防止使用者回上一頁、或是使用重新整理的方式重複送出表單資料。

再拿留言板舉例 (萬年題材 XD),假設在 form.html 填寫完表單,送出到資料到 post.php,而 post.php 處理資料後直接將結果顯示出來 (傳回 HTML),這個時候再瀏覽器按下「重新整理」按鈕,變會看到提示訊息,詢問是否要重送表單內容。


此時若重送表單資料,則會重新送出一模一樣的內容,若 post.php 沒有特別檢查,就會重複處理。很久以前開心農場就是用這種方法洗禮物的。

為了避免瀏覽器可以重新整理頁面,將資料處理的流程稍微做個調整:
  1. form.html 設定 submit 後,表單資料送給 post.php 處理
  2. post.php 處理資料後,不直接顯示 HTML,只送出 HTTP 3xx 做重新導向,跳到 done.php 顯示處理結果
  3. done.php 透過 URL 參數,顯示相對應的訊息

post.php 寫法大致如下:
if(saveData($_POST)){
   $status = 'ok';
}else{
   $status = 'error';
}

header('Location: done.php?status=' . $status);

由於使用 HTTP 3xx 重新導向,瀏覽器不會將 post.php 紀錄到瀏覽紀錄中,按下「上一頁」按鈕也是回到 form.html 而非 post.php,且 done.php 使用 HTTP GET 方式取得內容,所以重新整理頁面也不會重新送出表單內容。此流程按照三個步驟的 HTTP request 方式稱為 Post/Redirect/Get pattern。

PRG pattern 寫起來至少會有三個頁面要實作,也是挺麻煩的。若還要簡單一點的方式,那大概就是改用 AJAX 處理表單了吧。


Reference:
Post/Redirect/Get - Wikipedia, the free encyclopedia
http://en.wikipedia.org/wiki/Post/Redirect/Get

2014/04/23

瀏覽器與 HTTP Referer 之間的特性

無限期鬼打牆以後,才發現 HTTP Referer 不一定真的代表參考位址。

假設有三個頁面:

  1. form.html:填資料
  2. proccess.php:處理表單內容
  3. showError.php:表單內容有誤時,重新導向到這一頁

一般情況下 process.php 的 referer 會是 form.html、showError.php 的 referer 會是 process.php,但若 proccess.php 跳轉頁面是這樣寫:

if( ERROR ){
   header('Location: showError.php');
}

執行後 HTTP server 的回應會是 HTTP 302 而非 HTTP 200,瀏覽器不會將 302 視為正常的瀏覽行為,所以 proccess.php 不會被列入正式瀏覽記錄,當重新導向到 showError.php 時,Refer 仍然會是最後一個正式的瀏覽記錄,也就是 form.html。

若希望讓 showError.php 可以正確知道是哪一頁連過來的,就得靠其他方法了。

在這裡建議不要使用 HTTP Referer 來做判斷的依據。現有瀏覽器開發工具、外掛都可以讓人任意修改 Referer,也聽說有些防毒軟體會固定將 Referer 從 HTTP request 中刪除,再者,各家瀏覽器送 Referer 的情況也不同 (IE MUST DIE),用 Referer 判斷流程等方法會遇到不少例外情況要處理,別讓自己那麼累。



Reference:
php - HTTP_REFERRER and Location redirect - Stack Overflow

2012/09/01

jQuery 在表格新增一列

學 javascript 沒多久,剛開始只是很簡單的置換文字、為元素加上類別,短短幾行沒什麼感覺。到了開始動態新增表格資料時,javascript 程式碼裡面參雜 HTML 就越看越噁心。
function addRow( data ){
   $('#user-list > tbody ').append(
         '<tr> ' + 
            '<td>' + id + '</td>' +
            '<td>' + username + '</td>' +
            '<td>' + email + '</td>' +
         '</tr>'
      );
}

這樣的寫法除了可讀性很低以外,之後若修改表格結構以及 CSS 樣式時,必須同時修改樣板以及 javascript 內容,不容易維護。

今天翻了翻 jQuery docs,發現幾個方法拿出來用可以把 HTML 和 javascript 切割的頗乾淨。

先定義一列當作表格樣板,可以在 CSS 將這一列隱藏:
<table border="1">
  <tbody>
    <tr id="template" style="display: none;">
      <td class="id some-other-class"> </td>
      <td class="username"> </td>
      <td class="email"> </td>
    </tr>
  </tbody>
</table>

新增一列時,將 template 複製一份出來,再依照 class 名稱將資料填入不同欄位:
function addRow(){
  $('tr:last').after( $('#template').clone().removeAttr('id') );
  $('tr:last > td.id').text( id );
  $('tr:last > td.username').text( username );
  $('tr:last > td.email').text( email );
}


2012/07/18

Hook on header and footer

最近學用 Ajax 處理一些網頁上的事件,javascript 越寫越長,就覺得有必要按照程式碼類別拆成不同檔案,在執行時期決定到底哪些檔案需要匯入。像是管理介面用的 CSS、javascript 就需要在一般頁面當中載入,或是在不需要使用到 Google Maps 時將 javascript API 拿掉。

CodeIgniter 在 controller 與 view 切開後,傳遞資訊只能在 loader 載入時送參數,不過若有多個需要動態載入的資源放在一起,程式寫起來會很麻煩。

// Controller
$data['googleMapAPI'] = true;
$data['jqueryPlugin'] = true;

// View
<?php if( $googleMapAPI == true ): ?>
   <script src=" ..... "></script>
<?php endif; ?>

<?php if( $jqueryPlugin == true ): ?>
   <script src="...."></script>
<?php endif; ?>


這時候想到 Wordpress Codex 有個不錯的作法可以參考。Wordpress 為了讓樣板、外掛製作能夠分開、不會互相影響,做出了一個 add_action( ) 的功能,外掛設計師將需要執行的動作「註冊」到系統中,樣板設計師在特定位置呼叫時,系統便會執行已註冊的動作。

// Plugin
<?php
   add_action('wp_head', 'js_include');
   add_action('wp_footer', 'action-on-ready');

   function js-include(){
      echo '<script src="..."></script>';
   }

   function action-on-ready(){
      echo '<script> $('document').ready(); </script> ';
   }
?>

// Template
<html>
<head>
   <titie> .... </title>
   <!-- load script in header -->
   <?php echo wp_head(); ?>
</head>
<body>
   ......
   <!-- load page scripts in footer -->
   <?php wp_footer(); ?>
</body>
</html>


CodeIgniter 有 Hook 類別,不過並沒有 view 的插入點,想試試看能不能把 wordpress add_action( )  功能實作出來。

2012/02/15

CSS3 Background Future

JaceJu 的噗浪上看到 CSS3 background 新的特性,可以讓瀏覽器控制背景圖片的一些屬性,頗好用的。


CSS3 Backgrounds of the Future
http://www.andismith.com/blog/2012/02/css-backgrounds-of-the-future/


設定背景圖片:
body {
   backgroud: bg.jpg;  /* 1024x768 */
}

以上的設定,當視窗大小如你預期相同時,畫面便會與最初的設計相同,但若視窗較大或較小,都可能會讓畫面走樣。


加上 background-size 屬性,讓瀏覽器決定圖片的大小:
body {
   backgroud: bg.jpg;
   background-size: contain; 
}

修改之後,背景圖片便會依照視窗大小做調整。

2011/06/04

+1 按鈕

在部落格中塞了分享按鈕潮一下 :P

Blogger 的只要在設計選項中勾選「顯示分享按鈕」就會自動顯示,如果網頁樣板中沒有這個設定,可以參考這篇文章加入代碼即可。


在您的網站中加入 +1 按鈕 - +1 button API - Google Code
http://code.google.com/intl/zh-TW/apis/+1button/

2011/05/09

圖片編碼後鑲在網頁中

無意間發現 Google 404 頁面中的背景圖片並非以圖片形式存在,瀏覽器將 CSS 中的 base64 解碼後轉成圖片顯示而成。

檢視原始碼可看到:
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKsAAA....)


以這種方式鑲圖片的好處,除了點右鍵沒辦法令存圖片、暫存檔沒有實體檔案外 (其實我原始的目的就是想複製他的圖片 XD),主要的用途是讓瀏覽器不會對伺服器做而外的要求動作。

一般來說,瀏覽器會先取得 HTML,解譯過後發現需要額外的檔案,如:CSS、Javascript、圖片等,就會依照 HTML 中的網址向伺服器要檔案,若檔案數量很大則可能會造成伺服器不少負擔。若是將檔案直接鑲在網頁當中,瀏覽器解譯後直接使用,則不必再向伺服器要求資源。


參考資料:Data URI Scheme @ Wikipedia
http://en.wikipedia.org/wiki/Data_URI_scheme


找到一個工具可以將網路上的資源轉 base64,供大家將資源鑲在網頁中。

Binary / Image File to Base64 Encoder / Translator
http://www.greywyvern.com/code/php/binary2base64

2010/06/14

IE 6 Must Die

IE 6 是一個歷史悠久的瀏覽器,不是說他不好而是因為 parser 實在沒有按照標準撰寫,導致網頁設計的時候一堆語法還要為 IE6 客製化,實在浪費生命。

在網頁底下加入一段語法,讓使用 IE6 瀏覽網頁的使用者會收到建議更換瀏覽器的訊息:
<!--[if IE 6]>
   <script type="text/javascript" src="http://letskillie6.googlecode.com/svn/trunk/letskillie6.zh_TW.pack.js"></script>
<![endif]-->


參考資料:Let's Kill IE6
http://www.neoease.com/lets-kill-ie6/

2010/02/16

CSS 圓角矩形

LESS 看到的:
.rounded_corners {
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
}

LESS make less code to CSS

LESS 是一個用 Ruby 寫成的 CSS 產生器,可以讓習慣寫成是的人將 CSS 程式、模組化,在交由 LESS 轉成正式的 CSS 發佈。

例如事先定義:
@my_color: #f00;

之後可以在各個 class 用到:
.top {
   ...
   font-color: @my_color;
}

.main {
   background-color: @my_color;
}

感謝 Jefflen 推薦。


LESS - leaner CSS
http://lesscss.org/

2010/02/15

CSS width in box module

今天遇到的鳥問題:CSS 中真正的 width 要等於 margin + border + padding + 設定的 width。

假設原本的 DIV 設定如下:
.box {
   width: 800px;
}

若要讓原本的區塊寬度不變但要加上 20px 的 padding 必須這樣設定:
.box-padding {
   padding-left: 20px;
   padding-right: 20px;
   width: 760px; /* 800 - 20 - 20 = 760 */
}