JavaScript与.Net MVC的一次纠结之旅

首先我想实现的效果是这样的:
这里写图片描述
在下拉列表中选择要添加的题型,下面根据我选择的题型动态的载入不同格式的编辑器,比如我选择单项选择题,下面的编辑器应该像图中那样,包含一个题干的编辑框和四个选项的编辑框,并且每个选项前有一个radio button来让我选择哪个是正确的答案。
每种类型的编辑器我都采用单独的partial view来实现。最终将根据题型将不同的编辑器视图载入下面的div标签中

<div id="addquestionarea">
</div>

自然而然的我想到了给下拉框的change事件绑定一个函数来动态改变这个div标签中的视图:

$(document).ready(function()
{
    $("#typeList").change(function () {
        changeQuestionEditor();
    });

});

在changeQuestionEditor()这个函数中,我用Ajax来请求部分视图。

function changeQuestionEditor() {
    var unitTestId = $("#unitTestId").val();
    $.ajax({
        url: '../SingleChoiceManager/Create',
        data: { unitTestId: unitTestId },
        type: "GET",

        async: false,
        dataType: "html",
        success: function (data) {
            $("#addquestionarea").empty();
            $("#addquestionarea").html(data);
        }
    });

愉快的写好代码后马上运行了一下,理想中是那样的,可是事实确是这样的:
这里写图片描述
发生了神马?我马上右键审查元素:
这里写图片描述
源文件里是这样的:

<!-- 配置文件 -->
<script type="text/javascript" src="/Scripts/ueditor1_4_3-utf8-net/ueditor.config.js"></script>
<!-- 编辑器源码文件 -->
<script type="text/javascript" src="/Scripts/ueditor1_4_3-utf8-net/ueditor.all.js"></script>
<script type="text/javascript" src="/Scripts/ueditor1_4_3-utf8-net/kityformula-plugin/addKityFormulaDialog.js" charset="UTF-8"></script>
<script type="text/javascript" src="/Scripts/ueditor1_4_3-utf8-net/kityformula-plugin/getKfContent.js" charset="UTF-8"></script>
<script type="text/javascript" src="/Scripts/ueditor1_4_3-utf8-net/kityformula-plugin/defaultFilterFix.js" charset="UTF-8"></script>
<!-- 自定义 -->
<script type="text/javascript" src="~/Scripts/addQuestion.js" charset="utf-8"></script>
<script src="~/Scripts/SingleChoiceManager/createSingleChoice.js"></script>


<!-- 层叠样式表 -->
<link href="~/Content/addquestion.css" rel="stylesheet" type="text/css" />
<!-- 加载编辑器的容器 -->

我的JavaScript都被狗吃了么?!!

然后我发现,只要把

$("#addquestionarea").html(data);

改为

document.getElementById("addquestionarea").innerHTML = data;

引用的外部JavaScript就又重新出现了,原因不明,有知情者烦请不吝赐教。

虽然引用的外部JavaScript在审查元素时都能看到了,但是似乎依然没有执行js

然后百般求索,我发现了下面这篇博客:
IE 和 Firefox 可以通过特定方法使 innerHTML 方法载入的 SCRIPT 标签中的 JavaScript 代码在页面加载后也可以执行
里面说“所有浏览器中,默认情况下通过 innerHTML 方法动态插入到页面中的 SCRIPT 标签中的脚本代码均不能被执行。”
楼主针对IE和Firefox提出了两种方法解决这个问题:

  1. IE:给SCRIPT 元素加上 defer 属性可以让脚本延迟执行
    这真是简单实用啊,刚准备尝试,不小心看到了这句话“Chrome Safari Opera 不支持 defer 属性”,果然业界良心啊!有木有!!
  2. Firefox:先把div标签从文档树上拿下来,把包含局部页面的html通过innerHTML或 JQuery的.html()放进去,然后再重新把div标签挂到文档树上。
    这个似乎也不错,于是又一阵乱试,最后还是没有搞定。

于是决定静下心来把楼主的文章看完,到结尾的时候,楼主语重心长的说道:
“上面提到的 IE 及 Firefox 中使通过 innerHTML 方法动态插入的 SCRIPT 元素中脚本执行的方法均比较特殊,是利用了浏览器的 Bug,或者是利用了浏览器提供的特性。而 innerHTML 方法只是用来插入 HTML 代码,并不能使其中包含的脚本代码执行。
为了达到最好的兼容性,应避免利用浏览器特性及 Bug 使 innerHTML 插入的 SCRIPT 中的代码执行。所以上述 IE 和 Firefox 中的方法不可行。同时这种做法具有安全隐患。
对于可控来源的动态脚本,使用 createElement 创建 SCRIPT 元素并追加至页面的文档树中,以保证动态脚本的执行。”

最后一句话又给了我一丝希望!

然后我把代码改成了酱紫:

function changeQuestionEditor() {
    var unitTestId = $("#unitTestId").val();
    $.ajax({
        url: '../SingleChoiceManager/Create',
        data: { unitTestId: unitTestId },
        type: "GET",

        async: false,
        dataType: "html",
        success: function (data) {
            addAllScripts();
            $("#addquestionarea").empty();
            $("#addquestionarea").html(data);
        }
    });    
}

其中的addAllScripts()方法用来将所有的JavaScript追加到文档中,代码如下:

function addAllScripts()
{
    var head = document.getElementsByTagName("head")[0];

    var script1 = document.createElement("script");
    alert(document.location.host);
    script1.setAttribute("src", document.location.host+"/Scripts/ueditor1_4_3-utf8-net/ueditor.config.js");
    head.appendChild(script1);

    var script2 = document.createElement("script");
    script2.setAttribute("src", document.location.host+"/Scripts/ueditor1_4_3-utf8-net/ueditor.all.js");
    head.appendChild(script2);

    //以下省略
}

这下总可以了吧?

生活如果不让人失望那还有什么意思?!不说了,都在图里了:
这里写图片描述

谁能告诉我啥叫net::ERR_UNKNOWN_URL_SCHEME啊?

在网上找答案无果,自己猜测问题肯定是在JavaScript的路径上,于是将设置script中src属性的代码改成下面这样:

script1.setAttribute("src", "/Scripts/ueditor1_4_3-utf8-net/ueditor.config.js");

即删掉了document.location.host,果然不报错了,但是依然没有出现我想看到的结果,可见js还是没有执行。

后记:

最后结束这次纠结的方案是,先把partial view中的外部js引用全部移到主页面当中,然后刷新整个页面,并通过url把用户当前选中的选项传给刷新后的页面,再根据选中的值来动态加载不同的编辑器partial view。当然这样刷新整个页面的性能肯定不如局部刷新,这也只是我的一个权宜之计。如果谁知道如何让局部刷新的内容中包含的JavaScript可以执行的方法,恳请不吝赐教!其中还会遇到UEditor不能二次加载的问题,解决方案在我的另一篇博客中:UEditor不能重新加载的问题

转载于:https://www.cnblogs.com/chansonzhang/p/4523278.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值