ラベル tips の投稿を表示しています。 すべての投稿を表示
ラベル tips の投稿を表示しています。 すべての投稿を表示

2013年8月31日土曜日

【jQuery】iframe要素をモーダルウィンドウっぽいポップアップで読み込ませる


課題でつかったjQueryの一部を復習かねてまとめます。

こんなかんじで、ある要素をクリックした時点で画面全体をグレーアウトさせるレイヤーとその上にポップアップする外部ファイルを読み込むiframe要素を生成し、グレーアウト部分をクリックするとポップアップもグレーアウトレイヤーも消えて元画面に戻ります。
特にプラグインは必要なく、jQuery本体があれば実装できるつくりになっています。

イメージとしてはこんな感じ。


--------------------------------------------------------------------

HTMLはjQueryが動作しない時、javascriptの動作を許可しないユーザーのために

<a href="URL" target="_blank">リンク文字</a>

と別窓リンクを設定しておきます。
HTMLはこれだけで。

---------------------------------------------------------------------

CSSの設定は以下。

/*グレーアウトのスタイル定義*/
#gray{
background:#000;
opacity:0.8;
width:100%;
height:100%;
position:fixed;
top:0;
left:0;
display:none;
z-index:500;
}

/*ポップアップ部分のスタイル定義*/
#square{
display:block;
width:490px;
height:510px;
z-index:510;
background-color:#fff;
overflow:hidden;
}

#popup{
display:block;
width:490px;
height:510px;
overflow:hidden;
border:none;
}


---------------------------------------------------------------------
以下はjQueryのコード。

