狠狠撸

狠狠撸Share a Scribd company logo
みんな(多分)大好き
                 闯补惫补厂肠谤颈辫迟を
                ちょっとまじめに
                 考えてみたり
               そんな使い方ないワー
                なことを話します
12年10月27日土曜日                   1
おおくぼ ひろあき

  Interactive Designer
  Multimediaといっしょに20年




12年10月27日土曜日             2
闯补惫补厂肠谤颈辫迟を使って
                  Webサイトを
                作っていますか?



12年10月27日土曜日                    3
その闯补惫补厂肠谤颈辫迟が
         UXをだいなしにしてる....
             かもですよ


                    奥さん

12年10月27日土曜日               4
inazumatv.comの場合




12年10月27日土曜日        5
inazumatv.comの場合
 <head>
 <script type='text/javascript' src=/slideshow/javascript-14882630/14882630/&
 <script type='text/javascript' src='http://cdn.wpbooster.net/e3fd63a20401eb34dc2cb64dd7cfdb0f/wp-content/themes/yoko/js/
 smoothscroll.js?ver=1.0'></script>
 <script type='text/javascript' src='http://cdn.wpbooster.net/e3fd63a20401eb34dc2cb64dd7cfdb0f/wp-content/plugins/swfobj/
 swfobject.js?ver=2.2'></script>
 <script type="text/javascript" src="http://www.inazumatv.com/contents/wp-content/plugins/cforms/js/cforms.js"></script>




            たくさん!
          でも少ない方かも...


12年10月27日土曜日                                                                                                                  6
JavaScriptリンクは他ファイルのロードをブロックする




12年10月27日土曜日                      7
1.JavaScriptリンクは他ファイルのロードをブロックする

 【対策】
 </body>タグ直前に<script>タグを書く。

 document.createElement を使用して<script>タ
 グをHTML <head> へ挿入する。


 JavaScriptライブラリがあります。
 LasyLoad
 https://github.com/rgrove/lazyload
 LABjs
 LABjs : Loading And Blocking JavaScript
 https://github.com/getify/LABjs


 ...etc


12年10月27日土曜日                               8
HTML, CSS, 画像の最適化に
     心配りしたWeb制作を
         しているなら
       JavaScriptもね


12年10月27日土曜日            9
闯补惫补厂肠谤颈辫迟を
       無効にしてもWebサイトは
            問題無く
        見たり使用できますか?


12年10月27日土曜日            10
まさか闯补惫补厂肠谤颈辫迟を
      デザインに使ったりなんて


               よい子のみんなは
                 しないよね

12年10月27日土曜日              11
DOMの高さをそろえたり


 1行おきに背景に色をつけたり


 アコーディオン形式のリストの
 デフォルトが非表示だったり
 それから、あれや、これや、こんなことや、あんなことや、...etc




12年10月27日土曜日                         12
<a href="javascript:void%200"
 onclick="location.href='example.html';
 return false;">



 ダメ!
 絶対!!
 JavaScriptが有効でないと遷移で
 きません
12年10月27日土曜日                              13
var bool = true;
 $('#accordionBar a').on('click',
 function (e) {
 ! e.preventDefault();
 ! e.stopPropagation();

 ! if (bool) {
 ! ! $(this).parent().
 ! !    append('<div id="insert">追加</div>');
 ! } else {
 ! ! $('#insert').remove();
 ! }
 ! bool = !bool;
 });

12年10月27日土曜日                                   14
var bool = true;
 $('#accordionBar a').on('click',
 function (e) {
 ! e.preventDefault();
 ! e.stopPropagation();
                        DOMの再構築は
 ! if (bool) {          コストが高い
 ! ! $(this).parent().
 ! !    append('<div id="insert">追加</div>');
 ! } else {
 ! ! $('#insert').remove();
 ! }
 ! bool = !bool;
 });

12年10月27日土曜日                                   15
JavaScript

    ブラウザで実行される
    ブラウザ環境に依存する
    インタプリタ
    prototypeベースのオブジェクト指向言語


 ブラウザ互換問題が発生しやすい。
 ?処理スピード
 ?処理落ち

 それから、あれや、これや、こんなことや、あんなことや、...etc

12年10月27日土曜日                         16
JavaScriptの便利なライブラリ

 ライブラリは便利です。
 便利なものは使っちゃいましょ。




12年10月27日土曜日           17
JavaScriptの便利なライブラリ

 ライブラリは便利です。
 便利なものは使っちゃいましょ。

 【例】
 IE 6で32bit PNGを使う時どうしてます?
 DD_belatedPNG.js があれば解決!




12年10月27日土曜日                 18
JavaScriptの便利なライブラリ

 ライブラリは便利です。
 便利なものは使っちゃいましょ。

 【例】
 IE 6で32bit PNGを使う時どうしてます?
 DD_belatedPNG.js があれば解決!

 でも

 使い方を間違えると...
