部分脚本或常规 <script> 取决于请求类型

Posted

技术标签:

【中文标题】部分脚本或常规 <script> 取决于请求类型【英文标题】:Section Scripts or regular <script> depending on Request Type 【发布时间】:2016-11-04 15:39:42 【问题描述】:

我有一个场景,我想根据请求类型加载脚本。例如,假设我有这个代码:

@section scripts 
<script>
    $('#tabsContainer').InitializeTabs();
</scripts>

当我想加载整个页面时,这加载得很好。但是,我有一个用户也可以部分加载页面的东西。场景是这样的:

public ActionResult Page() 
if (Request.IsAjax()) return PartialView();
return View()

问题是,如果它被部分加载,脚本就不能工作,因为@section 脚本不能部分工作。如果我把它放在部分脚本之外,它不能在全视图下工作,因为我的脚本在底部,并且它试图在加载实际的 javascript 文件之前运行脚本。

我想知道实现这一点的好方法。我可以将我的脚本移动到页面顶部,这应该可以解决所有问题。我也可以有 2 个不同的脚本,但这可能意味着我必须编写两次相同的代码。

有没有人知道实现这个的好方法?也许是一个 html 助手,它根据请求类型在 @section scripts 或常规脚本标签中加载脚本?

基本上,写这个的正确方法是什么:

@if (!Request.IsAjaxRequest())

    <text>
    @section scripts
    
        <script>
            $(function () 
                $("#tabs").tabs();
            );
        </script>
    
    </text>

else

    <text>
        <script>
            $(function () 
                $("#tabs").tabs();
                ga('set', 'page', '/new-page.html'); // Update Google Analytics
            );
        </script>
    </text>

提前感谢您的帮助。

【问题讨论】:

脚本应该永远是部分的。将您的脚本放在视图或布局中 我不同意这种情况。当然,我同意他们应该几乎从不处于局部视图中。但是,有一个可以在PartialView中渲染的FullView,我觉得可能还可以吧?您能否在加载视图后定义另一种方式我可以 $('#tabs').Initialize() (无论是完整的还是部分的。除了我上面发布的方法之外)? 添加了一个例子来进一步说明我的观点。 【参考方案1】:

你可以简单地在 view() 中检查

@if (Request.IsAjaxRequest())

<script>
    alert('Partial view');
</script>

else

<script>
    alert('Main view');
</script>

【讨论】:

我知道,但我在帖子中声明我不希望有重复的脚本标签。【参考方案2】:

一个我没有机会测试的想法:在视图中存储一些关于请求是否是 ajax 请求的信息(例如在数据属性中),然后在您的脚本中测试该值并做相应的事情。

例如:

 <body data-isajaxrequest="@Request.IsAjaxRequest()">...</body>

然后是脚本:

$(function () 
    function InitializeTabs() 
        $("#tabs").tabs();
        if ($("body").data("isajaxrequest")) 
            // it's an ajax request
         else 
            // not an ajax request
            ga('set', 'page', '/new-page.html'); // Update Google Analytics
        
    

    $('#tabsContainer').InitializeTabs();
);

根据需要将逻辑放置在 cmets 所在的位置。实际脚本将进入完整视图。正如另一张海报所提到的,您不应该在局部视图中包含脚本。

【讨论】:

再一次,这需要我编写重复的脚本逻辑。 没有看到 InitializeTabs() 函数中有什么,这很难说。您可以将与 ajax 请求分开的逻辑分开并将其放在 if 中,然后将所有共同点放在 if 语句之外。根据您在帖子中写的内容,我更新了我的示例。那里没有重复的代码。 我认为这是有道理的,但是,问题仍然存在,如果它不是 Ajax 请求,则需要在 @section 脚本 中运行。我相信这更多是为了创建一个 MVC 助手,而不是 JS。 也许我误解了用例。我假设,无论它是否是 ajax 请求,您都希望加载完整视图,并且只有客户端逻辑 (JavaScript) 会有所不同。如果不是这种情况,那么我尝试的答案可能对您没有太大帮助。但是,如果是的话;将 JavaScript 移动到文件中,并将其包含在视图的脚本部分中,并保留视图上的数据属性。在文档准备好之前它不会加载,因为$(function () ...$(document).ready(...) 的简写。【参考方案3】:

您可以尝试使用本机 JavaScipt 方式来解决此问题:

var myFunction = function () 
   alert('myFunction called after 500ms.');
  // do a lot of stuff here


// and then call the function after the page is loaded
// let's supose an half second later:

setTimeout(myFunction, 500);

【讨论】:

以上是关于部分脚本或常规 <script> 取决于请求类型的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript_2

如何在 <script> 标记中的 html 上使用 json 脚本并在 <img src=???/> 中填充数据

XSS插入绕过一些方式总结

脚本标记中何时需要CDATA部分?

无法附加 <script> 元素

JS 部分基础内容总结