$(function(){
 /*-------------------------------
 イベント処理「PopUp」を定義
 --------------------------------*/
 var PopUp = function(){
  //読み込む外部ファイルを取得しておく
  var poplink = ($(this).attr('href'));
  //要素を作成
  $('<div id="gray" class="gray_panel"></div>').appendTo($('#main'));
  $('<div id="square"><iframe id="popup" name="popup"></iframe></div>').appendTo($('#main'))
  .css('display','none');
  //ポップアップを画面中央位置になるよう、位置関係を算出
  var leftposition = Math.floor(($(window).width() - $("#square").width()) / 2);

  //グレー背景をフェードインで表示
  $('#gray')
   .fadeIn("slow")
   .css("display","block");
  //ポップアップ表示領域のスタイル定義
  $('#square')
   .fadeIn("slow")
   .css({
    "position" :"fixed",
    "top"  :"30px",
    "left"  :leftposition,
    "display" :"block",
    "overflow" :"hidden"
   });
  $('#popup')
   //ポップアップ内に外部ファイルを読み込む
   .attr('src',poplink)
   .css({
    "position" :"fixed",
    "top"  :"30px",
    "left"  :leftposition,
    "display" :"block",
    "overflow" :"hidden"
   });

  //クリックして別窓表示という本来の動作をキャンセル
  return false;
 };
 /*-------------------------------
 イベント処理「PopDown」を定義
 --------------------------------*/
 //作成したグレーアウト、iframe、表示領域をフェードアウトさせて削除する
 var PopDown = function(){
  $('#gray,#popup,#square')
   .fadeOut("slow")
   .remove();
 };

 /*-------------------------------
 定義した処理を呼び出す指示
 --------------------------------*/
 //リンクをクリックしたらイベント処理「PopUp」を呼び出し
 $('
リンクの要素名')
  .click(PopUp);
 //グレーアウト部分をクリックしたらイベント処理「PopDown」を呼び出し(追加要素へのイベント処理なのでliveメソッド使用)
 $('#gray').live('click',PopDown);
});

--------------------------------------------------------------------------
ちょこちょこ入れているコメントアウトの通りですが細かく解説をいれると以下のようになります。

1.イベント処理[PopUp]を定義

  //読み込む外部ファイルを取得しておく
  var poplink = ($(this).attr('href'));

ここで、変数poplinkを用意し、クリックした要素(HTMLのリンク文字)が持つリンク先URL(href="URL"のURL)を取得して代入しておきます。
たとえばHTMLで<a href="page1.html" target="_blank">リンク文字</a>としていたら変数poplinkにはpage1.htmlが代入されます。



  //要素を作成
  $('<div id="gray" class="gray_panel"></div>').appendTo($('#main'));
  $('<div id="square"><iframe id="popup" name="popup"></iframe></div>').appendTo($('#main'))
  .css('display','none');

ここでクリックしたときにポップアップしてくる要素を生成します。
ここではグレーアウトさせるためのdiv要素を「gray」、ポップアップするiframeを内包したdiv要素を「square」、外部ファイルを読み込むiframe要素を「popup」とID付しています。
初期状態ではCSS・display:noneで非表示にしています。



 //ポップアップを画面中央位置になるよう、位置関係を算出
  var leftposition = Math.floor(($(window).width() - $("#square").width()) / 2);

これはコメントアウトの通りです。
変数leftpositionに計算式で出した数値を代入します。



 //グレー背景をフェードインで表示
  $('#gray')
   .fadeIn("slow")
   .css("display","block");

ここで画面全体を覆うグレーアウトのdiv要素#grayをfadeInメソッドで表示させます。



//ポップアップ表示領域のスタイル定義
  $('#square')
   .fadeIn("slow")
   .css({
    "position" :"fixed",
    "top"  :"30px",
    "left"  :leftposition,
    "display" :"block",
    "overflow" :"hidden"
   });


ポップアップのiframeを内包したdiv要素・#squareを上記の#grayと同じようにフェードインさせると共に、表示位置をCSSのpositionで設定。ここでpositionのleftに、先ほど用意した変数leftpositionを使います。



$('#popup')
   //ポップアップ内に外部ファイルを読み込む
   .attr('src',poplink)


生成したdivが含むiframe ・「#popup」が読み込む外部ファイルのソースを設定します。
生成した時点では<iframe id="popup" name="popup"></iframe>と、idとname付けしかしていないのでattrメソッドで属性src,値を変数poplinkとして追加します。



 //クリックして別窓表示という本来の動作をキャンセル
  return false;

これもそのまま。javascriptが動作した場合はHTMLに設定している別窓リンクをキャンセルさせます。これって、なんでreturn falseでキャンセルされるのかいまいちわからないまま使っています。(……)



2.イベント処理「PopDown」を定義

//作成したグレーアウト、iframe、表示領域をフェードアウトさせて削除する
 var PopDown = function(){
  $('#gray,#popup,#square')
   .fadeOut("slow")
   .remove();
 };

フェードアウトさせるための処理です。
生成した#gray,#popup,#square三つの要素すべてをフェードアウトして要素を削除します。
この削除がポイント。フェードアウトさせるだけでは、非表示になるだけで、再びリンクをクリックしたタイミングで同一のIDをもつdivやiframeが新たに生成されてしまいます。
単にリンクさせている場合は特に問題なさそうですが、読み込む外部ファイルにアンカーリンクさせていると、アンカーがうまく作動しなくなりました。
なので非表示にさせるタイミングで要素辞自体を一度削除するべきでしょう。



3.定義した処理を呼び出す指示

 //リンクをクリックしたらイベント処理「PopUp」を呼び出し
 $('リンクの要素名')
  .click(PopUp);
 //グレーアウト部分をクリックしたらイベント処理「PopDown」を呼び出し(追加要素へのイベント処理なのでliveメソッド使用)
 $('#gray').live('click',PopDown);
});



リンク文字をクリックした時点、グレーアウトをクリックした時点でそれぞれ定義したイベント処理「PopUp」「PopDown」を呼び出します。
#grayはHTMLのほうにある要素ではなく、jQueryの処理の中で新たに生成・追加した要素なのでliveメソッドを使っています。
このliveメソッドを適用させるタイミングがいまいちわかっておりません。うーん。


---------------------------------------------------------------------------

ざっとこんな感じでした。
HTMLでのリンクで外部ファイルにアンカーリンクを設定していて、removeさせるという考えが全くなく、アンカーが全く効かなくて頭をひねりまくりました。
removeが必要な理由を上で考察しましたが、その理由が正解なのかはわかりません笑

それにiframeを囲むdivも本当に必要だったのか?
iframe要素だけでは成り立たないのか、検証してません。もしかしたら必要ないかもしれません。

いろいろと詰めの甘いソースですが、現在の自分が組めたのはこんなものでした。

2013年8月17日土曜日

【jQuery】制作中【CSS3】

出遅れている中、課題の金魚ECサイトのコーディング中。
今回は横型のコンテンツなので、ページ遷移などに関して、jQueryを使ってみた。

参考にしたサイトをメモ。

【jQueryでマウスホイールで横にスクロールする横型コンテンツ】

【jQueryでマウスホイールすると余韻が残るイージングスクロールをつくる】

