Fly higher! Sky is the limit!

webの現場で働く人のブログ

配列の宣言で警告。

JSHintで警告が出ていた。

the array literal notation [] is preferable

日本語訳 :“配列リテラルの表記が好ましいっすね。”

配列の初期化宣言にリテラルを使った方がよいらしい。

x = new Array ();

x = [];

以上、覚書でした。

リテラルとは、プログラムのソースコードにおいて使用される、数値や文字列を直接に記述した定数のことである。 変数の対義語であり、変更されないことを前提とした値である。 プログラミング言語のコード中にリテラルが挿入される場合には、判別のために特定の書式を用いる必要がある。

www.weblio.jp

最近よく使う、CSSプロパティ 3選(vw/vh,calc(),flex) - #レスポンシブwebデザイン

ここ最近よく使うなーと思うCSSプロパティの紹介。

Viewport units: vw, vh, vmin, vmax

ビューポートの縦・横に対する割合の単位ですが、
めっちゃ使えるなぁーと思う今日この頃です。

記事紹介

coliss.com

dev.classmethod.jp

Can I use 状況

Can I use... Support tables for HTML5, CSS3, etc

Android4.3以下は、フォールバックを用意しておけばガンガン使えんじゃん! って感じでガンガン使ってます。

特にお気に入りは、ビューポートに合わせて文字サイズが変更できるところですね。

coliss.com

※ 一部次に紹介するcalc()との組み合わせの内容が含まれております。

対象ブラウザや要件定義が合えば積極的に使っていきたいですね!

calc() as CSS unit value

calc()関数です。 calc = calculation(計算)の略でその名の通り、四則計算ができます。

レスポンシブwebデザインをやる上で今までは、Sass(SCSS)内で計算させて横幅等を指定していたのですが、 これを使えば、そのまま「計算式」を「値」として指定できます。

もちろん、さらに洗練されたmixinにしても使えますね。

記事紹介

www.sassmeister.com

hyper-text.org

Can I use 状況

Can I use... Support tables for HTML5, CSS3, etc

Android4.3以下は、フォールバックを用意しておけばガンガン使えんじゃん! って感じでガンガン使ってます。

疑似要素で上下に画像を配置し、間の高さだけ背景を指定したい!といった場合に calc(高さ - 疑似要素で配置した大きさ*2 ) のように指定できたのに感動した記憶があります。

Flexible Box Layout Module

言わずもがなな感じがしていますが、便利ですねー。

記事紹介

coliss.com

css3のflexboxを使うとすごい簡単になるレイアウトを試してみた | スターフィールド株式会社

www.webcreatorbox.com

Can I use 状況

Can I use... Support tables for HTML5, CSS3, etc

ほぼ、接頭辞を付ければ問題なく使えます。 今まで、JSで高さ揃えを実装し構築してたものについても、CSSのプロパティ1つで済む可能性があるというのはかなりでかい点ですね。

以上、最近よく使う、CSSプロパティ 3選でした。

【自分メモ】cookieの値を取得する。

特定のcookieの値をだけを取得したい場合。

var getCookieValue = function(key) {
    var val = document.cookie.match(new RegExp('(^|\\s)'+key+'=([^;]+)'));
    return !!val && unescape(val[2]);
};

alert(getCookieValue("COOKIE名"));

参考URL blog.manaten.net

cookies.jsを使用した場合。

参考URL developer.mozilla.org

 /*\
 |*|
 |*|  :: cookies.js ::
 |*|
 |*|  A complete cookies reader/writer framework with full unicode support.
 |*|
 |*|  https://developer.mozilla.org/en-US/docs/DOM/document.cookie
 |*|
 |*|  Syntaxes:
 |*|
 |*|  * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
 |*|  * docCookies.getItem(name)
 |*|  * docCookies.removeItem(name[, path])
 |*|  * docCookies.hasItem(name)
 |*|  * docCookies.keys()
 |*|
 \*/

