我正在为我的网站编写一个笑脸解析功能。我想要完成的是转换某些字符串,例如":)"
成像这样的图像:
或者这里是实际的html作为例子:
":)" ===> <img src="images/smilies/smile.png" />
我的函数执行它的意图,但它也解析本机javascript函数名称!我的意思是,如果我键入包含字符串"push"
,"pop"
或"some"
的评论(可能会加载其他字符串),我的函数会将这些字符串解析为无效图像,如这样:
这是一个显示以下内容的html字符串:
<img src="images/smilies/function some() { [native code] }" alt="">
这会导致浏览器控制台中出现404未找到错误。
Failed to load resource: the server responded with a status of 404 (Not Found)
为什么会这样?我在代码中没有做任何太不寻常的事情,你可以在这里看到:
function parse_new_comment(commentElem){
$(commentElem).html(parse_comment($(commentElem).text()));
}
function parse_comment(comment){
var formatted_comment = "";
var smilies = new Array();
smilies[":)"] = "smile.png";
smilies[":D"] = "smile-big.png";
smilies[":p"] = "tongue.png";
smilies["[sheep]"] = "sheep.png";
smilies["<3"] = "love.png";
smilies["[love]"] = "love.png";
var words = comment.split(" ");
for (var i = 0; i < words.length; i++) {
if(smilies[words[i]] !== undefined){
formatted_comment += ' <img src="images/smilies/'+smilies[words[i]]+'" alt="" />';
}else{
formatted_comment += ' ' + words[i];
}
}
return formatted_comment;
}
我有一种感觉,这行代码导致问题if(smilies[words[i]] !== undefined){
,因为push
和pop
是数组函数,我不太确定但是......我如果有人可以就我的功能失败的原因提出任何想法,我将不胜感激。
哦,我忘了提,我的页面使用ajax来做所有事情,所以通过调用这样的函数解析新的注释:
parse_new_comment($("#comment_343"));
谢谢。
答案 0 :(得分:7)
检查对象是否具有属性本身,而不是对象的属性未定义。这可以使用hasOwnProperty
完成。
if(smilies.hasOwnProperty(words[i])){
而不是
if(smilies[words[i]] !== undefined){
此外,由于您没有将smilies
用作数组,因此我同意Pointy的评论,即它应该被声明为对象。值得一提的是,当您将密钥附加到JavaScript中的Array
时,如果they can be seen as unsigned integers,它们仅被视为数组索引。
var smilies = {};//short for new Object();
smilies[":)"] = "smile.png";
smilies[":D"] = "smile-big.png";
smilies[":p"] = "tongue.png";
smilies["[sheep]"] = "sheep.png";
smilies["<3"] = "love.png";
smilies["[love]"] = "love.png";
您可能对使用Explosion Pills建议的答案所建议的文字语法感兴趣。只是为了澄清,仍然需要使用hasOwnProperty
。
答案 1 :(得分:4)
我只是这样做:
function parse_new_comment(commentElem) {
commentElem.html(parse_comment(commentElem.text()));
}
function parse_comment(comment) {
return comment.replace(/(\:\)|\:D|\:p|\[sheep\]|\<3|\[love\])/gi, function (match) {
var smilies = {
":)": "smile.png",
":D": "smile-big.png",
":p": "tongue.png",
"[sheep]": "sheep.png",
"<3": "love.png",
"[love]": "love.png"
}
return '<img src="images/smilies/' + smilies[match] + '" alt="" />';
});
}
答案 2 :(得分:2)
不要使用Array
并像对象一样访问它。使用对象。您所看到的是使用对象访问语法访问Array方法的行为。您应该只使用数字键来访问数组。
var smilies = {
":)": "smile.png",
":D": "smile-big.png",
};
......等等。
您应该能够保持其余代码相同。
答案 3 :(得分:2)
我会使用一个动态创建正则表达式的实现(也可能更快):
RegExp.escape = function(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
function SmileyParser(smiles) {
var smilepatterns = [], k;
for (k in smiles) {
if (smiles.hasOwnProperty(k)) {
smilepatterns.push(RegExp.escape(k));
}
}
this.smiles = smiles;
this.re_smiles = RegExp("(^|\\s)("+smilepatterns.join("|")+")($|\\s)", 'g');
}
SmileyParser.prototype.replace = function (text) {
var smiles = this.smiles;
function replacer(m, p1, p2, p3) {
console.log(m);
return p1
+"<img src='/images/smiles/"+smiles[p2]+"'>"
+p3;
}
return text.replace(this.re_smiles, replacer);
};
然后像这样使用:
var smiles = {
":)": "smile.png",
":D": "smile-big.png",
":p": "tongue.png",
"[sheep]": "sheep.png",
"<3": "love.png",
"[love]": "love.png"
};
var sp = new SmileyParser(smiles);
var text = 'This comment parses my smiley fine :)';
var newtext = sp.replace(text);
newtext
将是:
This comment parses my smiley fine <img src='/images/smiles/smile.png'>
答案 4 :(得分:1)
是的,你是对的,你的代码应该成为:
if(smilies[words[i]] !== undefined && (typeof smilies[words[i]]) == 'string'){
或
if(words[i] in smilies && (typeof smilies[words[i]]) == 'string'){