こちらのページを参考にしてjQueryプラグインを使った実装。うーん、ほとんど理解せぬまま動くから、便利だけど、自分で作っておきながらいまいちわかってない不安感。
自分のつくったページを100%理解していたいなんて思ってしまうけど、じゃあそもそもライブラリ使うなって感もあるよな・・・・・・。
ともかく、WEBは惜しみなくその技術をオープンにしてくれる方々のおかげで、こんな自分でも動的コンテンツを作ることができる。とってもありがたいです。

横スクロールで、縦書きのレイアウト部分で出来るなら画像じゃなくテキストとして記述したいと、
WEB上で縦書きを実現する方法はないのかなと探していましたら、ありました。

JavaScript 版 縦書き化ツール「竹取JS」】

こちらはjQueryではなくjsです。
サンプルページがとてもきれい。横/縦書きの切り替えをさせられるのもいい。
今回は結局使わないけれど、機会があったらぜひ使ってみたい。

HTML5の授業の中でCSS3を少しずつ使いだし……
アニメーションロールオーバーが手軽でかっこいい!
透明度調整でなんかイケてる!
角丸いちいちpng画像にしなくてもいいんだ!

と、基礎的なところで感動中。
でも、感動の勢いでついつい無意味に装飾してしまいがちになるので、ほどほどに抑えよう…。
今回は通常の金魚ECサイトにないインターフェースを、というアプローチなので、装飾に凝るのは方向としては間違っていないのですが、機能性を丸無視しちゃあしょうがないですからね。改めてここら辺を念頭に入れておかないと。

PHPの勉強に手が回らない・・・・・・

2013年7月9日火曜日

HTML・CSS・アップロード検証

課題提出を目前にしてCSS採点ページがあるということを知った。
そりゃHTML採点があるならCSS採点もあるんでしょう。そうでしょう。
なぜもっと早く気付かなかったのか……と思いながらとりあえずCSS2.1で検証してもらうと、ボッコボコに減点してもらった。

CSSを策定しているW3WのCSS検証サービスはこちら。
http://jigsaw.w3.org/css-validator/validator.html.ja#validate_by_upload+with_options
もちろん無料。いやーありがたいことです。
単純に;落としてることとか、知らなかったCSS2.1準拠の書き方とか。

HTMLはこちらでチェック。
http://cetus.sakura.ne.jp/htmllint/htmllint.html

合わせて無料レンタルサーバにFFFTPでアップロードして検証してみるとローカルでは見逃されていたファイル名の大文字小文字の違いなどが見えてきて、うわー提出前に気が付いてよかったなあ。

ただ借りているサーバーのリリースがごく最近だったようで、初心者の自分にはひどく使いにくい。
初心者にやさしい、広告のでない無料サーバーをもう少し探したい。

2013年7月6日土曜日

IE以外のブラウザでリンクが見えているのにクリックできなかった件

課題もあとわずか、作業を詰めていく中で一週間くらい悩み、放置していた問題が片付いたので、まとめてみる。
一か月前にweb制作を始めたド素人の個人用メモに過ぎないので、分かりやすい説明を求めている方は申し訳ないが他の方のまとめられているのをお勧めします。

IE以外のブラウザ(firefox,chrome,opera)でリンクが機能しなかった

上部に横一列のナビゲーションを設置していた課題作品のwebサイトで。

基本的にどのページにも設置していたナビゲーションだったが、あるページでナビゲーションが機能しなくなった。
ロールオーバーを設定していたのだが、アンカーに触れてもピクリともしない。
クリックしてもなんの反応もない。しかしナビゲーションは確かに表示されている。

アレ? と思いXHTMLを見てみるが、ほかのページと代わりはない。
そりゃそうだ。共通するナビゲーション部分のソースはコピペして使っているのだから。
いやしかし見落としているだけで、余計なの混ざっちゃってるのかもしれない、と一応、コンテンツ部分だけ抜き出して、もう一度他のページからソースをコピペしなおしてみる。

おや? リンクが反応した。クリックできる。
やはり何かまじっちゃってたのか…と思いながら、コンテンツ部分用の外部CSSを問題のページ専用のものに付け替えた。

すると、リンクが再び反応しなくなった。

エエエ、とがっくりきながら、しかしこれは前進だ。

問題は外部CSSだったのだ。

今回のサイトは