var docCookies = {
  getItem: function (sKey) {
    if (!sKey || !this.hasItem(sKey)) { return null; }
    return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
  },
  setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return; }
    var sExpires = "";
    if (vEnd) {
      switch (vEnd.constructor) {
        case Number:
          sExpires = vEnd === Infinity ? "; expires=Tue, 19 Jan 2038 03:14:07 GMT" : "; max-age=" + vEnd;
          break;
        case String:
          sExpires = "; expires=" + vEnd;
          break;
        case Date:
          sExpires = "; expires=" + vEnd.toGMTString();
          break;
      }
    }
    document.cookie = escape(sKey) + "=" + escape(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
  },
  removeItem: function (sKey, sPath) {
    if (!sKey || !this.hasItem(sKey)) { return; }
    document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sPath ? "; path=" + sPath : "");
  },
  hasItem: function (sKey) {
    return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
  },
  keys: /* optional method: you can safely remove it! */ function () {
    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
    for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = unescape(aKeys[nIdx]); }
    return aKeys;
  }
}


alert(docCookies.getItem("COOKIE名"));

[jQuery]スクロールバーのデザインと実装方法と注意点 - 超軽量スクリプト Perfect Scrollbar

一昔前だとスクロールバーのデザインモックを見ただけで吐きそうになっていましたが、 今では便利なプラグインとCSS3といった技術を用いて比較的容易に実装できるようになりました。

本記事では、超軽量スクリプト Perfect Scrollbarを用いたデザイン性に富んだスクロールバーの実装方法を紹介したいと思います。

Perfect Scrollbarについて

Perfect Scrollbarについては、3年くらい前にcoliss様のサイトで紹介されていますので そちらをご参照ください。

http://coliss.com/articles/build-websites/operation/javascript/jquery-plugin-perfect-scrollbar.html

ダウンロードはこちら

perfect-scrollbar

実装方法

準備するもの

  • jQuery
  • Perfect Scrollbar
  • HTML/CSS/JS
  • (あればデザインカンプ)

サンプルデモ

さっそくですが、今回自分が作ったサンプルを見ながら解説します。

これは線路を走る電車のつもりです...汗
サンプルデモのデザインについては、ご了承ください。

まずは、スクロールバーを出す部分を実装していきます。 f:id:paradox_tm:20160517154350p:plain

HTML

<div class="box">
 <div id="js-scroll" class="inner">
 <!-- スクロールさせるコンテンツ  -->
 </div>
</div>

.box:スクロールさせる部分を囲っています。
.inner:実際にスクロールさせる場所になります。

※ デザインによってマークアップは調整してください。

CSS

.box {
  height:320px;
  width: 320px;
  box-sizing: border-box;
  padding: 20px 30px 20px 20px;
  border: 1px dotted #333;
  margin: 50px auto;
  background-color: #fff;
}

/*こちらがスクロールさせる箇所 */
.inner {
  position: relative;
  overflow: hidden;
  background-color: #fff;
  width: 280px;
  height: 280px;
}

それぞれのスタイルになります。こちらもデザインによって調整ください。
※ 但しスクロールさせたい箇所に「position: relative;overflow: hidden;」はつけるようにしてください。

JS

$(function() {
    $('#js-scroll').perfectScrollbar();
});

jQueryとperfectScrollbarを読み込ませた上で、指定してください。
GitHubを覗くと様々なオプションがありますが、今回はデフォルトの指定にしておきます。

気になる方は以下を参照してみてください。
https://github.com/noraesae/perfect-scrollbar

これで下準備完了です!

デザインの反映

ここでperfectScrollbar側から提供されているCSSを読み込ませると本家のサンプルデモと同じものができあがりますが、 今回はオリジナルのデザインを反映させたいのでその提供されているCSSをカスタマイズしていきます。

以下、必要な箇所を抜粋したCSSになります。

.ps-container {
  -ms-touch-action: none;
  touch-action: none;
  overflow: hidden !important;
  -ms-overflow-style: none;
}
@supports (-ms-overflow-style: none) {
  .ps-container {
    overflow: auto !important;
  }
}
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
  .ps-container {
    overflow: auto !important;
  }
}

/*スクロールバーのレールの背景指定*/
.ps-container.ps-active-y > .ps-scrollbar-y-rail {
  display: block;
  background: url(body.jpg) center center repeat; /*色でも可能*/
}

