POPSブログ

AlphaImageLoaderフィルターとIEの振る舞い

30

  Category:  jquery2012/02/21 pops 

AlphaImageLoaderフィルターとalphaフィルターのIEの振る舞いについてまとめて見ました。


AlphaImageLoaderフィルターとIEの振る舞い


jqueryなどを使い色々な処理をする途中、IEのフィルターあるいは、IE固有のバグなどにより多くの問題が発生すると思います。下記、説明は大変抽象的ですが、経験上からの対処方法など列記します。


透過PNG画像を使用する場合

以前から問題になる事ですが、少し取りまとめて見たいと思います。ほとんど使用されなくなったIE6についても記述します。またIE8が今後何年か使用されることも予想されますので、重要な問題です。

透過PNG画像を使用する場合に問題となるのはIE6では、透過PNG画像を使用できませんが、透過PNG画像にAlphaImageLoaderフィルターを施せば良いだけです。


但し、jqueryなどでフエード処理を行った場合は状況が違います。IE7,8で透過PNG画像が黒く壊れてしまいます。

IE7.8でも、AlphaImageLoaderフィルター処理を行なわねば成りません


jqueryなどでフエード処理を行うことなどを考慮して、その振る舞いの対処方法を考えます。

IE、以外では99%問題は起きません。IE固有の問題です。


IE6にAlphaImageLoaderフィルターを施す

例では背景画像に処理しています、次のようになります。

CSS


#parts {
	display: block;
	position: absolute;
	top: 0;left: 0;
	width: 20px;
	height: 20px;
	background: transparent url("../images/parts_bk.png") no-repeat;
	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/parts_bk.png',sizingMethod='scale');
	background-image: none;
}

背景画像の「読み込みパス」と「フィルター処理のパス」が違うことに注意ください。判らない場合は両方を「絶対パス」にすれば良い。

注意、背景画像の上にAlphaImageLoaderで、新たな透過画像が作られますので、処理後、背景画像を削除します。削除しないと2枚になり濃くなります。マージンは効きません。



