ASP.NET の ListView のアイテム内に表示された画像を jQuery でエフェクトしてみる

 

jQuery を使ってみようと思ったきっかけ

私は趣味で ASP.NET を使っている。趣味で ASP.NET をどう使うんだ?と不思議に思うところもあるかもしれないが、ホームシアター用の動画管理Webアプリ「MovieJukeBox」を作成するということで、2年前から ASP.NET を使い始めた。42歳のことである。言語は VB。C# にも挑戦したいけどちょっと難しいそうなので、VBオンリーでやってる。jQuery は JavaScript の便利なサンプルをまとめたライブラリらしい?けど、私は JavaScript のコーディングは、ほぼ未経験。

ASP.NET には MVC とかいうのもあるらしく、2014年の今、こうして ASP.NET の Webフォームでアプリを作ろうというのは、世間の状況からすると周回遅れ、いや10週遅れみたいなものらしい。5年前の2009年には、@ITで「ASP.NETプログラマーのためのjQuery入門」の連載が開始されている。

個人で利用する MovieJukeBox で、パフォーマンスに不満はない。新しいOS(Windows 8.1 Update)、新しいブラウザ(Internet Explorer 11)でもちゃんと動く。IIS8.5、.NET4.5でも動く。10週遅れだろうが、100周遅れだろうが、現時点では、まだ切り捨てられていないので、開発・手直しできる環境だ。

ただ、そうは言っても、jQuery でインタラクティブなページとかの記事を目にすると気になる。気にしないふりをしても気になる。

ということで、ASP.NET VB Webフォーム で jQuery を使用し、インタラクティブなページ作成の勉強をしようと思った。

あ、Webフォーム で jQuery 使うくらいなら、ASP.NET MVC + jQuery やれということかもしれないが、ASP.NET MVC わからんので、今はパス。

 

まずはWebフォームで jQuery を使って画像を拡大してみる

 

jQuery のライブラリ入手とWebサイトへの配置

jQueryのライブラリはこの記事を書いてる時点で最新の「2.1.1」を使用。下記からダウンロードし、フォルダ「Scripts」を作成し、そこへ jquery-2.1.1.min.js を配置した。

(入手先)

Download jQuery | jQuery
http://jquery.com/download/

 

内容

  • id が div1 の div に asp:image の画像と img の画像を配置。両画像とも Class を imagePoster とした。
  • id が div2 の div に asp:image の画像と img の画像を配置。両画像とも Class を imagePoster とした。
  • div1 には aspx に静的に埋め込んだスクリプトを割り当てる
    id が div1 の div 内の Class に imagePoster が割り当てられているimgタグにのみ、jQuery の animate を使って、3秒間で画像を300x400に拡大する。
    スクリプトは画像よりも後ろに埋め込まないと、エフェクトが適用されないので注意。
  • div2 には vb から ClientScript.RegisterStartupScript を使って動的に埋め込んだスクリプトを割り当てる。ClientScript.RegisterStartupScript でスクリプトを埋め込むと画像よりも後ろにある、</form>の直前にスクリプトが埋め込まれるのでエフェクトが適用される。
    02
    ClientScript.RegisterClientScriptBlock だと、画像よりも前にある<form>の直後にスクリプトが生成されてしまい、エフェクトが適用されないので使用しない。
    01
    w(幅)、h(高さ)、s(エフェクトスピード)の3つをテキストボックスから取得し、動的にスクリプトに埋め込む。

    (参考)
    @IT:.NET TIPS [ASP.NET]ページにJavaScriptを埋め込むには? - C# VB.NET Webフォーム
    http://www.atmarkit.co.jp/fdotnet/dotnettips/160regscript/regscript.html

 

結果

ASP.NET Webフォームで jQuery を使って画像を拡大してみる

 

ソース

