V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
loveuloveme
V2EX  ›  问与答

JavaScript 中存入一段 HTML 代码,运行的时候加入到 DOM 中,最佳操作是什么

  •  
  •   loveuloveme · 2020-10-03 10:19:16 +08:00 · 1963 次点击
    这是一个创建于 1517 天前的主题,其中的信息可能已经有所发展或是发生改变。

    HTML 代码比较多,所以希望是可以整块复制粘贴的,或微调一下的。

    第 1 条附言  ·  2020-10-03 11:00:56 +08:00

    使用 createContextualFragment 函数解决

    var new_dom = document.createRange().createContextualFragment(`
        <div x-data="comment()"
        @addcomment.window="addComment($event.detail)"
        x-show="show"
        class="fixed bottom-0 left-0 right-0 flex justify-center">
        <div class="bg-white h-64 w-full border p-5 border-b-0 max-w-screen-md rounded-t-lg shadow-2xl">
            <div class="h-10">
                <p>
                    Reply to
                    <strong class="text-blue-400 uppercase" x-text="comment_owner_name"></strong>
                </p>
            </div>
            <div class="h-32">
                <textarea name="body" id="body" x-model="body"  required="required" class="w-full h-full border-t border-b focus:outline-none pt-3 pb-3" spellcheck="false"></textarea>
            </div>
            <div class="h-16 flex justify-end items-center">
                <div>
                    <button @click="show = false" class="btn mr-4">
                        取消
                    </button>
                    <button @click="addCommentStore" type="submit" class="btn btn-purple btn-long">
                        提交
                    </button>
                </div>
            </div>
        </div>
        </div>
    `);
    
    
    
    document.body.appendChild(new_dom)
    
    第 2 条附言  ·  2020-10-03 12:10:52 +08:00

    做的是一个弹出模版。把HTML写到JS的代码里的好处就是哪里需要这个模版,直接引用JS就可以使用了,不需要在额外处理,或者额外加载。如果要修改,直接把HTML 拷贝到模版里改好就行。

    # 引用该JS后,就能直接使用这个弹出模块了,类似于这种
    x-data @click="$dispatch('addcomment')"
    
    
    如果大家用的也是Tailwind+Alpine, 可以拿去直接按照自己页面修改下就能用了。
    
    第 3 条附言  ·  2020-10-03 12:13:15 +08:00
    window.comment = function () {
        return {
            show: null,
            addComment(obj) {
                this.show = true
            },
            addCommentStore() {
    
        }
    }
    
    第 4 条附言  ·  2020-10-04 13:06:14 +08:00

    进一步更新如下

    // 把模版放到单独的html文件里,然后引用
    var new_dom = document.createRange().createContextualFragment(require('../tpl/comment_modal.html')); 
    document.body.appendChild(new_dom)
    
    第 5 条附言  ·  2020-10-04 13:08:05 +08:00

    写个函数稍微封装下

    // base/h.js
    // A few helper fuctions
    const h = {
        postUrl(uri) {
            return location.href.replace(location.search, '') + '/' + uri
        },
        addToDom(str) {
            var new_dom = document.createRange().createContextualFragment(str);
    
            document.body.appendChild(new_dom)
        }
    }
    
    module.exports = h;
    
    
    
    
    window.h = require('./base/h');
    
    
    
    
    h.addToDom(require('../tpl/comment_modal.html'))
    
    
    18 条回复    2020-10-04 09:14:07 +08:00
    crclz
        1
    crclz  
       2020-10-03 10:27:43 +08:00
    前端工程化还是 angular react vue 擅长。

    如果是前后端不分离的话,可以考虑后端模板引擎渲染那些公用的 html 代码。
    loveuloveme
        2
    loveuloveme  
    OP
       2020-10-03 10:29:53 +08:00
    @crclz 这个需求想用原生 JavaScript, 把一段 HTML 代码直接写在 JavaScript
    Jirajine
        3
    Jirajine  
       2020-10-03 10:30:49 +08:00 via Android
    直接 jsx ?
    lichdkimba
        4
    lichdkimba  
       2020-10-03 10:34:00 +08:00
    loveuloveme
        5
    loveuloveme  
    OP
       2020-10-03 10:37:07 +08:00
    @Jirajine JSX allows us to write HTML in React. JSX 可以在原生 JavaScript 中用吗?官方文档好像没提
    Cbdy
        6
    Cbdy  
       2020-10-03 10:40:51 +08:00 via Android
    React
    crclz
        7
    crclz  
       2020-10-03 10:42:59 +08:00
    服务端把公用的 html 片段以静态文件的方式提供,前端使用 JQuery.load 方法加载 https://api.jquery.com/load/ ,或者使用原生 js 请求+手动修改 dom 。
    hoyixi
        8
    hoyixi  
       2020-10-03 10:47:07 +08:00
    1 简单的:JS ( ES6+)的 string interpolation + 原生 DOM 操作(比如 append )
    2 复杂的,比如带点渲染逻辑的:Handlebars / Mustache,JS 模板库
    loveuloveme
        9
    loveuloveme  
    OP
       2020-10-03 10:51:03 +08:00
    @crclz 不想额外多一个请求,想要直接放在 JavaScript 代码里
    xiangyuecn
        10
    xiangyuecn  
       2020-10-03 10:59:19 +08:00
    很多语言多行文本支持的都很烂,尤其是 java (上古时期的 JavaScript 照搬的 java 语法)

    虽然 es6 提供了一个简陋版,不过该难用时还是难用,里面还是得转义`,界定符号都不提供,订标准的那坨人喂猪的嘛

    `:docx:
    <div>
    这么简单的语法支持一下就这么难 `遇到 markdown 就瞎比` 的神奇语法
    </div>
    :docx:`

    php 的那个 doc 语法表面不错,但几个高度相似语法就懒得讲了。所以我选择自己编译 js 自定义的语法,可以玩出花来
    flasktest1
        11
    flasktest1  
       2020-10-03 11:00:46 +08:00
    cmdOptionKana
        12
    cmdOptionKana  
       2020-10-03 11:43:53 +08:00 via Android
    @flasktest1 这个 template 非常好用,我很爱用,有了这个写简单页面很爽,不比 vue 差。
    cmdOptionKana
        13
    cmdOptionKana  
       2020-10-03 11:45:31 +08:00 via Android
    @loveuloveme 用 createContextualFragment 想微调不方便吧?建议用 template
    gouflv
        14
    gouflv  
       2020-10-03 11:56:26 +08:00 via iPhone
    用模板能解决的问题,居然说用 react,前端真不一样了现在
    loveuloveme
        15
    loveuloveme  
    OP
       2020-10-03 12:07:24 +08:00
    @cmdOptionKana 这个做好后不用调整的, 直接引用 JS 就可以用了,如果要调整的话,整段复制到模版里,改后直接复制过来就行。 这是一个弹出模块,这样做的好处,就是哪里需要,直接引用 JS ( JS 里也不会有额外的模版请求)就行,
    Jirajine
        16
    Jirajine  
       2020-10-03 12:09:00 +08:00 via Android
    @loveuloveme 预编译一下啊,非要不愿意编译那只能引用 babel 运行时编译。
    jsx 的好处是容易维护。
    zy445566
        17
    zy445566  
       2020-10-03 22:59:42 +08:00 via Android
    我是用 webpack 打包,然后 import 进来的,变量就是 HTML 字符串
    codingguy
        18
    codingguy  
       2020-10-04 09:14:07 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5334 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 05:48 · PVG 13:48 · LAX 21:48 · JFK 00:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.