简体   繁体   中英

jQuery rendering a link to chat system

I'm building an web app for my client and it involves a chat system where users can communicate with each other. Now what my client wants me to do, is that if user has send an link to another user using this chat system, it should automatically render it as an link (within a tag).

Now I can return a normal text if it's an regular text, but if it's a link, it currently returns [object Object]. The regular expression itself works, I have tested it out, the only part I'm having trouble is to actually render the link.

Here's my function to test if it's a link:

functions.js

function isAValidUrl(data)
{
    var pattern = new RegExp('(([\\w]+:)?//)?(([\\d\\w]|%[a-fA-f\\d]{2,2})+(:([\\d\\w]|%[a-fA-f\\d]{2,2})+)?@)?([\\d\\‌​w][-\\d\\w]{0,253}[\\d\\w]\\.)+[\\w]{2,4}(:[\\d]+)?(/([-+_~.\\d\\w]|%[a-fA-f\\d]{2,2})*)*(\\‌​?(&?([-+_~.\\d\\w]|%[a-fA-f\\d]{2,2})=?)*)?(#([-+_~.\\d\\w]|%[a-fA-f\\d]{2,2})*)?');
    if(!pattern.test(data)) {
        return data;
    } else {

         return $('<a>').attr('href', data.message).text(data.message);
    }
}

And here's a part of my Chat.js where I'm using that function

chat.js

function render() {

    var html = [], messages = $self.data('messages');
    var escaper = $('<div/>');
    for (var i = messages.length - 1; i >= 0; i--) {
        html.push(
            '<div class="media chat-message" data-message-id="' + messages[i].id + '">' +
            '<div class="message-meta"><span class="sender-name">' + messages[i].sender_name + '</span><span class="stamp pull-right" data-stamp="' + messages[i].created_at + '"></span></div>' +
            '<div class="media-body">' +
            '<div class="message-text">' + escaper.text(isAValidUrl(messages[i].message)).html() + '</div>' +
            '</div>' +
            '</div>'
        );
    }
    $self.find('.message-container').html(html.join('')).end().find('.stamp[data-stamp]').timeAgo();
    clearInterval(timeAgoTimer);
    timeAgoTimer = setInterval(function () {
        $self.find('.stamp[data-stamp]').timeAgo();
    }, 60000);
    return $self.chatBox('scrollToBottom');
}

Any help would be greatly appreciated!

You're treating your parameter inconsistently in the function -- is it an object with a property called message that's a string? Or is it just a string? If it's just a string, then this will work:

function isAValidUrl(data)
{
    var pattern = new RegExp('(([\\w]+:)?//)?(([\\d\\w]|%[a-fA-f\\d]{2,2})+(:([\\d\\w]|%[a-fA-f\\d]{2,2})+)?@)?([\\d\\‌​w][-\\d\\w]{0,253}[\\d\\w]\\.)+[\\w]{2,4}(:[\\d]+)?(/([-+_~.\\d\\w]|%[a-fA-f\\d]{2,2})*)*(\\‌​?(&?([-+_~.\\d\\w]|%[a-fA-f\\d]{2,2})=?)*)?(#([-+_~.\\d\\w]|%[a-fA-f\\d]{2,2})*)?');
    if(!pattern.test(data)) {
        return data;
    } else {

         return $('<a>').attr('href', data).text(data);
    }
}

If you're using jQuery this plugin works well and covers almost every possible situtation...

https://github.com/SoapBox/jQuery-linkify

As discussed in the comments, call linkify on the element that contains the text you want to "linkify", not on the text itself.

$('.message-text').linkify();

You are trying to set a text to div and then call .html() with the below code

var escaper = $('<div/>');    
escaper.text(isAValidUrl(messages[i].message)).html()

You should set .html() than use .text() as if its a link it would return an object.

'<div class="message-text">' + escaper.html(isAValidUrl(messages[i].message)).html()+ '</div>' +

Demo

 function isAValidUrl(data) { var pattern = new RegExp('(([\\\\w]+:)?//)?(([\\\\d\\\\w]|%[a-fA-f\\\\d]{2,2})+(:([\\\\d\\\\w]|%[a-fA-f\\\\d]{2,2})+)?@)?([\\\\d\\\\‌​w][-\\\\d\\\\w]{0,253}[\\\\d\\\\w]\\\\.)+[\\\\w]{2,4}(:[\\\\d]+)?(/([-+_~.\\\\d\\\\w]|%[a-fA-f\\\\d]{2,2})*)*(\\\\‌​?(&?([-+_~.\\\\d\\\\w]|%[a-fA-f\\\\d]{2,2})=?)*)?(#([-+_~.\\\\d\\\\w]|%[a-fA-f\\\\d]{2,2})*)?'); if (!pattern.test(data)) { return data; } else { return $('<a>').attr('href', data).text(data); } } $(document).ready(function() { var html = []; var messages = ["no link", "http://www.test.com"]; var msg = "http://www.test.com"; var div = $('<div/>'); for (var i = messages.length - 1; i >= 0; i--) { html.push('<div class="message-text">' + div.html(isAValidUrl(messages[i])).html() + '</div>'); } $('body').append(html); }); 
 .message-text { background: #eee; color: #555; font-size: 14px; padding: 10px; margin: 10px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM