スポンサーサイト

2014.01.27 Monday

一定期間更新がないため広告を表示しています

  • -
  • -
  • -

全然まとまってないのですが、まとまりそうもなく

また早くアウトプットして次にいきたかったのでメモを記事に。

前々回記事にしたアプリについて今ひとつ納得できない。

ふとcanvasの画像をiPhoneのカメラロールに保存ってできないかなぁ、

そーいえば画像は普通に長押しすれば保存ができるじゃん。

がしかし、スタンドアロンモードって色々制限されるんでしょうか?

まずimg要素長押ししてもうんともすんとも。

しょうがないからbase64をaタグにてリンクさせてみたけど

遷移しないし。

こーなったらblobを作成してクリックしてみたけど

これまたうんともすんとも。

blobリンクに関しては通常のsafariでもリンク先にいけませんでした。

う〜ん。

createObjectURLとはなかなか便利そうですが、

iOS対応しているのでしょうか???

Blob、ArrayBuffer、とかよくわからんなぁ。。。

なんか色々できそうですが、、、。

いずれまた改めて勉強したいと思いますので

これ以上考えるのはとりあえずやめよう。

今回のテスト内容は一応こちら

参考
Ajax:画像を取得して表示する(Firefox): Script雑感
XMLHttpRequest2 に関する新しいヒント - HTML5 Rocks

setTimeout

第一引数 文字列又は関数オブジェクト

function test() {
 alert('test');
};
setTimeout(test, 1000);//1ms後実行
setTimeout(test(), 1000);//評価時に即実行
setTimeout('test()', 1000);//1ms後実行
setTimeout('test', 1000);//単なる文字列なので何も起こらない

第一引数が文字列の時evalされる。
引数を渡したいとき、


var str = 'str';
function test(arg) {
 alert(arg);
};
setTimeout('test("' + str + '")', 1000);
//一応可能
setTimeout(function(){test(str)}, 1000);
//無名関数を渡せば問題無い

for文 条件文のiとスコープ

var arr = [1,2,3];
for(var i=0,len=arr.length;i<len;i++){
  setTimeout(function() {
    console.log(arr[i]);//undefined×3
  }, i * 1000);
};

setTimeout内でarrにアクセスできていないのかと一見思った。 がiがブロックスコープの為このコンソールは全てarr[3]にアクセスし undefinedが返っている。


var arr = [1,2,3];
console.log(i);//undefined>条件式で定義されてるからエラーではない
  for(var i=0,len=arr.length;i<len;i++){
    console.log(i);//0,1,2
    setTimeout(function() {
      console.log(i);//3,3,3>ブロックスコープでは無い為
    }, i * 1000);
  };
};
console.log(i);//3>条件式で3回インクリされた状態で残る
 
var arr = [1,2,3];
for(var i=0,len=arr.length;i<len;i++){
  (function(arg) {
    setTimeout(function() {
      console.log(arr[arg]);//1,2,3
    }, arg * 1000);
  })(i);
};
//クロージャにてスコープをキープ

DOMアクセス

forで回してDOM要素にアクセスしてイベントハンドリング。 参考までに画像を見込んだ順にフェードインするスクリプト。


DEMO


css
<style type="text/css">
h1 {
     font-family: Helvetica, Arial;
     text-align: center;
}
#gallery {
     width: 95%;
     margin: 0 auto;
     padding: 5px;
     border: solid 1px #ccc;
     border-radius: 5px;
}
#gallery li {
     list-style-type: none;
     width: 200px;
     height: 200px;
     display: inline-block;
     background: url('load.gif') no-repeat center;
}
#gallery img {
     width: 200px;
     height: 200px;
     opacity: 0;
}
</style>
html
<h1>- gallery -</h1>
<ul id="gallery">
     <li><img src="1.png" /></li>
     <li><img src="2.png" /></li>
     <li><img src="3.png" /></li>
     <li><img src="4.png" /></li>
     <li><img src="5.png" /></li>
     <li><img src="6.png" /></li>
     <li><img src="7.png" /></li>
     <li><img src="8.png" /></li>
     <li><img src="9.png" /></li>
     <li><img src="10.png" /></li>
     <li><img src="11.png" /></li>
     <li><img src="12.png" /></li>
</ul>

とりあえず、変数iをクロージャでキープ

onloadイベントの前に無名関数でスコープを作らないと

onloadが実行される時にはみんな同じiを参照してしまう、、、。

setTinerval内も無名関数のスコープで実行できる。


<script type="text/javascript">
var gallery = document.getElementById('gallery');
var elem = gallery.getElementsByTagName('img');
var timerId = [];
var count = [];
for(var i=0,len=elem.length;i<len;i++) {
     count[i] = 0;
     (function(arg) {
          elem[arg].onload = function() {
               timerId[arg] = setInterval(function(){fade(arg)}, 50);
          };
     })(i);
};
function fade(tar) {
     if(elem[tar].style.opacity >= 1) {
          clearInterval(timerId[tar]);
     } else {
          count[tar] += 0.1;
          elem[tar].style.opacity = count[tar];
     };
};
</script>

こん度は頑張ってthisとか使ってみる。

そんで、ついでにmouseoverとかも追加してみる。


<script type="text/javascript">
function ImgObj(img) {
     var that = this;
     this.img = img;
     this.duration = 0.1;
    
     this.img.addEventListener('load', function() { that.fadeIn() }, false);
     this.img.addEventListener('mouseover', function() { that.fadeOut() }, false);
     this.img.addEventListener('mouseout', function() { that.fadeIn() }, false);
};
 
ImgObj.prototype.fadeIn = function() {
     var that = this;
     if(this.fadeTimer) {
          clearInterval(this.fadeTimer);
     } else {
          this.opacity = this.img.style.opacity = 0;
     };
     this.fadeTimer = setInterval(function() { that.chgOpacity(1) }, 50);
};
ImgObj.prototype.fadeOut = function() {
     var that = this;
     if(this.fadeTimer) {
          clearInterval(this.fadeTimer);
     } else {
          this.opacity = this.img.style.opacity = 1;
     };
     this.fadeTimer = setInterval(function() { that.chgOpacity(0) }, 50);
};
ImgObj.prototype.chgOpacity = function(limit) {
     this.opacity = Math.round(this.opacity * 100) / 100;
     if(this.opacity == limit) {
          clearInterval(this.fadeTimer);
     } else {
          this.opacity += limit ? this.duration : -this.duration;
          this.img.style.opacity = this.opacity;
     };
};
 
var gallery = document.getElementById('gallery');
var elem = gallery.getElementsByTagName('img');
var imgObj = [];
for(var i = 0, len = elem.length; i < len; i++) imgObj[i] = new ImgObj(elem[i]);
</script>

クロージャなしでいけるのか?

しかしイベントリスナ部でthisを 使用するとそこはやはりそのイベント発生元のDOMを参照する。

setInterval内でのthisはwindowを参照する。

それでこのthisの参照が違うって聞くと、いよいよかっこよさげなapplyとか callが使えるの??って思って考えたけどよく理解していませんので 使い道が思いつきませんでした。

基本的にthisをローカル変数に代入してクロージャで参照するって感じでしょうか。

前から思ってたけどこういうイベントハンドリングみたいなのを クラスとか使う書き方が全くもってわからん。

なので我ながら 意味不明なコードになってます。

結局クロージャです。正直クロージャってのもあまり理解できていません。

なんか検索しようとするとメモリリークとかサジェストで出てくるし。

しっかり理解した方が良さそうさな。


1

calendar

S M T W T F S
 123456
78910111213
14151617181920
21222324252627
28293031   
<< October 2012 >>

profile

last entry:2013/06/10

selected entries

categories

archives

recent comment

search this site.

others