12年10月27日土曜日                 19
JavaScriptの便利なライブラリ DD_belatedPNG

 【例】
 DD_belatedPNG.fix('img’);


 この例だとHTML中の<img>タグ全てにCSS Rule
 が設定されます。

 使用されている画像が全て32bit PNGで無い限り使
 うべきではありません。



12年10月27日土曜日                         20
JavaScriptの便利なライブラリ DD_belatedPNG

 【例】
 DD_belatedPNG.fix('img’);


 DD_belatedPNGは自動的にmouseleave,
 mouseenterなどのマウス?アクションに対して
 attachEventを付加します。

 全ての画像にmouseleave, mouseenterアクション
 が必要なケースで無い限り使用するべきではありま
 せん。
12年10月27日土曜日                         21
JavaScriptの便利なライブラリ DD_belatedPNG

 【対策】
 DD_belatedPNG.fix('.png32’);


 CSS classなどで必要項目を特定して指定しましょう。

 あるいは、
 32bit PNGを使用しない。

 IE 6をサポート対象外にする。


12年10月27日土曜日                         22
箩蚕耻别谤测は
                スキですか?
               そしてプラグインも


12年10月27日土曜日               23
JavaScriptの便利なライブラリ jQuery

 【例】
 <script type="text/javascript">
 $(document).ready(function () {});
 </script>




 global領域にScriptを記述している。

 jQueryを互換モードで使用していない。



12年10月27日土曜日                          24
闯补惫补厂肠谤颈辫迟をglobal領域に記述しない
 <script type="text/javascript">
 $(document).ready(function () {});

 var exampleVar = ‘変数’;
 function exampleFunction () {
 ! alert(exampleVar);
 }
 </script>

 Scriptタグ内はglobal領域になります。
 外部ファイル(.js)化している場合も同様です。
 exampleVarはglobal変数、
 exampleFunctionはglobal関数になります。
12年10月27日土曜日                          25
闯补惫补厂肠谤颈辫迟をglobal領域に記述しない

 global領域にScriptを記述すると思いもかけない上
 書きなどのトラブルに簡単に巻き込まれます。

 名前空間(Name Space)の汚染問題として良く知ら
 れています。

 global変数、関数へのアクセスはlocalに比較すると
 遅いことも知られています。



12年10月27日土曜日                     26
闯补惫补厂肠谤颈辫迟をglobal領域に記述しない

 【対策】
 即時関数内にScriptを記述します。
 ;(function () {
 ! // ココにScript
 }());

 即時関数は記述したその場で直ぐに実行される関数
 です。
 名前(関数名)はありません。
 名前空間を汚染しません。

12年10月27日土曜日                 27
闯补惫补厂肠谤颈辫迟をglobal領域に記述しない

 【対策】
 即時関数内にScriptを記述します。
 ;(function () {
 ! var exampleVar = ‘変数’;
 ! function exampleFunction () {
 ! ! alert(exampleVar);
 ! }
 }());

 exampleVar, exampleFunctionどちらもlocalにな
 ります。

12年10月27日土曜日                              28
JavaScriptの便利なライブラリ jQuery

 $(document).ready(function () {});


 ;(function (window, $) {
 ! var document = window.document
 ! ;
 ! $(document).ready(function () {});
 }(this, jQuery));

 JavaScriptで使用するwindow, documentなどは
 global変数(オブジェクト)です。
 local化することでアクセス?スピードが向上します。

12年10月27日土曜日                            29
JavaScriptの便利なライブラリ jQuery

 ;(function (window, $) {
 ! var document = window.document
 ! ;
 ! $(document).ready(function () {});
 }(this, jQuery));

 jQueryを互換モードで使用しています。
 しかもjQueryのglobal “$” の名前をそのままにlocal
 化し使用しています。

 global領域にScriptを記述している。
 jQueryを互換モードで使用していない。

12年10月27日土曜日                            30
JavaScriptの便利なライブラリ jQuery




 箩蚕耻别谤测は互換モードで使用する。

 互換モードで使用しないと他のライブラリを使用し
 た時にコンフリクトを起こすかもかも            かも




 コンフリクトの多くは使用者側の不注意から発生し
 ます。



12年10月27日土曜日                       31
JavaScript

    ブラウザで実行される
    ブラウザ環境に依存する
    インタプリタ
    prototypeベースのオブジェクト指向言語
               そんなに処理スピードは速くない
 ブラウザ互換問題が発生しやすい。
 ?処理スピード
 ?処理落ち                   遅くなる要因は少なくしましょう

 それから、あれや、これや、こんなことや、あんなことや、...etc

12年10月27日土曜日                               32
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのEvent処理(Click)

 $('#someLink').click(function (e) {});

 $('#someLink').bind('click', function (e) {});

 $('#someLink').on('click', function (e) {});


 どれも正しく動作しますが、
 $('#someLink').on('click', function (e) {});

 を使用すべきです。
 jQuery 1.7から使用可能です。
12年10月27日土曜日                                    33
JavaScriptの便利なライブラリ jQuery



     最新版のjQueryを使用する
 特別な理由が無い限り(どんな理由があるのか思い
 つきませんが)最新版のjQueryを使うべきです。

 jQueryといえどもバグや処理遅延はあるかもです。
 bug ?xされたり最適化された最新版を使うべきで
 す。

12年10月27日土曜日                  34
JavaScriptの便利なライブラリ

長くメンテナンスされていない
 ライブラリ、プラグインを
    使用しない
 長くメンテナンス(更新)されていないライブラリ
 やプラグインを使用するべきではありません。

 日進月歩のInternet界で1年は長すぎると感じます。


12年10月27日土曜日                    35
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのEvent処理(Click)

 $('#someLink').on('click', function (e) {
 ! e.preventDefault();
 ! e.stopPropagation();
 });

 Eventのバブリング(伝播)を止めたり、キャンセル
 処理をちゃんと行っていますか?




12年10月27日土曜日                                 36
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのEvent処理(Click)

 $('#someLink').on('click', function (e) {
 ! e.preventDefault();
 ! e.stopPropagation();
 });

 Clickイベントを発生箇所以外でその後に使用する
 ことはあまりないと考えられます。

 ブラウザに不要な処理をさせない様に配慮するこ
 とが必要です。

12年10月27日土曜日                                 37
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのEvent処理(Click)
 var bool = false;
 $('#someLink').on('click', function (e) {
 ! e.preventDefault();
 ! e.stopPropagation();
 ! if (bool) {
 ! ! $(this).addClass('exampleClass');
 ! } else {
 ! ! $(this).removeClass('exampleClass');
 ! }
 ! bool = !bool;
 });

 毎回DOMを取得していませんか?

12年10月27日土曜日                                 38
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのEvent処理(Click)
 var bool = false,
 ! $someLink = $('#someLink');
 $someLink.on('click', function (e) {
 ! e.preventDefault();
 ! e.stopPropagation();

 ! if (bool) {
 ! ! $someLink.addClass('exampleClass');
 ! } else {
 ! ! $someLink.removeClass('exampleClass');
 ! }
 ! bool = !bool;
 });
 1回だけ取得し使い回す方が効率的です。
12年10月27日土曜日                                  39
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのloop処理(each)
 $('a').each(function (index, element) {});


 each()使ってますか?

 ループ処理の時に便利ですよね。
 しかしこのeach関数、処理が遅いことで知られて
 います。
 jQueryの問題では無く、JavaScriptの関数呼出の
 オーバーヘッドが原因です。
12年10月27日土曜日                                  40
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのloop処理(each)
 for (var i=0, limit=$a.length; i < limit; i++)
 {
 ! //$a[i];
 }


 まだ、こちらの方がましかと思います。

 ループ内で関数呼出したら同じことですけど...




12年10月27日土曜日                                  41
JavaScriptの便利なライブラリ jQuery
 ■jQueryのDOM Selector

 jQueryのDOM Selectorは大変優秀です。

 ネイティブ機能だけでは不可能なことも軽々とや
 ってのけてしまいます。

 これ無しには生きていけないかもしれません。
 不可能なことは無いのではと思えてしまいます。



12年10月27日土曜日                   42
JavaScriptの便利なライブラリ jQuery
 ■jQueryのDOM Selector




               でも
12年10月27日土曜日                  43
JavaScriptの便利なライブラリ jQuery
 ■jQueryのDOM Selector


               jQueryのDOM Select
                       の
                     仕組みを
                  見てみましょう

12年10月27日土曜日                       44
JavaScriptの便利なライブラリ jQuery
 ■jQueryのDOM Selector
 document.getElementById();
 document.getElementsByName();
 document.getElementsByTagName();
 document.getElementsByClassName();

 document.querySelector();
 document.querySelectorAll();

 JavaScriptには上記のようなselector関数が用意さ
 れています。
 jQueryと言えどもこれらの関数を使用します。

12年10月27日土曜日                          45
JavaScriptの便利なライブラリ jQuery
 ■jQueryのDOM Selector
 $('#main .className');
 jQueryで上記のような指定の場合JavaScriptだと...
 document.querySelectorAll('#main .className');

 しかしquerySelectorAllはモダンなブラウザにし
 か用意されていません。
                          コメントご指摘通り間違えているので削除します。
                          IEではgetElementsByClassNameの方が実装がquerySelectorAllより早く行わ
                          れています。

                          SafariはgetElementsByClassNameの方が早かったように思っていたのです
                          が確証がありません。


 使えない時は...
 document.
 ?getElementById('main').
 ?getElementsByClassName('className');

12年10月27日土曜日                                                                       46
JavaScriptの便利なライブラリ jQuery
 ■jQueryのDOM Selector

 jQueryにはsizzleというDOM Selectのためのライ
 ブラリが内蔵されており、レガシーブラウザの時で
 も、もっと効率的に選択が行われます。

 結果は全て複数になります。
 配列の様な形式です。

 単独のDOMを選択するより処理コストがかかりま
 す。
12年10月27日土曜日                         47
JavaScriptの便利なライブラリ jQuery
 ■jQueryのDOM Selector
 $('#main');

 DOMの選択はdocument.getElementByIdが最速
 です。
 可能な限りidで指定し取得すべきです。

 HTML内に1つしか存在しないのにtag名やclass名
 で選択していないか確認してみることをお勧めし
 ます。

12年10月27日土曜日                         48
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのEvent処理(Click)
 <ul id="tCon">
 !   <li><a href="img/s/earth.jpg"><img src=/slideshow/javascript-14882630/14882630/"img/t/earth.jpg" alt=""></a></li>
 !   <li><a href="img/s/jupiter.jpg"><img src="img/t/jupiter.jpg" alt=""></a></li>
 !   <li><a href="img/s/mars.jpg"><img src="img/t/mars.jpg" alt=""></a></li>
 !   <li><a href="img/s/mercury.jpg"><img src="img/t/mercury.jpg" alt=""></a></li>
 !   <li><a href="img/s/moon.jpg"><img src="img/t/moon.jpg" alt=""></a></li>
 !   <li><a href="img/s/neptune.jpg"><img src="img/t/neptune.jpg" alt=""></a></li>
 !   <li><a href="img/s/saturn.jpg"><img src="img/t/saturn.jpg" alt=""></a></li>
 !   <li><a href="img/s/solarsystem.jpg"><img src="img/t/solarsystem.jpg" alt=""></a></li>
 !   <li><a href="img/s/sun.jpg"><img src="img/t/sun.jpg" alt=""></a></li>
 !   <li><a href="img/s/uranus.jpg"><img src="img/t/uranus.jpg" alt=""></a></li>
 !   <li><a href="img/s/venus.jpg"><img src="img/t/venus.jpg" alt=""></a></li>
 </ul>



 【設問】
 上記のようなHTML内のaタグにclickイベントを設
 定するコードを記述せよ。


12年10月27日土曜日                                                                                 49
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのEvent処理(Click)
 <ul id="tCon">
 !   <li><a href="img/s/earth.jpg"><img src=/slideshow/javascript-14882630/14882630/"img/t/earth.jpg" alt=""></a></li>
 !   <li><a href="img/s/jupiter.jpg"><img src="img/t/jupiter.jpg" alt=""></a></li>
 !   <li><a href="img/s/mars.jpg"><img src="img/t/mars.jpg" alt=""></a></li>
 !   <li><a href="img/s/mercury.jpg"><img src="img/t/mercury.jpg" alt=""></a></li>
 !   <li><a href="img/s/moon.jpg"><img src="img/t/moon.jpg" alt=""></a></li>
 !   <li><a href="img/s/neptune.jpg"><img src="img/t/neptune.jpg" alt=""></a></li>
 !   <li><a href="img/s/saturn.jpg"><img src="img/t/saturn.jpg" alt=""></a></li>
 !   <li><a href="img/s/solarsystem.jpg"><img src="img/t/solarsystem.jpg" alt=""></a></li>
 !   <li><a href="img/s/sun.jpg"><img src="img/t/sun.jpg" alt=""></a></li>
 !   <li><a href="img/s/uranus.jpg"><img src="img/t/uranus.jpg" alt=""></a></li>
 !   <li><a href="img/s/venus.jpg"><img src="img/t/venus.jpg" alt=""></a></li>
 </ul>



 $('#tCon a').on('click', function (e) {
 ! e.preventDefault();
 ! e.stopPropagation();
 });
 動きますが、もう少し効率的な処理があります。

12年10月27日土曜日                                                                                 50
JavaScriptの便利なライブラリ jQuery
 ■jQueryでのEvent処理(Click)
 $('#tCon').on('click', function (e) {
 ! e.stopPropagation();
 ! e.preventDefault();
 ! var target = e.target,
 ! ! nodeName = target.nodeName.toLowerCase()
 ! ;
 ! if (nodeName !== 'img' && nodeName !== 'a') {
 ! ! return false;
 ! }
 });
 Event伝播の仕組みを利用し上位のコンテナで
 Clickアクションを取得し利用しています。
 *nodeNameを調べる必要があります。
12年10月27日土曜日                                       51
箩蚕耻别谤测は最速?


12年10月27日土曜日                52
箩蚕耻别谤测は最速?


 jQueryに限った話ではありません。
 他のライブラリ(Framework)も同じです。

 そもそも、
 このようなライブラリたちが登場したのはクロス
 ブラウザ対策が困難を極めたからです。

 多くのライブラリはレガシーブラウザを含め正常
 に機能するように設計されています。

12年10月27日土曜日                53
箩蚕耻别谤测は最速?
 var $tCon = document.getElementById('tCon');
 !
 function onClick (e) {
 !   var target, nodeName, a;
 !   if (typeof e === 'undefined') {
 !   !   e = window.event;
 !   !   target = e.srcElement;
 !   } else {
 !   !   e.preventDefault();
 !   !   e.stopPropagation();
 !   !   target = e.target;
 !   };
 !   nodeName = target.nodeName.toLowerCase();
 !   if (nodeName === 'img') {
 !   !   a = target.parentNode;
 !   } else if (nodeName === 'a') {
 !   !   a = target;
 !   } else {
 !   !   return false;
 !   };
 !   // ココにScript
 !   return false;
 };
 if (typeof $tCon.addEventListener !== 'undefined') {
 !   $tCon.addEventListener('click', onClick, true);
 } else {
 !   $tCon.attachEvent('onclick', onClick);
 };

 先ほどのClick問題をライブラリを使わずに書き直しました。

12年10月27日土曜日                                            54
箩蚕耻别谤测は最速?
 Eventをリスナーする
 EventはaddEventListenerかIEのattachEventを使いイベント?ハンドラを設定します。

 Eventハンドラ
 addEventListener
 addEventListenerを使ったときはハンドラ引数へEventインスタンスが送られてきます。
 EventインスタンスのtargetプロパティのnodeNameを調べるとEvent発生場所が分かりま
 す。
 Eventの伝播を止めるためにpreventDefault, stopPropagationします。

 attachEvent
 attachEventを使った時は引数へEventインスタンスが送られてきません。
 そのかわりwindow.eventが使えます。
 window.eventにはtargetプロパティがありません、そのかわりsrcElementプロパティが使
 えます。
 srcElementのnodeNameを調べるとEvent発生場所が分かります。
 preventDefault, stopPropagationが使えないのでEventの伝播を止めるためにreturn false
 で代用します。

12年10月27日土曜日                                                         55
箩蚕耻别谤测は最速?




               ふ~
12年10月27日土曜日        56
箩蚕耻别谤测は最速?




            なかなか大変ですが
          $(document).ready()
                 は
             もっと大変です


12年10月27日土曜日                    57
箩蚕耻别谤测は最速?
 ;(function (window, functions) {
     var document = window.document,
     functions = functions && functions.splice ? functions : [],
     ie = document.addEventListener ? false : true,
                                                                                     見えないですよね、
     complete = false,
     dispose = function () {


                                                                                     解説はblogへ
         if (complete) {
             return;
         };
         complete = true;
         if (!ie) {
             document.removeEventListener('DOMContentLoaded', onDOMContentLoaded);
             document.removeEventListener('readystatechange', onReadyStateChange);
             window.removeEventListener('load', onWindowLoad);
         } else {
             document.detachEvent('onreadystatechange', onReadyStateChange);
             window.detachEvent('onload', onWindowLoad);
         };
         for (var i = 0, limit = functions.length; i < limit; i++) {
             setTimeout(functions[i], 25 * i);
         };
     },
     onDOMContentLoaded = function (e) {
         dispose();
     },
     onReadyStateChange = function (e) {
         if (document.readyState == 'complete') {
             dispose();
         };
     },
     onWindowLoad = function (e) {
         dispose();
     }
     ;// end of variables
 ?
     if (!ie) {
         document.addEventListener('DOMContentLoaded', onDOMContentLoaded, false);
         document.addEventListener('readystatechange', onReadyStateChange, false);
         window.addEventListener('load', onWindowLoad, false);
     } else if (document.attachEvent) {
         document.attachEvent('onreadystatechange', onReadyStateChange);
         window.attachEvent('onload', onWindowLoad);
     };
 }(window,
     [
         function () {console.log('function 1')},
         function () {console.log('function 2')},
         function () {console.log('function 3')}
     ]
 ));


 http://www.inazumatv.com/contents/archives/7245
12年10月27日土曜日                                                                                     58
箩蚕耻别谤测は最速?




               ふ~
12年10月27日土曜日        59
箩蚕耻别谤测は最速?


 ライブラリ内はもっと効率良くScriptが書かれてい
 ます。

 クロスブラウザ対策に多くのコードが使われてい
 るのが分かって頂けたと思います。

 IEでは使えないpreventDefault, stopPropagation
 も使えるようになっていたり...



12年10月27日土曜日                               60
箩蚕耻别谤测は最速?




                  もしも
                モダンブラウザ
                  だけが
               ターゲットだったら


12年10月27日土曜日               61
箩蚕耻别谤测は最速?




           いらない機能ですよね~


 ほら、スマホとか...


12年10月27日土曜日             62
箩蚕耻别谤测は最速?




   jQuery 2.0 は IE 8以下をサポートしない

 jQuery 2.0 (early 2013, not long after 1.9): This
 version will support the same APIs as jQuery
 1.9 does, but removes support for IE 6/7/8
 oddities such as borked event model, IE7
 “attroperties”, HTML5 shims, etc.


 http://blog.jquery.com/2012/06/28/jquery-core-version-1-9-and-beyond/




12年10月27日土曜日                                                             63
闯补惫补厂肠谤颈辫迟を使って
                  Webサイトを
                作っていますか?



12年10月27日土曜日                    64
その闯补惫补厂肠谤颈辫迟が
         UXをだいなしにしてる....
             かもですよ


                    奥さん

12年10月27日土曜日               65
HTML, CSS, 画像の最適化に
     心配りしたWeb制作を
         しているなら
       JavaScriptもね


12年10月27日土曜日            66
闯补惫补厂肠谤颈辫迟を
       無効にしてもWebサイトは
            問題無く
        見たり使用できますか?


12年10月27日土曜日            67
JavaScriptは上手に使うとHTML, CSSだけでは実現
 できないUIを提供できます。

 HTML5のAPIには魅力的なものが沢山あります。
 Canvas, WebGL, Geo-Location, WebWorkers...

 弱点を良く知りステキなコンテンツを届けるために
 使ってあげて下さい。


12年10月27日土曜日                                  68
@taikiken

  http://www.inazumatv.com/contents/archives/7037




  まだまだ発展途上です。
  間違いなどありましたらご指摘下さい。




12年10月27日土曜日                                        69
修正 2012-10-26
  インタプリンタ -> インタプリタ
  p.16, p.32

  Page削除 p.46
  スライド上には残っています




12年10月27日土曜日          70

More Related Content

闯补惫补厂肠谤颈辫迟をまじめに考えました+

  • 1. みんな(多分)大好き 闯补惫补厂肠谤颈辫迟を ちょっとまじめに 考えてみたり そんな使い方ないワー なことを話します 12年10月27日土曜日 1
  • 2. おおくぼ ひろあき Interactive Designer Multimediaといっしょに20年 12年10月27日土曜日 2
  • 3. 闯补惫补厂肠谤颈辫迟を使って Webサイトを 作っていますか? 12年10月27日土曜日 3
  • 4. その闯补惫补厂肠谤颈辫迟が UXをだいなしにしてる.... かもですよ 奥さん 12年10月27日土曜日 4
  • 6. inazumatv.comの場合 <head> <script type='text/javascript' src=/slideshow/javascript-14882630/14882630/& <script type='text/javascript' src='http://cdn.wpbooster.net/e3fd63a20401eb34dc2cb64dd7cfdb0f/wp-content/themes/yoko/js/ smoothscroll.js?ver=1.0'></script> <script type='text/javascript' src='http://cdn.wpbooster.net/e3fd63a20401eb34dc2cb64dd7cfdb0f/wp-content/plugins/swfobj/ swfobject.js?ver=2.2'></script> <script type="text/javascript" src="http://www.inazumatv.com/contents/wp-content/plugins/cforms/js/cforms.js"></script> たくさん! でも少ない方かも... 12年10月27日土曜日 6
  • 8. 1.JavaScriptリンクは他ファイルのロードをブロックする 【対策】 </body>タグ直前に<script>タグを書く。 document.createElement を使用して<script>タ グをHTML <head> へ挿入する。 JavaScriptライブラリがあります。 LasyLoad https://github.com/rgrove/lazyload LABjs LABjs : Loading And Blocking JavaScript https://github.com/getify/LABjs ...etc 12年10月27日土曜日 8
  • 9. HTML, CSS, 画像の最適化に 心配りしたWeb制作を しているなら JavaScriptもね 12年10月27日土曜日 9
  • 10. 闯补惫补厂肠谤颈辫迟を 無効にしてもWebサイトは 問題無く 見たり使用できますか? 12年10月27日土曜日 10
  • 11. まさか闯补惫补厂肠谤颈辫迟を デザインに使ったりなんて よい子のみんなは しないよね 12年10月27日土曜日 11
  • 12. DOMの高さをそろえたり 1行おきに背景に色をつけたり アコーディオン形式のリストの デフォルトが非表示だったり それから、あれや、これや、こんなことや、あんなことや、...etc 12年10月27日土曜日 12
  • 13. <a href="javascript:void%200" onclick="location.href='example.html'; return false;"> ダメ! 絶対!! JavaScriptが有効でないと遷移で きません 12年10月27日土曜日 13
  • 14. var bool = true; $('#accordionBar a').on('click', function (e) { ! e.preventDefault(); ! e.stopPropagation(); ! if (bool) { ! ! $(this).parent(). ! ! append('<div id="insert">追加</div>'); ! } else { ! ! $('#insert').remove(); ! } ! bool = !bool; }); 12年10月27日土曜日 14
  • 15. var bool = true; $('#accordionBar a').on('click', function (e) { ! e.preventDefault(); ! e.stopPropagation(); DOMの再構築は ! if (bool) { コストが高い ! ! $(this).parent(). ! ! append('<div id="insert">追加</div>'); ! } else { ! ! $('#insert').remove(); ! } ! bool = !bool; }); 12年10月27日土曜日 15
  • 16. JavaScript ブラウザで実行される ブラウザ環境に依存する インタプリタ prototypeベースのオブジェクト指向言語 ブラウザ互換問題が発生しやすい。 ?処理スピード ?処理落ち それから、あれや、これや、こんなことや、あんなことや、...etc 12年10月27日土曜日 16
  • 18. JavaScriptの便利なライブラリ ライブラリは便利です。 便利なものは使っちゃいましょ。 【例】 IE 6で32bit PNGを使う時どうしてます? DD_belatedPNG.js があれば解決! 12年10月27日土曜日 18
  • 19. JavaScriptの便利なライブラリ ライブラリは便利です。 便利なものは使っちゃいましょ。 【例】 IE 6で32bit PNGを使う時どうしてます? DD_belatedPNG.js があれば解決! でも 使い方を間違えると... 12年10月27日土曜日 19
  • 20. JavaScriptの便利なライブラリ DD_belatedPNG 【例】 DD_belatedPNG.fix('img’); この例だとHTML中の<img>タグ全てにCSS Rule が設定されます。 使用されている画像が全て32bit PNGで無い限り使 うべきではありません。 12年10月27日土曜日 20
  • 21. JavaScriptの便利なライブラリ DD_belatedPNG 【例】 DD_belatedPNG.fix('img’); DD_belatedPNGは自動的にmouseleave, mouseenterなどのマウス?アクションに対して attachEventを付加します。 全ての画像にmouseleave, mouseenterアクション が必要なケースで無い限り使用するべきではありま せん。 12年10月27日土曜日 21
  • 22. JavaScriptの便利なライブラリ DD_belatedPNG 【対策】 DD_belatedPNG.fix('.png32’); CSS classなどで必要項目を特定して指定しましょう。 あるいは、 32bit PNGを使用しない。 IE 6をサポート対象外にする。 12年10月27日土曜日 22
  • 23. 箩蚕耻别谤测は スキですか? そしてプラグインも 12年10月27日土曜日 23
  • 24. JavaScriptの便利なライブラリ jQuery 【例】 <script type="text/javascript"> $(document).ready(function () {}); </script> global領域にScriptを記述している。 jQueryを互換モードで使用していない。 12年10月27日土曜日 24
  • 25. 闯补惫补厂肠谤颈辫迟をglobal領域に記述しない <script type="text/javascript"> $(document).ready(function () {}); var exampleVar = ‘変数’; function exampleFunction () { ! alert(exampleVar); } </script> Scriptタグ内はglobal領域になります。 外部ファイル(.js)化している場合も同様です。 exampleVarはglobal変数、 exampleFunctionはglobal関数になります。 12年10月27日土曜日 25
  • 26. 闯补惫补厂肠谤颈辫迟をglobal領域に記述しない global領域にScriptを記述すると思いもかけない上 書きなどのトラブルに簡単に巻き込まれます。 名前空間(Name Space)の汚染問題として良く知ら れています。 global変数、関数へのアクセスはlocalに比較すると 遅いことも知られています。 12年10月27日土曜日 26
  • 27. 闯补惫补厂肠谤颈辫迟をglobal領域に記述しない 【対策】 即時関数内にScriptを記述します。 ;(function () { ! // ココにScript }()); 即時関数は記述したその場で直ぐに実行される関数 です。 名前(関数名)はありません。 名前空間を汚染しません。 12年10月27日土曜日 27
  • 28. 闯补惫补厂肠谤颈辫迟をglobal領域に記述しない 【対策】 即時関数内にScriptを記述します。 ;(function () { ! var exampleVar = ‘変数’; ! function exampleFunction () { ! ! alert(exampleVar); ! } }()); exampleVar, exampleFunctionどちらもlocalにな ります。 12年10月27日土曜日 28
  • 29. JavaScriptの便利なライブラリ jQuery $(document).ready(function () {}); ;(function (window, $) { ! var document = window.document ! ; ! $(document).ready(function () {}); }(this, jQuery)); JavaScriptで使用するwindow, documentなどは global変数(オブジェクト)です。 local化することでアクセス?スピードが向上します。 12年10月27日土曜日 29
  • 30. JavaScriptの便利なライブラリ jQuery ;(function (window, $) { ! var document = window.document ! ; ! $(document).ready(function () {}); }(this, jQuery)); jQueryを互換モードで使用しています。 しかもjQueryのglobal “$” の名前をそのままにlocal 化し使用しています。 global領域にScriptを記述している。 jQueryを互換モードで使用していない。 12年10月27日土曜日 30
  • 31. JavaScriptの便利なライブラリ jQuery 箩蚕耻别谤测は互換モードで使用する。 互換モードで使用しないと他のライブラリを使用し た時にコンフリクトを起こすかもかも かも コンフリクトの多くは使用者側の不注意から発生し ます。 12年10月27日土曜日 31
  • 32. JavaScript ブラウザで実行される ブラウザ環境に依存する インタプリタ prototypeベースのオブジェクト指向言語 そんなに処理スピードは速くない ブラウザ互換問題が発生しやすい。 ?処理スピード ?処理落ち 遅くなる要因は少なくしましょう それから、あれや、これや、こんなことや、あんなことや、...etc 12年10月27日土曜日 32
  • 33. JavaScriptの便利なライブラリ jQuery ■jQueryでのEvent処理(Click) $('#someLink').click(function (e) {}); $('#someLink').bind('click', function (e) {}); $('#someLink').on('click', function (e) {}); どれも正しく動作しますが、 $('#someLink').on('click', function (e) {}); を使用すべきです。 jQuery 1.7から使用可能です。 12年10月27日土曜日 33
  • 34. JavaScriptの便利なライブラリ jQuery 最新版のjQueryを使用する 特別な理由が無い限り(どんな理由があるのか思い つきませんが)最新版のjQueryを使うべきです。 jQueryといえどもバグや処理遅延はあるかもです。 bug ?xされたり最適化された最新版を使うべきで す。 12年10月27日土曜日 34
  • 35. JavaScriptの便利なライブラリ 長くメンテナンスされていない ライブラリ、プラグインを 使用しない 長くメンテナンス(更新)されていないライブラリ やプラグインを使用するべきではありません。 日進月歩のInternet界で1年は長すぎると感じます。 12年10月27日土曜日 35
  • 36. JavaScriptの便利なライブラリ jQuery ■jQueryでのEvent処理(Click) $('#someLink').on('click', function (e) { ! e.preventDefault(); ! e.stopPropagation(); }); Eventのバブリング(伝播)を止めたり、キャンセル 処理をちゃんと行っていますか? 12年10月27日土曜日 36
  • 37. JavaScriptの便利なライブラリ jQuery ■jQueryでのEvent処理(Click) $('#someLink').on('click', function (e) { ! e.preventDefault(); ! e.stopPropagation(); }); Clickイベントを発生箇所以外でその後に使用する ことはあまりないと考えられます。 ブラウザに不要な処理をさせない様に配慮するこ とが必要です。 12年10月27日土曜日 37
  • 38. JavaScriptの便利なライブラリ jQuery ■jQueryでのEvent処理(Click) var bool = false; $('#someLink').on('click', function (e) { ! e.preventDefault(); ! e.stopPropagation(); ! if (bool) { ! ! $(this).addClass('exampleClass'); ! } else { ! ! $(this).removeClass('exampleClass'); ! } ! bool = !bool; }); 毎回DOMを取得していませんか? 12年10月27日土曜日 38
  • 39. JavaScriptの便利なライブラリ jQuery ■jQueryでのEvent処理(Click) var bool = false, ! $someLink = $('#someLink'); $someLink.on('click', function (e) { ! e.preventDefault(); ! e.stopPropagation(); ! if (bool) { ! ! $someLink.addClass('exampleClass'); ! } else { ! ! $someLink.removeClass('exampleClass'); ! } ! bool = !bool; }); 1回だけ取得し使い回す方が効率的です。 12年10月27日土曜日 39
  • 40. JavaScriptの便利なライブラリ jQuery ■jQueryでのloop処理(each) $('a').each(function (index, element) {}); each()使ってますか? ループ処理の時に便利ですよね。 しかしこのeach関数、処理が遅いことで知られて います。 jQueryの問題では無く、JavaScriptの関数呼出の オーバーヘッドが原因です。 12年10月27日土曜日 40
  • 41. JavaScriptの便利なライブラリ jQuery ■jQueryでのloop処理(each) for (var i=0, limit=$a.length; i < limit; i++) { ! //$a[i]; } まだ、こちらの方がましかと思います。 ループ内で関数呼出したら同じことですけど... 12年10月27日土曜日 41
  • 42. JavaScriptの便利なライブラリ jQuery ■jQueryのDOM Selector jQueryのDOM Selectorは大変優秀です。 ネイティブ機能だけでは不可能なことも軽々とや ってのけてしまいます。 これ無しには生きていけないかもしれません。 不可能なことは無いのではと思えてしまいます。 12年10月27日土曜日 42
  • 43. JavaScriptの便利なライブラリ jQuery ■jQueryのDOM Selector でも 12年10月27日土曜日 43
  • 44. JavaScriptの便利なライブラリ jQuery ■jQueryのDOM Selector jQueryのDOM Select の 仕組みを 見てみましょう 12年10月27日土曜日 44
  • 45. JavaScriptの便利なライブラリ jQuery ■jQueryのDOM Selector document.getElementById(); document.getElementsByName(); document.getElementsByTagName(); document.getElementsByClassName(); document.querySelector(); document.querySelectorAll(); JavaScriptには上記のようなselector関数が用意さ れています。 jQueryと言えどもこれらの関数を使用します。 12年10月27日土曜日 45
  • 46. JavaScriptの便利なライブラリ jQuery ■jQueryのDOM Selector $('#main .className'); jQueryで上記のような指定の場合JavaScriptだと... document.querySelectorAll('#main .className'); しかしquerySelectorAllはモダンなブラウザにし か用意されていません。 コメントご指摘通り間違えているので削除します。 IEではgetElementsByClassNameの方が実装がquerySelectorAllより早く行わ れています。 SafariはgetElementsByClassNameの方が早かったように思っていたのです が確証がありません。 使えない時は... document. ?getElementById('main'). ?getElementsByClassName('className'); 12年10月27日土曜日 46
  • 47. JavaScriptの便利なライブラリ jQuery ■jQueryのDOM Selector jQueryにはsizzleというDOM Selectのためのライ ブラリが内蔵されており、レガシーブラウザの時で も、もっと効率的に選択が行われます。 結果は全て複数になります。 配列の様な形式です。 単独のDOMを選択するより処理コストがかかりま す。 12年10月27日土曜日 47
  • 48. JavaScriptの便利なライブラリ jQuery ■jQueryのDOM Selector $('#main'); DOMの選択はdocument.getElementByIdが最速 です。 可能な限りidで指定し取得すべきです。 HTML内に1つしか存在しないのにtag名やclass名 で選択していないか確認してみることをお勧めし ます。 12年10月27日土曜日 48
  • 49. JavaScriptの便利なライブラリ jQuery ■jQueryでのEvent処理(Click) <ul id="tCon"> ! <li><a href="img/s/earth.jpg"><img src=/slideshow/javascript-14882630/14882630/"img/t/earth.jpg" alt=""></a></li> ! <li><a href="img/s/jupiter.jpg"><img src="img/t/jupiter.jpg" alt=""></a></li> ! <li><a href="img/s/mars.jpg"><img src="img/t/mars.jpg" alt=""></a></li> ! <li><a href="img/s/mercury.jpg"><img src="img/t/mercury.jpg" alt=""></a></li> ! <li><a href="img/s/moon.jpg"><img src="img/t/moon.jpg" alt=""></a></li> ! <li><a href="img/s/neptune.jpg"><img src="img/t/neptune.jpg" alt=""></a></li> ! <li><a href="img/s/saturn.jpg"><img src="img/t/saturn.jpg" alt=""></a></li> ! <li><a href="img/s/solarsystem.jpg"><img src="img/t/solarsystem.jpg" alt=""></a></li> ! <li><a href="img/s/sun.jpg"><img src="img/t/sun.jpg" alt=""></a></li> ! <li><a href="img/s/uranus.jpg"><img src="img/t/uranus.jpg" alt=""></a></li> ! <li><a href="img/s/venus.jpg"><img src="img/t/venus.jpg" alt=""></a></li> </ul> 【設問】 上記のようなHTML内のaタグにclickイベントを設 定するコードを記述せよ。 12年10月27日土曜日 49
  • 50. JavaScriptの便利なライブラリ jQuery ■jQueryでのEvent処理(Click) <ul id="tCon"> ! <li><a href="img/s/earth.jpg"><img src=/slideshow/javascript-14882630/14882630/"img/t/earth.jpg" alt=""></a></li> ! <li><a href="img/s/jupiter.jpg"><img src="img/t/jupiter.jpg" alt=""></a></li> ! <li><a href="img/s/mars.jpg"><img src="img/t/mars.jpg" alt=""></a></li> ! <li><a href="img/s/mercury.jpg"><img src="img/t/mercury.jpg" alt=""></a></li> ! <li><a href="img/s/moon.jpg"><img src="img/t/moon.jpg" alt=""></a></li> ! <li><a href="img/s/neptune.jpg"><img src="img/t/neptune.jpg" alt=""></a></li> ! <li><a href="img/s/saturn.jpg"><img src="img/t/saturn.jpg" alt=""></a></li> ! <li><a href="img/s/solarsystem.jpg"><img src="img/t/solarsystem.jpg" alt=""></a></li> ! <li><a href="img/s/sun.jpg"><img src="img/t/sun.jpg" alt=""></a></li> ! <li><a href="img/s/uranus.jpg"><img src="img/t/uranus.jpg" alt=""></a></li> ! <li><a href="img/s/venus.jpg"><img src="img/t/venus.jpg" alt=""></a></li> </ul> $('#tCon a').on('click', function (e) { ! e.preventDefault(); ! e.stopPropagation(); }); 動きますが、もう少し効率的な処理があります。 12年10月27日土曜日 50
  • 51. JavaScriptの便利なライブラリ jQuery ■jQueryでのEvent処理(Click) $('#tCon').on('click', function (e) { ! e.stopPropagation(); ! e.preventDefault(); ! var target = e.target, ! ! nodeName = target.nodeName.toLowerCase() ! ; ! if (nodeName !== 'img' && nodeName !== 'a') { ! ! return false; ! } }); Event伝播の仕組みを利用し上位のコンテナで Clickアクションを取得し利用しています。 *nodeNameを調べる必要があります。 12年10月27日土曜日 51
  • 53. 箩蚕耻别谤测は最速? jQueryに限った話ではありません。 他のライブラリ(Framework)も同じです。 そもそも、 このようなライブラリたちが登場したのはクロス ブラウザ対策が困難を極めたからです。 多くのライブラリはレガシーブラウザを含め正常 に機能するように設計されています。 12年10月27日土曜日 53
  • 54. 箩蚕耻别谤测は最速? var $tCon = document.getElementById('tCon'); ! function onClick (e) { ! var target, nodeName, a; ! if (typeof e === 'undefined') { ! ! e = window.event; ! ! target = e.srcElement; ! } else { ! ! e.preventDefault(); ! ! e.stopPropagation(); ! ! target = e.target; ! }; ! nodeName = target.nodeName.toLowerCase(); ! if (nodeName === 'img') { ! ! a = target.parentNode; ! } else if (nodeName === 'a') { ! ! a = target; ! } else { ! ! return false; ! }; ! // ココにScript ! return false; }; if (typeof $tCon.addEventListener !== 'undefined') { ! $tCon.addEventListener('click', onClick, true); } else { ! $tCon.attachEvent('onclick', onClick); }; 先ほどのClick問題をライブラリを使わずに書き直しました。 12年10月27日土曜日 54
  • 55. 箩蚕耻别谤测は最速? Eventをリスナーする EventはaddEventListenerかIEのattachEventを使いイベント?ハンドラを設定します。 Eventハンドラ addEventListener addEventListenerを使ったときはハンドラ引数へEventインスタンスが送られてきます。 EventインスタンスのtargetプロパティのnodeNameを調べるとEvent発生場所が分かりま す。 Eventの伝播を止めるためにpreventDefault, stopPropagationします。 attachEvent attachEventを使った時は引数へEventインスタンスが送られてきません。 そのかわりwindow.eventが使えます。 window.eventにはtargetプロパティがありません、そのかわりsrcElementプロパティが使 えます。 srcElementのnodeNameを調べるとEvent発生場所が分かります。 preventDefault, stopPropagationが使えないのでEventの伝播を止めるためにreturn false で代用します。 12年10月27日土曜日 55
  • 56. 箩蚕耻别谤测は最速? ふ~ 12年10月27日土曜日 56
  • 57. 箩蚕耻别谤测は最速? なかなか大変ですが $(document).ready() は もっと大変です 12年10月27日土曜日 57
  • 58. 箩蚕耻别谤测は最速? ;(function (window, functions) { var document = window.document, functions = functions && functions.splice ? functions : [], ie = document.addEventListener ? false : true, 見えないですよね、 complete = false, dispose = function () { 解説はblogへ if (complete) { return; }; complete = true; if (!ie) { document.removeEventListener('DOMContentLoaded', onDOMContentLoaded); document.removeEventListener('readystatechange', onReadyStateChange); window.removeEventListener('load', onWindowLoad); } else { document.detachEvent('onreadystatechange', onReadyStateChange); window.detachEvent('onload', onWindowLoad); }; for (var i = 0, limit = functions.length; i < limit; i++) { setTimeout(functions[i], 25 * i); }; }, onDOMContentLoaded = function (e) { dispose(); }, onReadyStateChange = function (e) { if (document.readyState == 'complete') { dispose(); }; }, onWindowLoad = function (e) { dispose(); } ;// end of variables ? if (!ie) { document.addEventListener('DOMContentLoaded', onDOMContentLoaded, false); document.addEventListener('readystatechange', onReadyStateChange, false); window.addEventListener('load', onWindowLoad, false); } else if (document.attachEvent) { document.attachEvent('onreadystatechange', onReadyStateChange); window.attachEvent('onload', onWindowLoad); }; }(window, [ function () {console.log('function 1')}, function () {console.log('function 2')}, function () {console.log('function 3')} ] )); http://www.inazumatv.com/contents/archives/7245 12年10月27日土曜日 58
  • 59. 箩蚕耻别谤测は最速? ふ~ 12年10月27日土曜日 59
  • 60. 箩蚕耻别谤测は最速? ライブラリ内はもっと効率良くScriptが書かれてい ます。 クロスブラウザ対策に多くのコードが使われてい るのが分かって頂けたと思います。 IEでは使えないpreventDefault, stopPropagation も使えるようになっていたり... 12年10月27日土曜日 60
  • 61. 箩蚕耻别谤测は最速? もしも モダンブラウザ だけが ターゲットだったら 12年10月27日土曜日 61
  • 62. 箩蚕耻别谤测は最速? いらない機能ですよね~ ほら、スマホとか... 12年10月27日土曜日 62
  • 63. 箩蚕耻别谤测は最速? jQuery 2.0 は IE 8以下をサポートしない jQuery 2.0 (early 2013, not long after 1.9): This version will support the same APIs as jQuery 1.9 does, but removes support for IE 6/7/8 oddities such as borked event model, IE7 “attroperties”, HTML5 shims, etc. http://blog.jquery.com/2012/06/28/jquery-core-version-1-9-and-beyond/ 12年10月27日土曜日 63
  • 64. 闯补惫补厂肠谤颈辫迟を使って Webサイトを 作っていますか? 12年10月27日土曜日 64
  • 65. その闯补惫补厂肠谤颈辫迟が UXをだいなしにしてる.... かもですよ 奥さん 12年10月27日土曜日 65
  • 66. HTML, CSS, 画像の最適化に 心配りしたWeb制作を しているなら JavaScriptもね 12年10月27日土曜日 66
  • 67. 闯补惫补厂肠谤颈辫迟を 無効にしてもWebサイトは 問題無く 見たり使用できますか? 12年10月27日土曜日 67
  • 68. JavaScriptは上手に使うとHTML, CSSだけでは実現 できないUIを提供できます。 HTML5のAPIには魅力的なものが沢山あります。 Canvas, WebGL, Geo-Location, WebWorkers... 弱点を良く知りステキなコンテンツを届けるために 使ってあげて下さい。 12年10月27日土曜日 68
  • 69. @taikiken http://www.inazumatv.com/contents/archives/7037 まだまだ発展途上です。 間違いなどありましたらご指摘下さい。 12年10月27日土曜日 69
  • 70. 修正 2012-10-26 インタプリンタ -> インタプリタ p.16, p.32 Page削除 p.46 スライド上には残っています 12年10月27日土曜日 70