3

我正在为我的网站编写笑脸解析功能。我想要完成的是转换某些字符串,例如":)"变成这样的图像:在此处输入图像描述

或者以实际的 html 为例:

":)" ===> <img src="images/smilies/smile.png" />

我的函数做了它应该做的事情,但它也在解析原生 javascript 函数名!我的意思是,如果我键入包含字符串"push""pop""some"(可能还有其他负载)的注释,我的函数会将这些字符串解析为无效图像,如下所示:

在此处输入图像描述

这是一个显示此内容的 html 字符串:

<img src="images/smilies/function some() { [native code] }" alt="">

这会导致浏览器控制台中出现 404 not found 错误。

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){,就像数组函数一样pushpop虽然我不太确定......如果有人能就我的函数失败的原因提出任何想法,我将不胜感激。

哦,我忘了提,我的页面使用 ajax 来做所有的事情,所以新的评论是通过调用这样的函数来解析的:

parse_new_comment($("#comment_343"));

谢谢你。

4

5 回答 5

7

检查对象是否具有属性本身,而不是对象的属性未定义。这可以使用hasOwnProperty.

if(smilies.hasOwnProperty(words[i])){

代替

if(smilies[words[i]] !== undefined){

另外,由于您没有将smilies其用作数组,因此我同意 Pointy 的评论,即应将其声明为对象。值得一提的是,当您Array在 JavaScript 中将键附加到 an 时,只有当它们可以被视为无符号整数时,它们才会被视为数组索引。

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仍然需要使用。

于 2013-03-30T17:29:18.457 回答
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="" />';
    });
}

小提琴

于 2013-03-30T17:39:50.500 回答
2

不要Array像对象一样使用和访问它。使用一个对象。您所看到的是使用对象访问语法访问 Array 方法的行为。您应该只使用数字键来访问数组。

var smilies = {
    ":)": "smile.png",
    ":D": "smile-big.png",
};

...等等。

您应该能够保持其余代码相同。

于 2013-03-30T17:30:37.693 回答
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'>
于 2013-03-30T18:04:01.643 回答
1

是的,你是对的,你的代码应该变成:

if(smilies[words[i]] !== undefined && (typeof smilies[words[i]]) == 'string'){

或者

if(words[i] in smilies && (typeof smilies[words[i]]) == 'string'){
于 2013-03-30T17:34:03.207 回答