我在开发AJAX应用程序时经常遇到这个问题。假设我希望用户能够点击与我网站上的每条评论相关联的“标记”图标,这会导致向服务器发送AJAX请求,请求标记评论。我需要将注释id与客户端上的注释相关联,以便AJAX请求可以向服务器传达要标记的注释。
This page解释了以这种方式注释HTML的一些方法,但没有一种方法非常令人满意。虽然我可以使用id或class属性将注释id与标记按钮相关联(例如id =“comment_1998221”),但这会失败,因为更复杂的数据不能很好地适应这些属性(例如,任意字符串)。这种事情有最好的做法吗?每次我需要这样做时,我最终会得到一些像使用id属性,隐藏的表单字段或者更糟的是设置为显示的范围:无。
HTML5数据 - *属性似乎是一个完美的解决方案,但我已经看到了很多对他们的敌意,这让我觉得人们必须已经有了他们满意的解决方案。我很想知道它是什么。
答案 0 :(得分:2)
本页介绍了以这种方式注释HTML的多种方法,但没有一种方法非常令人满意。
尽管如此,它们几乎就是你所拥有的。虽然该页面并不是一个非常好的摘要,但是它存在错误并且误解了“不显眼”的JavaScript意味着什么。
例如,将脚本元素放在body中是完全有效的 - 只是不直接在table元素中。您可以将所有脚本片段放在表的底部,或者将每一行放在它自己的表中,如果您打算在相关行中改变DOM,则可能会有一些限制。
设置“id =”comment-123“”然后扫描id为“comment-”的所有行确实适合您的特定情况。要设置非标识额外信息属性,您可以使用HTML5数据属性或使用例如将其破解为类名。 “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库都会这样做。
答案 1 :(得分:0)
jQuery data API很适合这个。
假设您有以下DOM ...
<div class="comment">
<a href="#">Flag</a>
Some text
</div>
然后,假设您还要通过ajax加载这些元素,则可以执行
$(".comment").data('someKey', (any javascript value/object));
然后,在点击处理程序到标志后,您可以执行...
$(".flagSelector").click(function(ev) {
var extraData = $(this).closest(".comment").data("someKey");
// use extraData along with your request
});
如果要在服务器端生成注释并将其与初始页面一起发送,则需要弄清楚如何初始化数据。一种方法是为注释和页面加载提供唯一的ID-s,仍然通过Ajax从服务器加载自定义数据。
答案 2 :(得分:0)
我将如何做到这一点:
在呈现页面服务器端时,生成标记链接作为普通链接,以便在没有启用javascript的情况下它可以正常工作。
<a class="flag_link" href="/comment/123/flag/"><img src="flag.gif" /></a>
然后,在javascript中,添加一个click事件来代替ajax。我将使用jQuery作为我的例子,但没有它我也不难做到。
<script>
$('a.flag_link').click(function() { $.get($(this).attr('href'), function() { alert('you flagged this comment'); }); });
</script>
当然,你会做一些比警报更加用户友好的事情来表示成功。