TestJQuery.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="TestJQuery.aspx.vb" Inherits="TestJQuery" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script src="./scripts/jquery-2.1.1.min.js" type="text/javascript"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="div1">
        W<asp:TextBox ID="TextBoxW" runat="server" Columns="4">300</asp:TextBox>
        H<asp:TextBox ID="TextBoxH" runat="server" Columns="3">400</asp:TextBox>
        S<asp:TextBox ID="TextBoxS" runat="server" Columns="4">5000</asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="" />
        <br />
        <asp:Image ID="Image1" runat="server" ImageUrl="~/Images/zTP6q3wIkOVCTKMYZ8SfXKRZPvs.jpg" CssClass="imagePoster" />
        <img alt="" class="imagePoster" src="Images/zTP6q3wIkOVCTKMYZ8SfXKRZPvs.jpg" />
    </div>
    <div id="div2">
        <asp:Image ID="Image2" runat="server" ImageUrl="~/Images/zTP6q3wIkOVCTKMYZ8SfXKRZPvs.jpg" CssClass="imagePoster" />
        <img alt="" class="imagePoster" src="Images/zTP6q3wIkOVCTKMYZ8SfXKRZPvs.jpg" />
    </div>
    </form>
    <script type="text/javascript">
        $('#div1 img.imagePoster').animate({ width: 300, height: 400 }, 3000);
    </script>
</body>
</html>

スクリプトを埋め込むイベントは「Page_Load」でOKみたい。その他OKだったイベントはコメント化しておいた。

TestJQuery.aspx.vb

Partial Class TestJQuery
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        Dim w As String = TextBoxW.Text
        Dim h As String = TextBoxH.Text
        Dim s As String = TextBoxS.Text
        Dim strScript As String = "<script type=""text/javascript""> $('#div2 img.imagePoster').animate({ width: " + w + ", height: " + h + " }, " + s + "); </script>"
        ClientScript.RegisterStartupScript(Me.GetType(), 1, strScript)
        'ClientScript.RegisterClientScriptBlock(Me.GetType(), 1, strScript)
    End Sub

    Protected Sub Page_LoadComplete(sender As Object, e As EventArgs) Handles Me.LoadComplete
        'Dim w As String = TextBoxW.Text
        'Dim h As String = TextBoxH.Text
        'Dim s As String = TextBoxS.Text
        'Dim strScript As String = "<script type=""text/javascript""> $('#div2 img.imagePoster').animate({ width: " + w + ", height: " + h + " }, " + s + "); </script>"
        'ClientScript.RegisterStartupScript(Me.GetType(), 1, strScript)
    End Sub


    Protected Sub form1_Init(sender As Object, e As EventArgs) Handles form1.Init
        'Dim w As String = TextBoxW.Text
        'Dim h As String = TextBoxH.Text
        'Dim s As String = TextBoxS.Text
        'Dim strScript As String = "<script type=""text/javascript""> $('#div2 img.imagePoster').animate({ width: " + w + ", height: " + h + " }, " + s + "); </script>"
        'ClientScript.RegisterStartupScript(Me.GetType(), 1, strScript)
    End Sub

    Protected Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load
        'Dim w As String = TextBoxW.Text
        'Dim h As String = TextBoxH.Text
        'Dim s As String = TextBoxS.Text
        'Dim strScript As String = "<script type=""text/javascript""> $('#div2 img.imagePoster').animate({ width: " + w + ", height: " + h + " }, " + s + "); </script>"
        'ClientScript.RegisterStartupScript(Me.GetType(), 1, strScript)
    End Sub

    Protected Sub form1_PreRender(sender As Object, e As EventArgs) Handles form1.PreRender
        'Dim w As String = TextBoxW.Text
        'Dim h As String = TextBoxH.Text
        'Dim s As String = TextBoxS.Text
        'Dim strScript As String = "<script type=""text/javascript""> $('#div2 img.imagePoster').animate({ width: " + w + ", height: " + h + " }, " + s + "); </script>"
        'ClientScript.RegisterStartupScript(Me.GetType(), 1, strScript)
    End Sub

    Protected Sub Image2_Load(sender As Object, e As EventArgs) Handles Image2.Load
        'Dim w As String = TextBoxW.Text
        'Dim h As String = TextBoxH.Text
        'Dim s As String = TextBoxS.Text
        'Dim strScript As String = "<script type=""text/javascript""> $('#div2 img.imagePoster').animate({ width: " + w + ", height: " + h + " }, " + s + "); </script>"
        'ClientScript.RegisterStartupScript(Me.GetType(), 1, strScript)
    End Sub

