【问题标题】:Setting HTML tag attribute before load在加载之前设置 HTML 标签属性
【发布时间】:2018-09-15 01:55:39
【问题描述】:

我使用 cookie 来记住用户的偏好。基本上,我有一个左侧面板,可以使用按钮折叠或展开。当用户点击它时,我通过cookie记住它的状态。

现在我需要让页面的初始加载与 cookie 的内容保持同步,以防止它出现生涩的行为。

那是<body class="mini-navbar"> 中的类。此类是否存在取决于状态。

我拥有获取和设置 cookie 的所有方法。

我的问题是,如何在页面加载之前基于 cookie 动态添加/删除此类

【问题讨论】:

  • 您是否将类名存储在 cookie 中,以便当它为空时您决定从正文中删除该类,否则您将 cookie 中提到的类添加到正文元素中?
  • 不,它只是一个二进制 cookie。
  • 您使用的是 asp.net MVC 还是 WebForms?
  • 是asp.net MVC 5
  • 您可以查看我发布的答案。即使您在问题中提到了 JavaScript,我也展示了如何仅使用 C# 来实现您的结果。我也提供了一个仅 JavaScript 的解决方案。

标签: javascript html asp.net asp.net-mvc


【解决方案1】:

您可以使用带有 Razor 语法的服务器端代码或纯 JavaScript 来实现您的场景。为 cookie 混合 JavaScript 和服务器端代码有时会产生意想不到的结果,因此请选择纯服务器端方法或纯 JavaScript 方法。

我的示例中的二进制 cookie 称为 bodyStyle,它的值为 1 或 0。我正在创建一个持久性 cookie,该 cookie 将从今天起 30 天到期,并且将在您域中的页面上可用/持久。此外,您可以在创建 cookie 时添加一些条件检查或根据您的要求在两种方法中设置其值。

我使用 cookie 值添加到正文的自定义类是 miniNavBar

服务器端方法

body 标签通常会出现在共享视图中,因此将下面的 Razor 代码添加到共享视图中。

使用二进制 cookie 动态设置正文类的 C# Razor 代码

@{
    //set bodyStyle cookie based on some condition using a if statement as per your requirements
    Response.Cookies["bodyStyle"].Value = "1";
    Response.Cookies["bodyStyle"].Expires = DateTime.Now.AddMinutes(2);
}

<body class="@(Response.Cookies["bodyStyle"].Value == "1" ? "miniNavBar" : "")">

JavaScript 方法

下面的代码可以进入任何需要这个逻辑的视图,或者如果你想将它应用到所有视图,可以将它添加到共享布局视图中。

使用二进制 cookie 动态设置 body 类的 JavaScript 代码

<script type="text/javascript">

    //main cookie function that will contain your logic for creating the binary cookie
    function setBodyCookie() {
        //if perisistent cookie exists then do not create it         
        if (document.cookie.indexOf("bodyStyle=0") >= 0 || document.cookie.indexOf("bodyStyle=1") >= 0) {
               return;
        }

        //create body cookie if it does not exist
        //you can add an if statement here when creating a cookie based on your scenario
        var now = new Date();
        now.setTime(now.getTime() + 30 * 24 * 60 * 60 * 1000);//expire this in 30 days from now
        document.cookie = "bodyStyle=1;expires=" + now.toUTCString() + ";path=/";
    }

    $(document).ready(function () {
        //set binary cookie according to your requirements
        setBodyCookie();

        //add class to body if binary cookie has a value of 1
        if (document.cookie.indexOf("bodyStyle=1") >= 0) {
            $("body").addClass("miniNavBar");
        }
    });


</script>

如果您想避免闪烁,另一种 JavaScript 解决方案可能是将文档就绪事件代码放在标记中的正文标记之后,并删除您正在使用的原始文档就绪事件,如下所示。您会注意到准备好的文档没有在下面的代码中使用。

<body class="expandedNavBar">
<script>
            //set binary cookie according to your requirements
            setBodyCookie();

            //add class to body if binary cookie has a value of 1
            if (document.cookie.indexOf("bodyStyle=1") >= 0) {
                //remove all classes that are already there or just remove the
                //the ones you like to
                $("body").removeClass();
               //add your class now
                $("body").addClass("miniNavBar");
            }
</script>

另一个替代方法是您可以使用.hide 类来避免闪烁,因为在文档就绪事件中更改了正文类。这显示在下面的示例代码中。

<style>
   .hide{ visibility:hidden}
</style>
<script>
 $(document).ready(function () {
            //set binary cookie according to your requirements
            setBodyCookie();

            //add class to body if binary cookie has a value of 1
            if (document.cookie.indexOf("bodyStyle=1") >= 0) {
                $("body").removeClass("hide");//remove the hide class
                $("body").addClass("miniNavBar");
            }
        });
</script>
<body class="hide">

【讨论】:

  • 非常感谢@Sunil 提供示例代码。我正在使用客户端方法,这就是我已经得到的,但我看到的问题是,$(document).ready 似乎并没有首先发生。首先发生的是渲染&lt;body&gt; 所说的任何内容。因此,如果默认情况下(即在代码中)标签是&lt;body&gt;,那么面板首先展开,然后$(document).ready 将指示折叠(基于 cookie 的值)。或相反亦然。这会导致眨眼或抖动动作。如果在通过$(document).ready 渲染之前更新了正文标签,那么我认为它会修复它。
  • 如果您使用了我提供的服务器端代码,那么这个问题将得到解决。如果您想使用客户端方法,则始终将一个名为 .hide{ visibility:hidden} 的类添加到正文标记中。然后在文档就绪事件中,您可以使用$("body").removeClass("hide") 在二进制 cookie 逻辑之后删除此隐藏类
  • 作为我上一条评论的替代方法,将文档中的 Javascript 放置在脚本标记中,紧跟标记中的正文标记之后,以便在呈现正文之前执行。并从您的页面中删除文档就绪事件。
  • 非常感谢。这是非常好的主意。我按照您的建议使用了隐藏类,现在看起来整个页面重新加载而不是那个烦人的面板。这要好得多。我将您的答案标记为解决方案。
【解决方案2】:

如果您使用 javascript 设置 cookie,您可以将 javascript 放在部分并设置类(我使用 jquery 为例)

if(document.cookie // cookie name)
{ 
    $("body").addClass('mini-navbar'); 
}

或者如果你使用 php 或其他你可以写的东西:

<body `<?php echo $COOKIE['bodyClass']; ?> `>

【讨论】:

  • 感谢您的回复,但我不确定在哪里添加。我已经在 document.ready 中尝试过上面的 $("body").addClass('mini-navbar'); ,或者我什至尝试在 &lt;body&gt; 上使用 onload 事件,但仍然没有运气。
  • 你是如何设置cookie的?
  • 使用 jscript document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";。我想如果我能弄清楚如何在 mvc5 razor 中做一些类似于你的 php 示例的事情,可以解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
相关资源
最近更新 更多