何かありましたら、メールで連絡いただくか、ブログのどこかにコメント入れてくださいね
Menu
ゼロと無限の間に
-
- WebサービスAPI用のPHPライブラリのリンク集
-
- 日曜大工ですな
-
- 何が出るかな
-
- いつかここが宝石箱になるといいな
-
- 蛇のおともに薬箱
-
- おさるのチャチャチャ
-
- ささやかな小箱です
コメントと更新履歴はゼロと無限の間のログ » Pryn.js & cssへどうぞ。
よく使う初期設定用のJavaScriptとCSSをまとめたもの。
主にユーザビリティの向上が目的。JavaScriptとCSSを読み込めば、あとは自動で設定される。
使いやすくするためにMITライセンスで公開した。
※サンプルで使っているのは最新のBeta版の場合あり
MITライセンスで。
内部的に使っているYUIのCSSはBSDライセンス。
Pryn.cssではGoogleによってホスティングされているYUIのCSSをimportする。これについてはGoogle AJAX Libraries APIの利用規約も確認のこと。
/** * Pryn.js * @see http://0-oo.net/sbox/javascript/pryn-js-css * @version 0.2.5 * @copyright 2007-2010 dgbadmin@gmail.com * @license http://0-oo.net/pryn/MIT_license.txt (The MIT license) * * 連携するCSSクラス * (a, form).open 別Windowで開く * (a, form).same-window 同じWindowで開く * (input, textarea).ready ページ表示時に入力待機状態にする要素 * autofocus属性にも対応 * (input, textarea).focused 入力中の要素 * (input, textarea).hint ヒント付テキストボックス。placeholder属性にも対応 * placeholder属性を使わない場合は、 * ・入力後のclassは ex-hint になる * ・ヒントはtitle属性にセットしておく * (input, textarea).copy コピー用テキスト * table.stripes シマシマにしたい表 * tr.stripe シマシマにされた行 * .wait formをsubmit後のマウスカーソル設定用 * .round-inner 角丸の内側(必要に応じてpaddingを指定する) */ /** IE高速化 @see http://d.hatena.ne.jp/amachang/20071010/1192012056 */ /*@cc_on _d = document; eval("var document = _d")@*/ /***** 組み込みオブジェクトの拡張 *****/ /** * 文字列のtrim * @return String trim後の文字列 */ String.prototype.trim = function() { return this.replace(/(^\s+|\s+$)/g, ""); }; /** * 子要素全てに関数の処理を実行する * @param Object it 子要素をループ処理できるオブジェクト */ Function.prototype.foreach = function(it) { for (var i = 0, len = it.length; i < len; i++) { this(it[i]); } }; Function.prototype.foreach.foreach = null; //再帰を防ぐ /***** グローバル関数/オブジェクト *****/ /** * Firebugが無い場合はconsole.log()を空振りさせる */ if (!window.console) { window.console = { log: function(s){}, dummy: true }; } /** * html要素をidで取得する(既に$()があればそちらを使う) * @param String id * @retrun HTMLElement html要素 */ if (!window.$) { window.$ = function(id) { return document.getElementById(id); }; } /** * html要素をタグ名で取得する * @param String tagName * @retrun NodeList */ function $T(tagName) { return document.getElementsByTagName(tagName); } /***** Pryn *****/ var Pryn = {}; /** * イベントを追加する * @param HTMLElement elm * @param String eventName * @param Function fnc */ Pryn.addEvent = (function(){ if (window.attachEvent) { return function(elm, eventName, fnc){ //IEでもfunction内でthisで自分(elm)を参照できるようにする elm.attachEvent("on" + eventName, function(){ fnc.call(elm); }); }; } //Safari3.0.x以前はDOMContentLoadedに未対応 var webKit = navigator.userAgent.match(/AppleWebKit\/([0-9]+)/); var oldWebKit = (webKit && webKit[1] < 525); return function(elm, eventName, fnc){ if (elm == window && eventName == "load" && !oldWebKit) { document.addEventListener("DOMContentLoaded", fnc, false); } else { elm.addEventListener(eventName, fnc, false); } }; })(); /** * 選択リストで選択された選択肢を取得する * @param String id 選択リストのid * @return HTMLElement 選択された選択肢(option要素) */ Pryn.getSelected = function(id){ var selector = document.getElementById(id); return selector.options[selector.selectedIndex]; }; /** * 角丸っぽく見せる * @param HTMLElement elm */ Pryn.round = function(elm){ elm.style.padding = "1px 0"; elm.innerHTML = '<div class="round-inner">' + elm.innerHTML + "</div>"; }; /***** Pryn.ClassAccessor *****/ /** * html要素のclass属性へのアクセサクラス * @param HTMLElement elm */ Pryn.ClassAccessor = function(elm) { /** * html要素にclassがあるか確かめる * @param String cName * @return Mixed あればArray、なければnullまたは"" */ this.hasClass = function(cName) { var cn = elm.className; return (cn && cn.match(this._toRegExp(cName))); }; /** * html要素にclassを追加する * @param String cName */ this.addClass = function(cName) { if (!this.hasClass(cName)) { elm.className += " " + cName; } }; /** * html要素からclassを削除する * @param String cName */ this.removeClass = function(cName) { elm.className = elm.className.replace(this._toRegExp(cName), " "); }; /** * html要素のclassを変更する * @param String oldClass * @param String newClass */ this.convertClass = function(oldClass, newClass) { this.removeClass(oldClass); this.addClass(newClass); }; /** * class名を表す正規表現を取得する * @param String cName * @return RegExp */ this._toRegExp = function(cName) { return new RegExp("(^|\\s)" + cName + "(\\s|$)", "ig"); }; }; /***** Pryn.Init *****/ /** * ページ表示時の初期処理 */ Pryn.Init = { /** 別ドメインへの遷移を別Windowで開くかどうか */ keepThisSite: true, /** formの二重送信防止を解除するまでの時間(秒) */ frozenTime: 10, /** formの二重送信防止対象 */ frozen: [], /** label要素と対応させるidの番号 */ labelForIdNo: 0, /** label要素と対応させるidのプリフィクス */ labelForIdPrefix: "pryn-label-for-id-", /** imageボタンの配列 */ _inputImages: [], /** HTML5 placeholder属性対応可否 */ _placeHoldable: navigator.userAgent.match(/AppleWebKit/) }; /** * 表をシマシマにする(奇数番目のtr要素のclassに stripe を追加する) * シマシマにしたくない行(見出し行など)はthead要素で囲っておくこと * @param HTMLElement table table要素 */ Pryn.Init.stripeTable = function(table) { if (!(new Pryn.ClassAccessor(table)).hasClass("stripes")) { return; } var rows = table.getElementsByTagName("tbody")[0].getElementsByTagName("tr"); for (var i = 0, len = rows.length; i < len; i += 2) { (new Pryn.ClassAccessor(rows[i])).addClass("stripe"); } }; /** * formの子要素のstyle等の設定 * @param HTMLElement fElm formの子要素 */ Pryn.Init.setStyles = function(fElm) { var acs = new Pryn.ClassAccessor(fElm); if (fElm.tagName == "TEXTAREA") { Pryn.Init._setTextStyle(fElm, acs); } else if (fElm.tagName == "INPUT" && !fElm.getAttribute("type")) { fElm.type = "text"; //FirefoxとOperaはセットしないとtextと認識しない } switch (fElm.type) { case "text": case "password": Pryn.Init._setTextStyle(fElm, acs); break; case "submit": fElm.value = fElm.value || "クエリ送信"; //IEに合わせる break; case "image": Pryn.Init.setSmartImage(fElm); Pryn.Init._inputImages.push(fElm); break; } if (acs.hasClass("ready") || fElm.getAttribute("autofocus") != undefined) { fElm.focus(); //デフォルトでfocusを当てる } }; /** * テキスト入力系要素のstyle等の設定 * @param HTMLElement fElm formの子要素 * @param Pryn.ClassAccessor acs */ Pryn.Init._setTextStyle = function(fElm, acs) { //HTML5 placeholder対応済みブラウザはplaceholderを使う if (Pryn.Init._placeHoldable) { if (acs.hasClass("hint")) { fElm.placeholder = fElm.title; acs.removeClass("hint"); } } else { //placeholder未対応ブラウザはhintクラスにより対応 var placeHolder = fElm.getAttribute("placeholder"); if (placeHolder) { fElm.title = placeHolder; acs.addClass("hint"); } } Pryn.addEvent(fElm, "focus", function() { //フォーカスされた時 if (!fElm.readOnly) { acs.addClass("focused"); } if (acs.hasClass("hint")) { //ヒント付テキストボックス this.value = ""; acs.convertClass("hint", "ex-hint"); } else if (acs.hasClass("copy")) { //コピー用テキスト setTimeout(function() { fElm.select(); }, 100); //selectし損ねるのを防ぐ } }); Pryn.addEvent(fElm, "blur", function() { //フォーカスが外れた時 acs.removeClass("focused"); if (acs.hasClass("ex-hint") && !fElm.value) { //ヒント付テキストボックスで未入力 acs.convertClass("ex-hint", "hint"); fElm.value = fElm.title; } }); if (acs.hasClass("hint")) { //ヒント付テキストボックス if (fElm.value && fElm.value != fElm.title) { //既に値がある場合 acs.convertClass("hint", "ex-hint"); } else { fElm.value = fElm.title; //title属性の値を表示 } } else if (acs.hasClass("copy")) { //コピー用テキスト fElm.readOnly = true; } }; /** * 別Windowで開くリンク・formの設定 * @param HTMLElement obj a要素 or form要素(自動判断にはhref属性が必要) */ Pryn.Init.setTarget = function(obj) { var url = (obj.href || obj.action); if (!url) { return; } var acs = new Pryn.ClassAccessor(obj); var ext = false; if (Pryn.Init.keepThisSite && !acs.hasClass("same-window")) { //外部へのリンクかどうか ext = (url.match(/^http(|s):/i) && url.split("/")[2] != location.hostname); } if (ext || acs.hasClass("open")) { obj.target = "_blank"; } }; /** * formの二重送信防止と別Windowで開く設定 * @param HTMLElement frm */ Pryn.Init.setSmartSubmit = function(frm) { Pryn.addEvent(frm, "submit", function() { Pryn.Init._setSubmitStyles.foreach(this); //imageボタンはformの子要素にならないので別途処理 Pryn.Init._setSubmitStyles.foreach(Pryn.Init._inputImages); //ページ全体のマウスカーソルも変える Pryn.Init._setSubmitStyles(document.body); }); Pryn.Init.setTarget(frm); //必要に応じて別Windowで開く }; /** * formのsubmit時の処理 * @param HTMLElement formの子要素等 */ Pryn.Init._setSubmitStyles = function(fElm) { var acs = new Pryn.ClassAccessor(fElm); if (acs.hasClass("hint")) { //送信前にヒントをクリア fElm.value = ""; } if (fElm.disabled) { return; } //操作不可にして、しばらくしたら戻す setTimeout(function() { fElm.disabled = true; acs.addClass("wait"); }, 1); setTimeout(function() { fElm.disabled = false; acs.removeClass("wait"); }, Pryn.Init.frozenTime * 1000); Pryn.Init.frozen.push(fElm); }; /** * label要素のクロスブラウザ対応(Safari2以前は非対応) * @param HTMLElement label */ Pryn.Init.setSmartLabel = function(label) { if (!label.htmlFor) { var input = label.getElementsByTagName("INPUT")[0]; if (!input) { return; } else if (!input.id) { input.id = Pryn.Init.labelForIdPrefix + Pryn.Init.labelForIdNo++; } label.htmlFor = input.id; //IE6ではfor属性の省略ができない } //IEはlabel要素内のimg要素をクリックしてもチェックが付かない var images = label.getElementsByTagName("IMG"); var len = images.length; if (!len) { return; } var clickIt = function() { document.getElementById(label.htmlFor).click(); }; for (var i = 0; i < len; i++) { Pryn.addEvent(images[i], "click", clickIt); } }; /** * 画像系要素のtitleの設定 * @param HTMLElement img */ Pryn.Init.setSmartImage = function(img) { //title属性をセット(IEの動きに合わせる) if (!img.title && img.alt) { img.title = img.alt; } }; /** * 初期処理(Pryn.Initの実行。見た目の影響のあるものを優先) */ Pryn.addEvent(window, "load", function() { Pryn.Init.stripeTable.foreach($T("table")); Pryn.Init.setStyles.foreach($T("input")); Pryn.Init.setStyles.foreach($T("textarea")); Pryn.Init.setTarget.foreach($T("a")); Pryn.Init.setSmartSubmit.foreach($T("form")); Pryn.Init.setSmartLabel.foreach($T("label")); Pryn.Init.setSmartImage.foreach($T("img")); Pryn.Init.setSmartImage.foreach($T("area")); }); /** * formの二重送信防止の凍結解除 */ Pryn.addEvent(window, "unload", function() { (function(fElm) { fElm.disabled = false; (new Pryn.ClassAccessor(fElm)).removeClass("wait"); }).foreach(Pryn.Init.frozen); });
@charset "UTF-8"; /** * Pryn.css * @see http://0-oo.net/sbox/javascript/pryn-js-css * @version 0.2.5 * @copyright 2007-2010 dgbadmin@gmail.com * @license http://0-oo.net/pryn/MIT_license.txt (The MIT license) */ /******************************************************************************* * YUI 2 CSS Toolsのimport * @see http://developer.yahoo.com/yui/2/ * Grids.cssはbuilderが便利 * @see http://developer.yahoo.com/yui/grids/builder/ ******************************************************************************/ /** * GoogleのCDNから読み込む(httpsも使えてyahooapis.comより速い) * @see http://code.google.com/intl/en/apis/ajaxlibs/documentation/#yui */ @import "https://ajax.googleapis.com/ajax/libs/yui/2/build/reset-fonts-grids/reset-fonts-grids.css"; @import "https://ajax.googleapis.com/ajax/libs/yui/2/build/base/base-min.css"; /** YUI 2 CSS Tools適用後の調整 */ body{ margin: 0; } select, input, textarea, button{ margin-right: 1px; } select, input[type="text"], input[type="password"], textarea{ border: solid 1px #7f9db9; /* 背景色を指定しても枠線が変わらないようにする */ } input[type="text"], input[type="password"], textarea{ padding: 2px; } input[type="submit"], input[type="button"], input[type="reset"], button{ padding: 0 1em; /* クリックしやすいように広げる */ /* IE8:余白調整 */ padding-top: 2px\9; line-height: 1.3; /* IE7:ボタンが大きいので小さめにする */ *padding: 3px 0.4em 0; *line-height: 1; } /** * フォント指定 * ・IE7+ : メイリオ(IE7+はClearTypeが適用されるのでギザギザにならない) * ・Mac : ヒラギノ * ・その他: 半角はVerdana、全角はブラウザのデフォルトフォント */ body, select{ font-family: "メイリオ", Verdana, sans-serif; /* IE7+ */ _font-family: Verdana, sans-serif; /* IE6 */ } html:not(:target) body, html:not(:target) select{ /* その他 */ font-family: "Hiragino Kaku Gothic Pro", Verdana, sans-serif; } input, textarea, button{ /* 巨大化するのでメイリオにしない */ font-family: "Hiragino Kaku Gothic Pro", Verdana, sans-serif; } /******************************************************************************* * 汎用的なstyle ******************************************************************************/ html{ /* Firefox:常に縦のスクロールバーを表示 */ overflow-y: scroll; } textarea{ /* IE:スクロールバー不要なら非表示 */ overflow: auto; } a, object{ /* クリックされた時に破線を表示しない */ outline: none; } img{ /* IE:サイズを変えた画像を綺麗にする */ -ms-interpolation-mode: bicubic; } select, label, button, input.copy, textarea.copy, .clickable{ cursor: pointer; /* マウスカーソルを手にする(IE7-:select非対応)*/ } input[type="submit"], input[type="button"], input[type="reset"], input[type="image"], input[type="checkbox"], input[type="file"], input[type="radio"]{ cursor: pointer; /* マウスカーソルを手にする(Firefox:file非対応)*/ } select[disabled], input[disabled], textarea[disabled], button[disabled]{ cursor: not-allowed;/* マウスカーソルを禁止マークに(IE6:非対応、IE7+:一部のみ) */ } body.wait, select.wait, input.wait, textarea.wait{ cursor: wait; /* マウスカーソルを砂時計やクルクルにする */ } input, textarea{ /* IME On */ ime-mode: active; } select, input.han, input.number, textarea.han{ /* IME Off */ ime-mode: inactive; } input[type="password"]{ /* Firefox:パスワードでautoだとIME不可になる */ ime-mode: auto; } input.number{ /* 数値 */ text-align: right; } optgroup{ color: #728490; } option{ /* optgroupから引き継ぐ文字色を元に戻す */ color: #000; } table.collapse{ /* cellspacing="0" cellpadding="0" */ border-collapse: collapse; } .left{ float: left; } .right{ float: right; } .center{ text-align: center; } .clear{ /* floatのクリア */ clear: both; } .nowrap{ /* 改行防止 */ white-space: nowrap; } /** * 角丸っぽく見えるボックス */ .round-outer{ /* こちらに背景色(あればmarginも)を指定する */ padding: 1px 0; } .round-inner{ /* こちらに(あれば)paddingを指定する */ display: block; margin: 0 -1px; background-color: inherit; } /** * バリアフリーな色 * @see http://jfly.iam.u-tokyo.ac.jp/colorset/ */ .bf-gray{ color: #728490; } /******************************************************************************* * サイトごとのstyle(サイトに合わせて上書きする) ******************************************************************************/ #bd{ font-size: 116%; /* @see http://developer.yahoo.com/yui/fonts/#using */ line-height: 1.4; /* 単位を付けない */ } div.error, span.error{ /* 入力エラーメッセージ */ color: #f30; font-weight: bold; } a{ color: #03c; /* Bingの色 */ } a:visited{ color: #639; /* Bingの色 */ } a:hover, a:active{ color: #c11; /* Googleのactiveの色 */ } select.error, input.error, textarea.error{ background-color: #ffd3cc; /* 入力エラーの要素(Firefox:check系非対応) */ } input.focused, textarea.focused{/* フォーカスされた入力要素 */ background-color: #ff9; } input.hint, textarea.hint{ /* テキストボックス内の説明文 */ color: #728490; } input[readonly], input[disabled][type="text"], input[disabled][type="password"], textarea[readonly], textarea[disabled]{ /* 使用不可系 */ background-color: #eee; } pre{ background-color: #ccc; } table.stripes tr.stripe{ /* シマシマにされる行 */ background-color: #ccc; } .border-radius{ /* 角丸(IE:非対応) */ border-radius: 10px; /* Chrome, Opera */ -moz-border-radius: 10px; /* Firefox */ -webkit-border-radius: 10px;/* Safari, (Chrome) */ } /** * Googleカスタム404ページ対応 * @see http://www.google.com/support/webmasters/bin/answer.py?hl=jp&answer=100044 */ #goog-wm li{ padding-bottom: 1em; }