/*スクロールバーのレールの位置の指定*/
.ps-container > .ps-scrollbar-y-rail {
  position: absolute;
  right: 6px; /*位置調整*/
  width: 15px; /*デザイン幅の指定*/
}

/*スクロールバーの指定*/
.ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
  position: absolute;
  background: 
  url(head.jpg) top center no-repeat, /*スクロールバーを三分割したうちの上矢印の部分*/
  url(foot.jpg) bottom center no-repeat, /*スクロールバーを三分割したうちの下矢印の部分*/
  url(body.jpg) center center repeat; /*スクロールバーを三分割したうちのお腹の部分(リピートできるもの)*/
  right: -2px; /*位置調整*/
  width: 19px; /*デザイン幅の指定*/
}

ポイントは、以下の通りです。

  • スクロールバーのレールの背景の切り出し(リピートできるもの)
  • スクロールバーのデザイン部分を三分割し、上矢印部分(固定)/下矢印部分(固定)/お腹の部分(リピート) に分けて3枚の背景画像を指定
  • それぞれの位置調整と幅調整

f:id:paradox_tm:20160517154359p:plain

この3点を守れば、素敵なスクロールバーが実装できます。
今回は、縦スクロールで実装しましたが、横スクロールの場合も同じです。

デザインの注意点

デザインを反映する上での注意ですが、スクロールバーは可変になります。スクロール量(コンテンツ量)が増えれば、当然スクロールバーの長さも変わります。

実装できない(厳密には、不自然になる)デザインは、スクロールバーの大きさが固定のものです。 またスクロールバーのお腹のリピート部分が不規則な形になると繋ぎ目が美しくなくなってしまいます...(今回のデモサンプルのように...)

以上です!

デザイン次第でかなり素敵なものができそうですね!

ネイティブアプリでシェアされない!? Twitterでシェアする内容を動的に変える時の注意点。

某案件で[クイズに答えて正解数に応じてTwitterでシェアする内容を変更するもの]を実装しました。
ここでネイティブアプリ(iPhoneとかに入っているTwitterアプリ)でハマったので記録として記しておきます。

jQueryを使用した話になります。

attrメソッドを使用してのシェア内容の変更はネイティブアプリでは動かない。

そのままですが、attrメソッドを使用しhrefの内容を変更すると、Twitterアプリを立ち上げてシェアした際に変更したシェア内容が継承されず、真っ白になります。

ダメなサンプル例

HTML

<a id="tweetBtn" href="">ツイート</a>

JavaScript

if(count === 1){
  $('#tweetBtn').attr('href','http://twitter.com/intent/tweet?original_referer=URL&amp;url=URL&amp;text=%e3%81%bb%e3%81%92%e3%81%bb%e3%81%92');
}
// countはクイズの正解数
// %e3%81%bb%e3%81%92%e3%81%bb%e3%81%92 = ほげほげ(エンコード
// URLの:(全角)を:(半角)に変更してください

PCで検証した場合、Twitterページが立ち上がりうまくシェアできますが、ネイティブアプリがiPhoneなどに入っている場合ツイート内容が消えてしまいます。
Androidは試していないのでわかりません(汗)

解決策

HTML

<div id="tweetBtn"><a href="">ツイート</a></div>

JavaScript

if(count === 1){
  $('#tweetBtn').find('a').remove();
  $('#tweetBtn').append('http://twitter.com/intent/tweet?original_referer=URL&amp;url=URL&amp;text=%e3%81%bb%e3%81%92%e3%81%bb%e3%81%92')
}
// countはクイズの正解数
// %e3%81%bb%e3%81%92%e3%81%bb%e3%81%92 = ほげほげ(エンコード
// URLの:(全角)を:(半角)に変更してください

一度aタグを消して再度、DOMを生成させています。
こうすることでネイティブアプリでも動的に変更したシェア内容を引き継ぎ、ツイートすることができます。

パフォーマンス的にはその都度、要素を消したり追加したりしているのであまりよくない気がしますが...
jQueryを使用する場合、この方法で良いかと思います。