End Class

 

次に ListView のアイテム内に表示された画像を jQuery でエフェクトしてみる

 

実施内容

ListView のアイテム内に動的に描画された画像に、jQuery でエフェクトをかけてみる。画像のサイズ変更に加えて、「jqueryrotate」というライブラリを使用し画像をマウスオーバーで回転させてみる。jQuery マウスオーバーで検索したら、jqueryrotate が下記で紹介されていた。

いろんな画像をクルックルクルックル回すイケイケjQueryプラグイン 「jQueryRotate」|わざログ| うずまきブログ| 名古屋のホームページ制作/印刷物デザイン 株式会社うずまきデザイン
http://uzmk.jp/blog/tips/entry-229.html

 

jqueryrotate の入手と配置

(入手)

jqueryrotate - jQuery plugin that rotate images (and animate them) by any angle - Google Project Hosting
https://code.google.com/p/jqueryrotate/

入手した「jQueryRotateCompressed.js」をScriptsフォルダへ入れる。
07

 

結果

ウェイト時間を設けないと意図したリサイズ動作にならない。1200ミリ秒以上のウェイトをかけると意図したリサイズ動作になる。またマウスオーバーで画像が時計回りに、マウスアウトで反時計回りに回転できた。

ASP.NET の ListView のアイテム内に表示された画像を jQuery でエフェクトしてみる

 

特記事項

 

jQuery の適用をウェイトさせる

SQL Server の FILESTREAM で画像を保存しているが、うちの開発環境では、サンプルのような画像読み込みに数秒の時間が必要だ。ListView の画像表示が完了しないまま、jQuery の画像サイズ変更が適用されると、最小サイズから変更後指定サイズへのサイズ変更となってしまう。そこで、初期表示サイズの画像が表示されるまでウェイトして、変更後指定サイズへリサイズするようにしてみた。ウェイト時間はテキストボックスから指定できるようにする。

ウェイトさせるためのスクリプト
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <style></style>
    <script type="text/javascript">
        function loopWait(timeWait){
            var timeStart = new Date().getTime();
            var timeNow = new Date().getTime();
            while( timeNow < (timeStart + timeWait ) )
            {
                timeNow = new Date().getTime();
            }
            return;
        }
    </script>
</head>

 

jQuery ライブラリのインポート

AJAX Contorol Toolkit の ScriptManager を配置しているので、これを使ってインポートする。マスターページに ScriptManager を配置している場合は便利じゃないかな。
08

id名を固定化する

ASP.NET のコントロールのプロパティ「ClientIDMode」を Static にしないと、各コントロールの id名 は html生成時に 自動的に連番のようなものが加算されてしまう。今回は asp:image に Class=imagePoster を割り当てたので、Class指定だけで jQuery はエフェクト対象のコントロールを特定できるが、参考にメモ。

Static にすると id名 は固定される。ListView の各アイテム内のコントロールには、一律同じ id名 が付与される。ListView の各アイテム内のコントロールに同じ id名を付与して、一律に jQuery から参照させる場合は Static がいいのかな。
0506

Static にしないと id名は連番のようなものが加算されて付与される。ListView の各アイテム内のコントロールには、すべて異なる id名 が付与される。ListViewの何個目のアイテムだけに適用するとかの場合は、Static にしない感じかな。
0506

適用先の検索方法はいろいろあるみたいなので、もう少し勉強が必要かな。

 

(参考)

ASP.NETプログラマーのためのjQuery入門 - @IT
http://www.atmarkit.co.jp/fdotnet/special/jquery/jquery_02.html

RIAへの第一歩としてのjQuery (1/3):CodeZine
http://codezine.jp/article/detail/6880

 

ソース

 

ListViewPosterJQ.aspx

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ListViewPosterJQ.aspx.vb" Inherits="ListViewPosterJQ" %>

