为了账号安全,请及时绑定邮箱和手机立即绑定

从清单 json 动态更新 href/src 属性

从清单 json 动态更新 href/src 属性

繁花不似锦 2021-12-02 19:22:28
我正在通过读取 manifest.json 文件动态更新 html src/href 属性。但我很确定我这样做的方式没有遵循最佳实践。我找不到有关该主题的任何内容。为了更新我的 html 中的链接,阅读我的 manifest.json 的理想方式是什么?我所做的 :  <link id="maincss" rel="stylesheet"></head><body>  <script id="mainscript"></script>  <script>    function readTextFile(file, callback) {        var rawFile = new XMLHttpRequest();        rawFile.overrideMimeType("application/json");        rawFile.open("GET", file, true);        rawFile.onreadystatechange = function() {            if (rawFile.readyState === 4 && rawFile.status == "200") {                callback(rawFile.responseText);            }        }        rawFile.send(null);    }    readTextFile("/dist/manifest.json", function(text){        var data = JSON.parse(text);        document.getElementById('mainscript').setAttribute('src', '/dist/'+data.main[1]);        document.getElementById('maincss').setAttribute('href', '/dist/'+data.main[0]);    });  </script>您可以看到,一旦我阅读了文件,我就为 javascript 设置了 src 属性,为 css 设置了 href 属性。我的 manifest.json :{"main":["mycss.798d79ab87daa2i3df123.css","main.f8aaae15e396b637e82e.js"]}
查看完整描述

1 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

看起来您正在尝试将 JavaScript 和 CSS 外部化,以便您可以在应用程序之外更改它们,而无需进行重新部署(或类似的操作)。


我认为这个用例有更干净的解决方案,但考虑到您的设置,我只是稍微清理一下,让它更灵活一点。


我要解决的第一件事是:


<link id="maincss" rel="stylesheet"> document.getElementById('maincss').setAttribute('href', '/dist/'+data.main[0]);


这可能不是问题,但这实际上只是将您锁定在单个 css 文件中。如果您需要添加另一个文件怎么办?或者它可能是不同的文件类型(如字体样式)。


话虽如此,我会完全放弃占位符元素。显然,您引用占位符(mainscript、maincss)的方式也将被抛弃。


对于初学者,我会重构您的json文件以使其更具可扩展性,然后,我基本上会创建一个“迷你模块加载器”


这是我会做的:


// Fake HTTP Get that returns your manifest file

const fakeGetRequest = () => {

  return [{

      "type": "link",

      "src": "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css",

    },

    {

      "type": "script",

      "src": "https://code.jquery.com/jquery-3.3.1.slim.min.js"

    }

  ];

}


// Helper function to centralize the creation of the reference tag

const createRef = (src, type) => {

  switch (type) {

    case 'script':

      const script = document.createElement('script');

      script.src = src;

      return script;

    case 'link':

      const link = document.createElement('link');

      link.rel = 'stylesheet';

      link.href = src;

      return link;

  }

  return null;

}


// Your manifest.json

const manifest = fakeGetRequest();


// Iterate over your manifest and append things where you want them

manifest.forEach(item => {

  const ref = createRef(item.src, item.type);

  switch (item.type) {

    case 'link':

      document.head.appendChild(ref);

      break;

    case 'script':

      document.body.appendChild(ref);

      break;

  }

});

这将使您能够添加任意数量的脚本/css 引用,并且您的代码将始终知道如何附加它们,无论您要附加多少。由于您的清单文件现在是可配置的,并且您的页面中有代码知道如何将其转换为有意义的内容,因此支持不同的文件类型(例如图像或您想放入的任何其他内容)需要将该类型添加到您的代码中它知道如何处理它。


我在清单 ( srcand type) 中只有两个属性,但实际上,您可能需要诸如 order 之类的东西(也许需要先引用一个依赖项),另一个属性,如果您希望将其附加到head或body, 等等...


长话短说,我认为您拥有的一切都很好,那里确实没有太多需要改进的地方。您唯一可以显着改进的是可扩展性(如果需要)。


查看完整回答
反对 回复 2021-12-02
  • 1 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信