まとめ

  • Twitterでシェアする内容を動的に変える時は必ず実機で確認する!
  • jQueryを使用する場合は、attrメソッドを使用しない!
  • その都度、DOMを生成させる!
  • エンコードは怠るな!

以上です。

一言

試してないですが、ReactやAngularJSだとこんなことしなくてもうまくいけるかもですねー。

最近見つけたiOSのバグ(?) -JQuery アニメーション-

最近、ほとんどjQueryを使用したアニメーションの実装をしなくなってきておりますが、 たまたまiOSで納品物をチェックしている際に見つけてしまった挙動について記したいと思います。

サイドからスライドするメニューの動きが不自然。

メニューボタンを押すと横からスライドするパターンのメニューですが、 メニューボタンを押して開く時はスムーズなのですが、戻るときの挙動が[最初に瞬間移動をして真ん中あたりにいき、そこからアニメーションが始まるような感じ]になっておりました。

以下、jQueryソースコード(抜粋)

ボタンを押してメニューを開く処理

$('#hoge').animate({
  right:'80%'
});

ボタンを押してメニューを閉じる処理

$('#hoge').animate({
  right:'0'
});

一見、どこにでもありそうな処理ですがこの記述がどうやらiOSでは、 不自然な動きを起こしてしまうようです。

解決方法

ボタンを押してメニューを閉じる処理の数値を0と指定するのではなく、 0%と指定してあげることでスムーズに動くようになりました。

実際に以下のページをiPhone等で確認するわかります。

CodePen - iOS - bug??

もし自社サイトなどで似たような動きをしていた場合、試してみる価値はあるかと思います。

検証環境

iOS 9.1/ 9.2.1 / 9.3.1

深まる謎(余談)

ただこれが逆の場合、この現象が起きないという...。 (誰か教えてください。)

$('#hoge').animate({
  left:'80%'
});

$('#hoge').animate({
  left:'0'
});

最後に

この度の熊本地震により被災されたみなさまとそのご家族の方々に心からお見舞い申し上げます。 また一日も早い復旧がなされますことをお祈りいたします。

[jQuery]自作ブックマークレットで効率化!!~リードタイムの短縮~

世の中には先人が作った素晴らしいアドオンやブックマークレットがたくさんあります。私も様々なアドオンやブックマークレットをブラウザに入れ普段の業務に役立てております。

しかし、すべての作業についてそれらのアドオンやブックマークレットで賄えるわけでもなく

「この繰り返しの作業、どうにかならないか...」
「あんな機能ほしい!」
「あの機能とこの機能が一緒であれば...」

ということがあったりします。

ということで制作者であれば自分たちの現場に合った素敵なブックマークレットを作ってしまおう!というのが今回のお話です。 もちろん生のJSで記述することもできますが、今回は親しみやすいjQueryを使ったブックマークレットの作り方(導入部分)を紹介いたします。

jQueryブックマークレットの記述

javascript:(function(){
!function(d,f,s){s=d.createElement("script");s.src="//j.mp/1bPoAXq";s.onload=function(){f(jQuery.noConflict(1))};d.body.appendChild(s)}(document,function($){
/**************************************************
* BOOKMARKLET by jQuery
***************************************************/


//処理はここまで
});})();

こちらのソースでjQueryを使ったブックマークレットが作製可能になります。

ブックマークレットを作製するときの手順

実際に自分がブックマークレットを作製するときの手順が以下になります。

①:エディターにて編集
②:自分が書いたJSコードをブラウザで実行
③:JSコードを圧縮
④:ブックマーク(お気に入り)に追加

②のところで個人的にオススメの確認方法は、Firefoxのアドオンの「Firebug」を使用する方法です。

ブックマークレットを作製する場合、接頭辞に「javascript:」という記述をいれないといけないのですが 通常のブラウザでデバックしようするとエラーになってしまいます。

しかし、Firebugの場合まるまる自分が記述したJSコードをコピペするだけでデバックができます。

試しに以下のソースをコピーし、Firebugで実行してみます。

