マスターページのCSSをJavaScriptで置換しても正しく動作しない - ASP.NET

マスターページのCSSをJavaScriptで置換しても正しく動作しない現象について紹介します。

概要

こちらの記事の方法でJavaScriptを利用してCSSファイルを動的に置き換えることができます。
ASP.NET アプリケーションでマスターページを利用している場合、同じコードを利用してもうまく動作しない場合があります。 この記事では、ASP.NET アプリケーションでマスターページのCSSを動的に置換する方法を紹介します。

動作する例

マスターページとWebフォームが同じディレクトリにある場合は、こちらの記事の方法でCSSファイルを変更できます。

コード

ASP.NET Webアプリケーションプロジェクトを作成し、下記のマスターページ、CSS、Webフォームを作成します。
Style1.css
body {
  background-color:#d8d8d8;
}

.frmae1{
  border:1px solid #ff6a00;
  width:320px;
}
Style2.css
body {
  color:#FFFFFF;
  background-color: #4b4b4b;
}

.frmae1 {
  color: #FFFFFF;
  border: 1px solid #ffe346;
  width: 320px;
}
Site3.Master
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site3.master.cs" Inherits="ChangeCss.Site3" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <link id="PageStyleSheet" rel="stylesheet" href="Style1.css" />
    <script type="text/javascript">
        function changeStyleSheetMP() {
            var elem = document.getElementById("PageStyleSheet");
            elem.href = "Style2.css";
        }
    </script>

    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
            </asp:ContentPlaceHolder>
        </div>
    </form>
</body>
</html>
WebForm3.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Site3.Master" AutoEventWireup="true" CodeBehind="WebForm3.aspx.cs" Inherits="ChangeCss.WebForm3" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <p>WebForm3です。</p>
    <div class="frmae1">
        枠1です。
    </div>
    <p><a href="javascript:changeStyleSheetMP();">スタイルシート変更(WebFormリンク)</a></p>
</asp:Content>

解説

マスターページとWebフォームが別のファイルですが、動作はこちらの記事の方法で紹介しているJavaScirptのコードを実行しています。

実行結果

上記のASP.NETアプリケーションを実行します。下図のページが表示されます。


ページ下部の[スタイルシートを変更]のリンクをクリックします。JavaScriptが実行され、スタイルシートが変更され、ページのデザインが変わります。

うまく動作しない例

Webフォームとマスターページのフォルダが違う場合にはうまく動作しません。

コード

先のプロジェクトにWebフォームをサブフォルダに追加します。
今回は "folder" サブフォルダ内に "WebForm3f.aspx" Webフォームを作成します。
folder/WebForm3f.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Site3.Master" AutoEventWireup="true" CodeBehind="WebForm3f.aspx.cs" Inherits="ChangeCss.folder.WebForm1f" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <p>WebForm3です。</p>
    <div class="frmae1">
        枠1です。
    </div>
    <p><a href="javascript:changeStyleSheetMP();">スタイルシート変更(WebFormリンク)</a></p>
</asp:Content>

実行結果

プロジェクトを実行し、Webフォームを表示します。下図のページが表示されます。


ページ下部の[スタイルシートを変更]のリンクをクリックします。JavaScriptが実行されますが、スタイルシートは反映されず、スタイルが設定されていない状態になってしまいます。

原因

Webフォームの配置位置が基準になるため、マスターページと同じディレクトリにあるCSSファイルの参照が一つ上のフォルダとなっています。
代入して置き換えると、フォルダの位置関係が変わってしまい、正しい位置のCSSファイルを参照できなくなってしまうためです。
folder/WebForm3f.aspx のページ表示時のソース
<!DOCTYPE html>

<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>

</title><link id="PageStyleSheet" rel="stylesheet" href="../Style1.css" />
    <script type="text/javascript">
        function changeStyleSheetMP() {
            var elem = document.getElementById("PageStyleSheet");
            elem.href = "Style2.css";
        }
    </script>

    
</head>
<body>
    <form method="post" action="./WebForm3f.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="2TRXph0sPpOoJ9hxd20u/jKWNva8SivJIV+cJ0b0E0PI7U8Gm+PTY/tlYgayrCHR70+/Bm9b3o+wpxoAmWcfuYAO8PIQh94Q4YVT7IGO7TY=" />
</div>

<div class="aspNetHidden">

	<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="679A48C9" />
</div>
        <div>
            
    <p>WebForm3です。</p>
    <div class="frmae1">
        枠1です。
    </div>
    <p><a href="javascript:changeStyleSheetMP();">スタイルシート変更(WebFormリンク)</a></p>

        </div>
    </form>
</body>
</html>

対処法

方法1 : 置換する内容を変更する

elem.href = "Style2.css"elem.href = "../Style2.css" に変更します。
  <script type="text/javascript">
    function changeStyleSheetMP() {
      var elem = document.getElementById("PageStyleSheet");
      elem.href = "../Style2.css";
    }
  </script>

この方法では、サブフォルダ内にWebフォームがある場合は動作しますが、 Webフォームがアプリケーションルートフォルダにある場合や、サブサブフォルダにある場合は正しく動作しなくなってしまいます。

方法2 : replace で置換する

JavaScriptのreplace関数を利用して、ファイル名を置換する方法です。

コード

ASP.NET Webアプリケーションを作成し、下記ファイルを作成します。
Site4.Master
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site4.master.cs" Inherits="ChangeCss.Site4" %>
<!DOCTYPE html>
<html>
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <link id="PageStyleSheet" rel="stylesheet" href="Style1.css" />
    <script type="text/javascript">
        function changeStyleSheetMP() {
            var elem = document.getElementById("PageStyleSheet");
            elem.href = elem.href.replace("Style1.css","Style2.css");
        }
    </script>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
            </asp:ContentPlaceHolder>
        </div>
    </form>
</body>
</html>
WebForm4.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Site4.Master" AutoEventWireup="true" CodeBehind="WebForm4.aspx.cs" Inherits="ChangeCss.WebForm4" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <p>WebForm4です。</p>
    <div class="frmae1">
        枠1です。
    </div>
    <p><a href="javascript:changeStyleSheetMP();">スタイルシート変更(WebFormリンク)</a></p>
</asp:Content>
folder/WebForm4f.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Site4.Master" AutoEventWireup="true" CodeBehind="WebForm4f.aspx.cs" Inherits="ChangeCss.folder.WebForm4f" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <p>WebForm4です。</p>
    <div class="frmae1">
        枠1です。
    </div>
    <p><a href="javascript:changeStyleSheetMP();">スタイルシート変更(WebFormリンク)</a></p>
</asp:Content>

実行結果

上記のプロジェクトを実行し"WebForm4.aspx" Webフォームを表示します。下図のページが表示されます。


[スタイルシートを変更]リンクをクリックします。スタイルシートが変更され、デザインが変わります。


続いてサブフォルダにある、"folder/WebForm4f.aspx" Webフォームを表示します。下図のページが表示されます。


[スタイルシートを変更]リンクをクリックします。サブフォルダのWebフォームでもスタイルシートが正しく変更され、デザインが変わります。


マスターページを利用した場合での動的なスタイルシートファイルの置き換えが実装できました。
このページのキーワード
  • マスターページのCSSをJSで置換しても正しく動作しない
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2021-03-16
作成日: 2021-03-16
iPentec all rights reserverd.