一尘不染

如何将服务器端数据与HTML中的客户端UI元素相关联?

ajax

在开发AJAX应用程序时,我经常遇到这个问题。假设我希望用户能够单击与我的网站上每个评论关联的“标志”图标,这导致将AJAX请求发送到服务器,请求对评论进行标记。我需要将注释ID与客户端的注释相关联,以便AJAX请求可以与服务器进行通信,以标记要注释的注释。

本页介绍了许多以这种方式注释HTML的方法,但是没有一种方法令人满意。虽然我可以使用id或class属性将注释id与标志按钮关联(例如id
=“
comment_1998221”),但是由于较复杂的数据不能很好地适合那些属性(例如任意字符串),因此失败。对于这种事情是否有最佳实践?每当我需要这样做时,我都会遇到一些麻烦,例如使用id属性,一个隐藏的表单字段,或者更糟糕的是将span设置为display:none。

HTML5 data- *属性似乎是一个完美的解决方案,但是我对它们感到厌恶,这使我认为人们必须已经有了他们满意的解决方案。我很想知道这是什么。


阅读 274

收藏
2020-07-26

共1个答案

一尘不染

本页介绍了许多以这种方式注释HTML的方法,但是没有一种方法令人满意。

不过,它们几乎就是您所拥有的。尽管该页面不是一个非常好的摘要,但仍然存在错误,并且误解了“不引人注目的” JavaScript的含义。

例如,实际上将脚本元素放在主体内是完全有效的—而不是直接放在表元素内。您可以将所有脚本片段放在表的底部,也可以将每一行放在其自己的表中,或者,如果要对DOM进行突变,则可以在有问题的行内添加一些限制。

设置“ id =“ comment-123””,然后扫描所有以“
comment-”开头的id的行,确实适合您的特定情况。为了设置非标识性的额外信息属性,您可以使用HTML5数据属性,也可以使用eg将其入侵到类名中。“
class =“ comment type-foo data-
bar””。当然,ID和类名对于可以使用哪些字符都有其限制,但是可以将任何字符串编码为有效字符串。例如,您可以使用自定义URL样式编码来隐藏非字母数字字符:

<tr class="greeting-Hello_21_20_E2_98_BA">
    ...
</tr>

function getClassAttr(el, name) {
    var prefix= name+'-';
    var classes= el.className.split(' ');
    for (var i= classes.length; i-->0;) {
        if (classes[i].substring(0, prefix.length)==prefix) {
            var value= classes[i].substring(prefix.length);
            return decodeURIComponent(value.split('_').join('%'));
        }
    }
    return null;
}

var greeting= getClassAttr(tr, 'greeting'); // "Hello! ☺"

您甚至可以通过以下方式存储复杂的非字符串值:将它们编码为JavaScript或JSON字符串,然后使用exec(或JSON.parse,如果有)检索它们。

但是,如果您在其中放置任何不重要的内容,很快就会变得混乱。那是您可能喜欢评论的地方。您可以在此处插入除“-”以外的任何内容,如果碰巧出现在字符串中,则很容易转义。

<table>
    <tr class="comment">
        <td>...</td>
        <!-- {"id": 123, "user": 456} -->
    </tr>
</table>

function getLastComment(node) {
    var results= [];
    for (var i= node.childNodes.length; i-->0;)
        if (node.childNodes[i]==8)
            return node.childNodes[i];
    return null;
}

var user= getLastComment(tr).user;

摘要警告说,由于XML解析器可能会丢弃注释,因此不能保证一定会起作用,但是DOM Level 3
LS解析器必须默认保留它们,并且到目前为止,每个浏览器和主要的XML库都可以保留注释。

2020-07-26