reset.css     (リセット用)
base.css     (共通している要素(headやfooter)のデザイン)(問題の上部ナビゲーションの設定はここでしていた。)
ページ名.css  (各コンテンツエリアのデザインをページごとに分けて作っていた)

の三段構えで作っていた。

件のクリックしなくなった問題は、一番下のページ名.cssを付け替えた時点で起こった。
ということはこのページ名.cssに何か問題があるのだ。

というわけであれやこれやと検証した結果……

positionを設定してある要素同士の重なりが問題だったみたいだ。

ページ全体をposition:relativeで中央寄せし、子要素ナビゲーションにはposition:absoluteでbase.cssに、同じく子要素のメインコンテンツにはposition:relativeでページ名.cssにそれぞれ位置指定していた。
しかしこれは他のページも同じだしな…と、他のページのページ名.cssを引っ張り出して見比べてみると……

*ID名などは仮

問題のページCSS

#maincontents{
 position:relative;
 margin-left:auto;
 margin-right:auto;
 padding-top:85px;


-------------------------------------

他のページCSS

#maincontents{
 position:relative;
 margin-left:auto;
 margin-right:auto;
 top:85px;


-------------------------------------

おや?
どうやらメインコンテンツの上部の余白の稼ぎ方が違ったらしい。

問題のページはpaddingを上に伸ばしているので実際は見えている状態だったが、上部ナビゲーションの上にメインコンテンツ領域がかぶさった状態だったらしい。

他のページはpositionのtopで上から85pxのところからこの領域、という指定をしていたので上部ナビゲーションとは重なっていない。

なるほどなるほど。
レイヤーみたいに重なっちゃってるんだな……うん? なんかそんな話授業のどこかで聞いたな…と汚い殴り書きノートをめくってみる。

あった。positionを初めて習ったとき、あんま使わないよネ~と思っていたposition:fixedの項目の下に、

z-index  positionがついたものの重なり順を設定できる。
ex)z-index:10; ←1でもよいが10単位が一般的。数字が大きいほうが上に重なる。

と走り書き。
この10単位が一般的、というのは、
後から新たに挿入する要素がでてきたとき、要素1:z-index:1と要素2:z-index:2と設定してしまうと要素2のz-index:を3にしてから新要素:z-index:2などと設定しなくてはならない。
しかしもともとz-indexを10と20で設定しておけば間に挿入する新要素のz-indexは11でも15でも19でもいいのだ。
つまり、元の要素のz-indexをいじる手間が省ける。
しかも要素1のさらに下層にも挿入するのも簡単にできる。
ということらしい。

少し脱線したが、とりあえずbase.cssの上部ナビゲーション部分にz-index:100を設定してみた。
(100の理由はとにかく上! 上に来い!! という気負いと、もし他の要素にz-index指定があっても100は上回れまい、という微妙にビビりな理由から。他要素にz-indexが登場していなければ10で十分かと思われます)


きた!
リンクが反応した! ヤッターと小躍りして家族に擦り寄ったら、事情を知らない相手から「あぁそうよかったね」とドライな返事。いや、返事してくれただけでありがたい。よかったよほんと。

-----------------------------------------------------------

結果…

positionで指定した要素同士の領域が被ると、下層になってしまった要素のアンカーリンクはたとえ見えていてもクリックもロールオーバーもできない(まさに触れられない)

ということだったみたいだった。
しかも厄介なことに、IEではクリックできる。
とりあえず自分で確認したブラウザopera,firefox,chromeではクリックできなかった。

対処法は重なった要素のどちらか、あるいは全てにz-indexで重なり順を調整すること。
リンクを機能させたいなら一番上にその要素を持ってくる。

まだブラウザ毎の差異について軽く話を聞いていただけで、アァ~デフォルトのマージン量が違うんだナ~くらいにしか思っていなかったので、今回のことで身に染みた。今回はIEで通って、それ以外だと機能しないパターンだったが、世間ではその逆で、IEにだけ効かない!! ということが多々あるらしい。
IE嫌われてんだなあーとかるーく思っていたがこういうことを毎度IEだけで起こったら確かに嫌やな…と実感。

とりあえず、今回のページは特に重なりを必要とするレイアウトでもなかったので、結局z-indexを使わず、padding-topをpositionのtopに差し替えて終了。
うんうん言いながらいろいろ検証してみてよかった。こういうアクシデント(ていうほどでもないんだろうけど)対処って勉強になるなあと。

さ、課題にもどるのだ……。