透過PNG画像を周辺に配置し、動かした場合の現象です。

  • IE7.8 透過PNG画像に対応しているのですが、フェード処理した場合に「透過画像が黒く壊れる」ので、「AlphaImageLoaderフィルター」を処理する。(alphaフィルターの影響。完全に対応していないと言える)
  • IEでテーブルの周辺に、透過PNG画像を配置した場合は正常(画像重なりなど無い)ですが、動かした場合は中に配置した画像とのズレが発生します。テーブルの移動が重いためです。IEでは以外と簡単ですが、構成にもよるが、IE以外は移動の際に周辺が切れてしまうなどの現象がおきます。[註1]
  • IEでBOXの周辺に、透過PNG画像を配置した場合は、透過PNG画像アルファチャンネル部分(陰影)が重なる現象がおきます。BOX構成により違いはありますが、正常なものは作れないでしょう。
    標準モード、互換モードにより少し違いはありますが、IE6.7では全体の大きさを偶数値にしますと消えます。
    IE8では完全に壊れ、修正画像を用いなければ直りません。
  • BOX構成でも、図のようにバラバラにしてアニメした場合は「画像が重なる現象」はおきません。但しマシン性能が悪い場合はキレイに動きません。隙が発生します。また中央に画像を配置した場合は消さなければなりません。処理速度が違うため隙が出来るからです。[註2]
  • 移動させないで表示した場合はあまり問題は出ないでしょう。但しフエード処理の場合は多くの問題がでます。

  • 透過PNG画像を周辺に配置した場合、IEでは動かせない、クロスブラウザは困難である。動いている時に「周辺透過PNG画像を表示させない」BOX構造ならば問題は起きません。
    [註1].テーブル構成の場合、DIVにTABLEをappend()出来るがTABLEにDIVをappend()出来ない。z-index操作で旨く作ることは可能だが、少々面倒です。
    [註2].IE「透過画像重なり」等は、要素に幅高さを設定すれば余り起きません。このためこの分離方式は簡単ですが、性能の良いマシンで作ると欠点が見え難いので要注意です。


    全ての不具合は、IEのバグが原因です。IEを対象外にすれば「問題は全く無く」全てが簡単です。記事にもなりません。


    問題のおきやすいopacity処理(フェード処理)

    SCRIPTの例

    
    opacity処理の例
    $("#item").animate({'opacity':1,'width':width_v,'height':height_v,'top':pos_Y,'left':pos_X},speed_v,function() {
    	//
    });
    
    //通常のfadeInであっても同じ、opacity処理に変わりなし
    $("#item").children("img").fadeIn(v_speed,function() {
    	//
    });
    

    • IEで陰影が重なる場所は同じです。陰影の無い普通のGIF画像は、重なっているのですが見た目判りません。これはBOXをどのように構成しても同じです。
    • IE6.7では全体の大きさを偶数値の寸法を与えると、重なり部分が無くなります。アニメ途中は早いので描画がスキップされますので見えません。IE8は別の方法をとります。
    • フェード処理の後に、「フィルター処理」の重なる部分に問題がおき易い。出来れば重なら無いように配置するか、alphaフィルターを削除するとほとんどは直る。
    • IEで陰影部分が欠けたり、フェード処理途中に真っ黒になる部分が出来た場合は、透過PNG画像が位置ズレしています。IEでは初期のCSSが適用されその後の変化に対応できない特性があります。該当部分を「入れ子」にして、逆方向から配置すると直ります。
    • そのほか画像の重なりなどで問題がおきたら、alphaフィルターの削除。または反対にalphaフィルターを処理する。それで直る場合もあります。
    • IE6では、陰影の重なりを完全に治すことは不可能です。アニメ終了時に少し見える場合があります。但し余り判らない様にすることは可能。程なくIE6対応しなくても良くなるでしょう。
    • IE6.7 早くなくなってくれ。
    AlphaImageLoaderフィルター関連のバグは、寸法を与えると直る場合が多い。

    IEのバグの多くは、実寸値を与えると直るものが多いようですが、中々、%の指定も使用せざるを得なく現実的では無い。バグメーカーを作る側の問題です。


    IEのalphaフィルター

    画像やBOXなどに透明度を与えるには、通常はCSSで下記の様に指定します。

    CSS

    
    -ms-filter: "alpha( opacity=50 )"; 
    filter: alpha( opacity=50 ); 
    opacity: 0.5;
    

    IEのalphaフィルターの弊害


    そもそも、IEではJavaScript互換のJSscript(マイクロソフト開発の専用スクリプト)を使用しているのが原因です、誰しも何の意識をせずにJavaScriptを使用しますが、IEの内部では別のJavaScriptが動いているわけです。
    また、透明度処理にはIE独自のalphaフィルターが使用されています。大変な粗悪品です。
    alphaフィルターなるもの色々な弊害を与えます。フィルターを併用すると壊れたり。副作用だらけの劇薬であります。
    通常はあまり意識はしないでしょうが、jqueryなどで処理する途中に問題を起こします。



    .

    IEのフィルターの問題と解決方法

    抽象的ですが、次に対処方法を記述します。

    • 「AlphaImageLoaderフィルター」を処理した画像のリンクが壊れる。対処方法としては、リンク専用のBOXなど上に配置する。javasctiptのリンクをあたえるなど、、positionを与えれば直るとも言いますが、概に与えている場合が多い。
    • 「AlphaImageLoaderフィルター」を処理した画像などをアニメすると中の部分が消失する。中の寸法をもう一度設定すると直る場合が多い。
    • alphaフィルターにより「画像に白い点」が出る場合は、画像のalphaフィルターを除去する。(Fadeアニメ処理中は直らない、アニメ処理が終了してから処理する)
    • IE8専用の画像を配置する。重なる箇所は同じですので重なる箇所のアルファチャンネル部分をカットした画像を配置して修正する。
    • IE8でフェード処理を行うと、汚くなったり非常に重くなったりする(IE8のみの現象、処理すべき対象を認識していない。)場合は、z-indexを与える。[註3]
      z-indexは、IE8であることを判定させて、IE8の場合のみ与えるほうが良い。IE8以外では関連する層に全てz-indexを付けなければならなくなる。

    [註3] 通常IDなどで処理対象を指定すると、「入れ子」の中の部分も対象となるはずですが、IE8の場合それを認識しない。z-indexを与えると認識する。このような状況ではかなり気を配らないといけません。


    その他のalphaフィルターの影響。

    • 2重のフィルター処理は壊れることが多いので、2重のフィルター処理はしない。
    • alphaフィルターの施したBOXに文字を直接書くと透明になる。対処方法としては、新たなDIV要素など配置してその中に文字を書く。
    • alphaフィルターの影響を防ぐため、一旦「影響を受ける中の部品を非表示」にする。(非表示に出来る場合のみ。非表示の部分は処理されないのを利用)
    • 「透過PNG画像ボタン」など使用したい場合は、ボタン以外のフェード処理後、appned()して付け加える。
    • alphaフィルター処理したBOXにappned()できない場合は、alphaフィルターを除去する。(IEの場合、まれに起きるときがある。appned()なってるが透明に変換されて見えなくなる。)
    • IE のフェード処理で「画像など壊れ」の修復には、alphaフィルターを除去する。または画像が重ら無ないようする。alphaフィルターを除去する階層に変化が無い場合は、その親の階層を処理する。
      (IE8の場合キチンとしたつもりでも中々旨く行かない、この方法は結構有効かも知れない)
    • IE の透過PNG画像の配置如何では、重なり箇所が出て汚くなる。対処方法としては、寸法の是正、画像の取替えをする。または状況によりテーブル構成を使用する。透過PNG画像に寸法を与えると直ることも多い。
    • IE 早くなくなってくれ。
    alphaフィルター関連のバグは、alphaフィルターを除去すると直る場合が多い。

    HTML IE8の専用修正画像を読み込む。

    
    //IE8は画像が違うので専用のCSSを読み込むこと
    
    <!--[if IE 8]>
    <link rel="stylesheet" href="css/pops-ibox-c2_ie8.css" type="text/css" media="all" />
    <![endif]-->
    

    HTML 文字が透明になるのを守る。

    
    #text_box {
    filter: alpha( opacity=50 ); 
    opacity: 0.5;
    background-color:#FF0000;
    }
    //IEで半透明文字になる
    <div id="text_box">おいらは半透明文字だ</div>
    
    //直ぐ上に配置できる場合
    <div id="text_box"></div>
    <div id="text_box2">おいらは文字だ</div>
    
    //直ぐ上に配置でき無い場合
    <div id="text_box_wrap">
    <div id="text_box"></div>
    <div id="text_box2">おいらは文字だ</div>
    </div>
    
    どちらにしろ面倒なことだ
    

    SCRIPT 通常 alphaフィルター除去の例1

    
    //通常
    $("#item").fadeIn(v_speed,function() {
    	//alphaフィルター除去 通常は画像も処理する
    	$("#item").css({'filter':'none'});
    });
    
    //IE8が認識しない場合
    $("#item").children("img").fadeIn(v_speed,function() {
    	//IE8はこちらしか処理しない時がある
    	$("#item").css({'filter':'none'});
    	//画像のalphaフィルター除去
    	$("#item").children("img").css({'filter':'none'});
    });
    
    //IE8が認識しない場合2
    #itemの親が#item_wrapであると仮定して
    $("#item").children("img").fadeIn(v_speed,function() {
    	//IE8の場合のみ
    	$("#item_wrap").css({'filter':'none'});
    
    });
    ここまでしなければならないのは異常である
    -----------------------------------------------
    
    #itemの中にボタンも入っていると想定の場合
    
    //ボタンも一緒にfadeIn、当たり前の処理が、効かない時もある
    //通常処理
    $("#item").fadeIn(v_speed,function() {
    	//alphaフィルター除去
    	$("#item").css({'filter':'none'});
    	$("#item_bottun").css({'filter':'none'});
    });
    
    //逆転の発想、ボタンが変だ、先にボタンを処理する、有効の場合もある
    $("#item_bottun").css({'opacity':'1.0'});
    //通常処理
    $("#item").fadeIn(v_speed,function() {
    	//alphaフィルター除去
    	$("#item").css({'filter':'none'});
    });
    

    SCRIPT 中の画像などが無くなるとき、IE6に多い

    
    #item_nanikaは中の要素、DIVだったり色々だ、
    fadeIn前に高さが実寸で規定されていな場合などの時発生
    
    //通常処理
    $("#item").fadeIn(v_speed,function() {
    	//fadeInなりの処理が終了したら、直ぐに対象の大きさをCSSで決める
    	//原因は高さの場合が圧倒的
    	$("#item_nanika").css({'width':300,'height':200});
    });
    

    SCRIPT PNG透過ボタンを守る。

    
    #itemの中に#bottunボタンがありfadeInで黒くなると仮定する
    
    一旦消す方法
    //一旦消す
    $("#bottun").css({'display':'none'});
    //通常処理
    $("#item").fadeIn(v_speed,function() {
    	//fadeInなりの処理が終了したら表示する
    	$("#bottun").css({'display':'block'});
    });
    
    新たにボタンをappendする方法
    //通常処理
    $("#item").fadeIn(v_speed,function() {
    	//fadeInなりの処理が終了したら表示する
    	$("#item").append('<div id="bottun">オラボタンダ</div>');
    });
    
    考えれば、色々な方法はあると思う
    

    どのように関連しているか判らない場合もあり、怪奇としか言い様が無い。
    通常の処理で旨く行かない場合は、何でも試すほか無い。


    SCRIPT 黒い点が出る alphaフィルター除去の例2

    
    //黒い点が出る1
    $("#item").children("img").fadeIn(v_speed,function() {
    	//画像のalphaフィルター除去
    	$("#item").children("img").css({'filter':'none'});
    });
    
    //黒い点が出る2
    $("#item").fadeIn(v_speed,function() {
    	//画像のalphaフィルター除去
    	$("#item").children("img").css({'filter':'none'});
    });
    

    IE8の問題と解決方法

    IE8は異常である

    IE8の場合、抜きんじて、alphaフィルター障害が多いです。かなり時間をかけて修正は可能ですが、かなりの気力と労力が必要です。あまり時間がかかる場合はあきらめたほうが賢明です。

    • IE8の場合フェード処理を極力避ける事。alphaフィルターに起因しているのは確かですが、フィルターを削除しようとしても反応しない場合が多い。
      z-indexも効かない場合もある。こんな場合は逆に、親の層からalphaフィルター除去を行うとか、通常行わないことも実行する。
    • alphaフィルターが除去できなく、opacity 0.999で処理したなんて言うこともある。発想を変えてみる。
    • 時間をかけて、色々な方法を考えて実行してみる。または併用する。
    • 他の人のものを参考にするのも一つの方法ですが、BOXの構造が少し違っただけで対応しない場合もある。
    • 時間の無駄。あきらめる。
    • IE8 早くなくなってくれ。

    alphaフィルターの有無を知る

    不具合のおきる部材の、「alphaフィルター」の「有無」を知る事も大切です。jQueryの場合CSSを調べれば良い。結果をどこかに表示して確認すればすこしは参考になる。
    私の場合は、画面のどこかに「テキストを表示させるDIV」を作っておき、そこに色々表示させて「デバック」の代用にしている。

    
    var filter_txt=$("#buhin").css("filter");
    //どこかにテキスト表示用のDIVを作っておき、そこに表示させる
    $("#text_view").text(filter_txt);
    
    ここでは
    filterが無ければ none が表示される
    

    最大の対処方法は、IEに対応しないことです。



[ この記事のURL ]


タグ:CSS , jquery , memo , web

 

ブログ記事一覧

年別アーカイブ一覧



[1]