<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="asp" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <style></style>
    <script type="text/javascript">
        function loopWait(timeWait){
            var timeStart = new Date().getTime();
            var timeNow = new Date().getTime();
            while( timeNow < (timeStart + timeWait ) )
            {
                timeNow = new Date().getTime();
            }
            return;
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        <asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Path="./scripts/jquery-2.1.1.min.js" />
                <asp:ScriptReference Path="./Scripts/jQueryRotateCompressed.js" />
            </Scripts>
        </asp:ToolkitScriptManager>
    
        W:<asp:TextBox ID="TextBoxW" runat="server" Columns="4">150</asp:TextBox>
        H:<asp:TextBox ID="TextBoxH" runat="server" Columns="4">300</asp:TextBox>
        W:<asp:TextBox ID="TextBoxJW" runat="server" Columns="4"></asp:TextBox>
        H:<asp:TextBox ID="TextBoxJH" runat="server" Columns="3"></asp:TextBox>
        S:<asp:TextBox ID="TextBoxJS" runat="server" Columns="4"></asp:TextBox>
        Wait:<asp:TextBox ID="TextBoxWait" runat="server" Columns="4"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="" />
        <br />
    
        <asp:ListView ID="ListView1" runat="server" DataKeyNames="ID" DataSourceID="SqlDataSource1" GroupItemCount="10">
            <AlternatingItemTemplate>
                <td runat="server" style="vertical-align: top">ID:
                    <asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' />
                    <br />STREAMID:
                    <asp:Label ID="STREAMIDLabel" runat="server" Text='<%# Eval("STREAMID") %>' Visible="False" />
                    <br />TMDbID:
                    <asp:Label ID="TMDbIDLabel" runat="server" Text='<%# Eval("TMDbID") %>' />
                    <br />aspect_ratio:
                    <asp:Label ID="aspect_ratioLabel" runat="server" Text='<%# Eval("aspect_ratio") %>' />
                    <br />file_path:
                    <asp:Label ID="file_pathLabel" runat="server" Text='<%# Eval("file_path") %>' Visible="False" />
                    <br />height:
                    <asp:Label ID="heightLabel" runat="server" Text='<%# Eval("height") %>' />
                    <br />width:
                    <asp:Label ID="widthLabel" runat="server" Text='<%# Eval("width") %>' />
                    <br />
                    <asp:Image ID="Image2" runat="server" ImageUrl='<%# "imagePoster.aspx?ID=" + Convert.ToString(DataBinder.Eval(Container.DataItem, "ID")) + "&w=" + Convert.ToString(DataBinder.Eval(Container.DataItem, "w")) + "&h=" + Convert.ToString(DataBinder.Eval(Container.DataItem, "h")) %>' CssClass="imagePoster" />
                    <br /></td>
            </AlternatingItemTemplate>
            <EmptyDataTemplate>
                <table runat="server" style="">
                    <tr>
                        <td></td>
                    </tr>
                </table>
            </EmptyDataTemplate>
            <EmptyItemTemplate>
            <td runat="server" />
            </EmptyItemTemplate>
            <GroupTemplate>
                <tr id="itemPlaceholderContainer" runat="server">
                    <td id="itemPlaceholder" runat="server"></td>
                </tr>
            </GroupTemplate>
            <ItemTemplate>
                <td runat="server" style="vertical-align: top">ID:
                    <asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' />
                    <br />STREAMID:
                    <asp:Label ID="STREAMIDLabel" runat="server" Text='<%# Eval("STREAMID") %>' Visible="False" />
                    <br />TMDbID:
                    <asp:Label ID="TMDbIDLabel" runat="server" Text='<%# Eval("TMDbID") %>' />
                    <br />aspect_ratio:
                    <asp:Label ID="aspect_ratioLabel" runat="server" Text='<%# Eval("aspect_ratio") %>' />
                    <br />file_path:
                    <asp:Label ID="file_pathLabel" runat="server" Text='<%# Eval("file_path") %>' Visible="False" />
                    <br />height:
                    <asp:Label ID="heightLabel" runat="server" Text='<%# Eval("height") %>' />
                    <br />width:
                    <asp:Label ID="widthLabel" runat="server" Text='<%# Eval("width") %>' />
                    <br />
                    <asp:Image ID="Image1" runat="server" ImageUrl='<%# "imagePoster.aspx?ID=" + Convert.ToString(DataBinder.Eval(Container.DataItem, "ID")) + "&w=" + Convert.ToString(DataBinder.Eval(Container.DataItem, "w")) + "&h=" + Convert.ToString(DataBinder.Eval(Container.DataItem, "h")) %>' CssClass="imagePoster" />
                    <br /></td>
            </ItemTemplate>
            <LayoutTemplate>
                <table runat="server">
                    <tr id="Tr1" runat="server">
                        <td id="Td1" runat="server" style="">
                            <asp:DataPager ID="DataPager2" runat="server" PageSize="20">
                                <Fields>
                                    <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" />
                                    <asp:NumericPagerField ButtonCount="50" />
                                </Fields>
                            </asp:DataPager>
                        </td>
                    </tr>
                    <tr runat="server">
                        <td runat="server">
                            <table id="groupPlaceholderContainer" runat="server" border="0" style="">
                                <tr id="groupPlaceholder" runat="server">
                                </tr>
                            </table>
                        </td>
                    </tr>
                    <tr runat="server">
                        <td runat="server" style="">
                            <asp:DataPager ID="DataPager1" runat="server" PageSize="20">
                                <Fields>
                                    <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" />
                                    <asp:NumericPagerField ButtonCount="50" />
                                </Fields>
                            </asp:DataPager>
                        </td>
                    </tr>
                </table>
            </LayoutTemplate>
        </asp:ListView>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TESTConnectionString %>" SelectCommand="SELECT [ID], [STREAMID], [TMDbID], [aspect_ratio], [file_path], [height], [width], [iso_639_1], [vote_average], [vote_count],@w as w,@h as h FROM [TMDbPoster]">
            <SelectParameters>
                <asp:ControlParameter ControlID="TextBoxW" Name="w" PropertyName="Text" />
                <asp:ControlParameter ControlID="TextBoxH" Name="h" PropertyName="Text" />
            </SelectParameters>
        </asp:SqlDataSource>
    
    </div>

    </form>

    <script type="text/javascript">
        $("#groupPlaceholderContainer img.imagePoster").rotate({
            bind:
            {
                mouseover : function() {
                    $(this).rotate({
                        animateTo: 360
                    })
                },
                mouseout : function() {
                    $(this).rotate({
                        animateTo: 0
                    })
                }
            }      
        });
    </script>

</body>
</html>

 

ListViewPosterJQ.aspx.vb
Partial Class ListViewPosterJQ
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        Dim w As String = TextBoxJW.Text
        Dim h As String = TextBoxJH.Text
        Dim s As String = TextBoxJS.Text
        Dim Wait As String = TextBoxWait.Text
        Dim strScriptWait As String = "<script type=""text/javascript"">loopWait(" + Wait + "); </script>"
        Dim strScriptSize As String = "<script type=""text/javascript""> $('#groupPlaceholderContainer img.imagePoster').animate({ width: " + w + ", height: " + h + " }, " + s + "); </script>"
        If w = "" Or h = "" Or s = "" Or Wait = "" Then
        Else
            ClientScript.RegisterStartupScript(Me.GetType(), 1, strScriptWait)
            ClientScript.RegisterStartupScript(Me.GetType(), 2, strScriptSize)
        End If

    End Sub

End Class

 

今後

jQuery を利用して、MovieJukeBox をインタラクティブにしたいと思う。jQuery のことをまだわかっていないので、勉強し、公開されているライブラリを吟味して、MovieJukeBox をより良いものにできたらいいな。ますます映画を観ることよりもホームシアター環境の構築に走ってしまいそうだ。

jQuery 及び それを利用したライブラリの提供者へ感謝です。

コメント

このブログの人気の投稿

エアコン室外機のフロンガス銅管を覆うカバーを交換しました

ダブルクォーテーションで括られたCSVカ​ンマ区切りテキストファイルを SQL Server で Bulk Insert する方法

IKEAの鏡を壁に取り付ける