javascript:(function(){
!function(d,f,s){s=d.createElement("script");s.src="//j.mp/1bPoAXq";s.onload=function(){f(jQuery.noConflict(1))};d.body.appendChild(s)}(document,function($){
/**************************************************
* BOOKMARKLET by jQuery
***************************************************/

var pageTitle = $('h1').text();
alert('このページのh1は「'+pageTitle+'」です');


//処理はここまで
});})();

手順

1.Firefox上でF12を押しFirebugを起動する

2.コンソールタブを選択し、矢印ボタンを押しコンソール画面を表示
f:id:paradox_tm:20160307172654p:plain

3.ソースを貼り付ける f:id:paradox_tm:20160307172705p:plain

実行できると閲覧しているページのh1をアラートで知らせてくれるかと思います。 f:id:paradox_tm:20160307172717p:plain

あとはJSコードを圧縮すれば自作のブックマークレットの完成です!

Firebug
https://addons.mozilla.org/ja/firefox/addon/firebug/

圧縮する時の注意点

圧縮する時の注意点として、「javascript:」という記述が消えないようにすることです。 オンラインで圧縮する場合、以下のサイトが良いかと思います。

JS Minifier (JavaScriptの圧縮)
https://syncer.jp/js-minifier

自作したブックマークレットの機能紹介

かなり現場に依存してたブックマークレットですが、機能だけ紹介致します。
(少しでもヒントになればと思いリストだけ載せておきます。)

  • 日付を入力するとURLにパラメーターを付与するもの
  • ページの生成時に画像のパス(ディレクトリ)が最新のものになっているかチェックするもの
  • DOCTYPE宣言の確認
  • ページタイトルの確認
  • descriptionの確認
  • パンくずの確認
  • UAイベントの検出の確認
  • 外部ドメインの有無の確認
  • PDFの有無の確認
  • YOUTUBE(動画IDなど)の確認
  • 特定のページへリンクの確認
  • OGP情報の確認(og:type、og:site_name、og:url、og:image、og:title、og:description)
  • Test Server Switcher etc

こちらのブックマークレットは現場からの声を元に実装し提供しました。 確認作業が少しでも効率よく済めば、リードタイムの短縮につながりますね!

おまけ

ブックマークレットを少しでもオシャレ(?)に表現するためにモーダル風なものを用意しました。 よろしければお使いください..。 ※ sampleではページのh1を取得しております。

javascript:(function(){
!function(d,f,s){s=d.createElement("script");s.src="//j.mp/1bPoAXq";s.onload=function(){f(jQuery.noConflict(1))};d.body.appendChild(s)}(document,function($){
/**************************************************
* BOOKMARKLET by jQuery
***************************************************/
$("body").append('<div id="js-GlayLayer"></div><style>#js-GlayLayer{background: #000 none repeat scroll 0 0;height: 100%;left: 0;opacity: 0.6;position: fixed;top: 0;width: 100%;z-index: 9999;}</style>');
var $layer = $('#js-GlayLayer');
$("body").append('<div id="js-INFO" class="fadeInUp"></div><style>#js-INFO {border-radius:8px;border:2px solid #333;position:absolute;left:50%;margin-left: -480px;top:50px;padding: 20px;width:920px;background: #fff;z-index:9999;}.titlestyle03{padding:0 15px 10px 0;}@-webkit-keyframes fadeInUp {0% {opacity: 0;transform: translate3d(0, 100%, 0);}100% {opacity: 1;transform: none;}}@keyframes fadeInUp {0% {opacity: 0;transform: translate3d(0, 100%, 0);}100% {opacity: 1;transform: none;}}.fadeInUp {animation-name: fadeInUp;animation-duration: 0.3s;animation-fill-mode: both;}</style>');
var $info = $('#js-INFO');


/*ここから記述*/
$info.append('<h1 style="margin-bottom:30px;font-size:24px">ページタイトル取得</h1><p style="margin-bottom:30px">'+$('h1').text()+'<p>');


/*レイヤー削除*/
$(document).on('click',$layer,function(){
  $info.remove();
  $layer.remove();
});
//処理はここまで
});})();