0

The users on my review type of platform highlight titles (of movies, books etc) in <em class="title"> tags. So for example, it could be:

<em class="title">Pacific Rim</em>

Using jQuery, I want to grab the content within this em class and add it inside a hyperlink. To clarify, with jQuery, I want to get this result:

<em class="title"><a href="http://example.com/?=Pacific+Rim">Pacific Rim</a></em>

How can I do this?

4
  • 1
    JavaScript gets executed on the client-side, you shouldn't worry about performance. Commented Nov 2, 2014 at 15:13
  • 1
    @Matteo Yes, but poorly written JS can slow down the page for the user (which is what I was referring to). Commented Nov 2, 2014 at 15:15
  • 1
    api.jquery.com/wrapinner Commented Nov 2, 2014 at 15:15
  • Please update you original post with the new updated questions you had added in the comments under each answer. Commented Nov 4, 2014 at 16:26

6 Answers 6

3
+100

Try this:

var ems = document.querySelectorAll("em.title");

for (var i = 0; i < ems.length; ++i) {
    if (ems[i].querySelector("a") === null) {
        var em = ems[i],
            text = jQuery(em).text();   
        var before = text[0] == " ";
        var after = text[text.length-1] == " ";
        text = text.trim();
        while (em.nextSibling && em.nextSibling.className && em.nextSibling.className.indexOf("title") != -1) {
            var tmp = em;
            em = em.nextSibling;
            tmp.parentNode.removeChild(tmp);
            text += jQuery(em).text().trim();
            ++i;
        }
        var link = text.replace(/[^a-z \-\d']+/gi, "").replace(/\s+/g, "+");
        var innerHTML = "<a target=\"_blank\" href=\"http://domain.com/?=" + link + "\">" + text + "</a>";
        innerHTML = before ? " " + innerHTML: innerHTML;
        innerHTML = after ? innerHTML + " " : innerHTML;
        ems[i].innerHTML = innerHTML;
    }
}

Here's a fiddle

Update: http://jsfiddle.net/1t5efadk/14/

Final: http://jsfiddle.net/186hwg04/8/

Sign up to request clarification or add additional context in comments.

16 Comments

I am going to bounty this question with 100 points in 2 days when it is eligible. Can you help me make a complete answer? This is what is missing, see the fiddle with a few examples: jsfiddle.net/1t5efadk/1 -- I want to remove "." and "," and most importantly "&" but keep single quotation marks and other characters. Remove html if its inside the tag. If 2 em tags are next to each other, then merge them. And if there is a link within the tag, then skip that tag. I think the fiddle explains it better.
@HenrikPetterson jsfiddle.net/1t5efadk/4 - is this how you want it to work?
Thank you! Unfortunately, there is one problem. The code should not strip special characters of the content, only the URL part. For example, see this fiddle: jsfiddle.net/1t5efadk/7 as you can see, it should display "Fast & Furious". The & characters should only be removed in the URL.
A performance test on your code VS another one shows that yours is 90% faster: jsperf.com/em-test Awesome! I'll mark this answer as correct and award it 100 points. There is just one minor issue that needs to be fixed. See fiddle: jsfiddle.net/186hwg04/3 As you see, it removes empty space at the end of the content of the EM tag, it shouldn't do this. It should remove it from the URL but not the content. Can you please fix this final issue so that we can finally put this answer to rest?! Note that I've change your code slightly and fixed an error, so please update code in fiddle.
The space needs to be outside tha <a> tag or the space will be underlined, so it checks if the text contains a space at beginning or end and then adds it outside the <a>.
|
2
$("em.title").each(function() {
    var content = $(this).text();
    var parameter_string = content.replace(/ /g, "+").trim();
    parameter_string = encodeURIComponent(parameter_string);
    var new_content = '<a href="http://domain.com/?s=' + parameter_string + '">' + content + '</a>';
    $(this).html(new_content);
});

If you want to remove any kind of punctuation, refer to this other question.

7 Comments

Thank you very much, although I have a question. Would it be better to use the wrapinner() function: api.jquery.com/wrapinner
When you want to replace the content of an HTML tag, you have to use html, wrapInner does a different thing.
1+ Great answer but it has one flaw. You should update your code so that it removes any unnecessary empty spaces and special characters. See this fiddle: jsfiddle.net/b5feyh4n (note the extra + and comma that should not be added to the domain URL)...
I've added a trim and encode call in the JS because I don't think special characters should be removed. They are part of the book title or whatever it is and they should be passed to the new page.
I am going to bounty this question with 100 points in 2 days when it is eligible. Can you help me make a complete answer? This is what is missing, see the fiddle with a few examples: jsfiddle.net/u52rt6ad/1 -- I want to remove "." and "," and most importantly "&" but keep single quotation marks and other characters. If 2 em tags are next to each other, then merge them. And if there is a link within the tag, then skip that tag. I think the fiddle explains it better.
|
2

$('em.title').html(function(i,html) {
  return $('<a/>',{href:'http://domain.com/?='+html.trim().replace(/\s/g,'+'),text:html});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<em class="title">Pacific Rim</em>

UPDATE 1

The following updated version will perform the following:

  1. Grab the contents of the em element
  2. Combine with the contents of the next element, if em and remove that element
  3. Create a query string parameter from this with the following properties
    • Remove the characters ,.&
    • Remove html
  4. Append the query parameter to a predetermined URL and wrap the unmodified contents in an e element with the new URL.

DEMO

$('em.title:not(:has(a))').html(function() {
    $(this).append( $(this).next('em').html() ).next('em').remove();
    var text = $(this).text().trim().replace(/[\.,&]/g,'');
    return $('<a/>',{href:'http://domain.com/?par='+encodeURIComponent(text),html:$(this).html()});
});

Or DEMO

$('em.title:not(:has(a))').html(function() {
    $(this).append( $(this).next('em').html() ).next('em').remove();
    var text = $(this).text().trim().replace(/[\.,&]/g,'').replace(/\s/g,'+');
    return $('<a/>',{href:'http://domain.com/?par='+text,html:$(this).html()});
});

UPDATE 2

Per the comments, the above versions have two issues:

  1. Merge two elements that may be separated by a text node.
  2. Process an em element that's wrapped in an a element.

The following version resolves those two issues:

DEMO

$('em.title:not(:has(a))').filter(function() { 
    return !$(this).parent().is('a'); 
}).html(function() {
    var nextNode = this.nextSibling;
    nextNode && nextNode.nodeType != 3 && 
        $(this).append( $(this).next('em').html() ).next('em').remove();
    var text = $(this).text().trim().replace(/[\.,&]/g,'').replace(/\s/g,'+');
    return $('<a/>',{href:'http://domain.com/?par='+text,html:$(this).html()});
});

15 Comments

Thank you. Is it possible to make it remove special characters? See this fiddle (see the comma issue in the URL): jsfiddle.net/1wujst29/2
I am going to bounty this question with 100 points in 2 days when it is eligible. Can you help me make a complete answer? This is what is missing, see the fiddle with a few examples: jsfiddle.net/Lx1Laurk -- I want to remove "." and "," and most importantly "&" but keep single quotation marks and other characters. Remove html if its inside the tag. If 2 em tags are next to each other, then merge them. And if there is a link within the tag, then skip that tag. I think the fiddle explains it better.
Sure, I'd be glad to help.
@HenrikPetterson, I see exactly what you mean. Will take care of it in a flash.
Yes, I will and I'll let you know.
|
0

Actually,if you just want to add a click event on em.title,I suggest you use like this:

$("em.title").click(function(){
    q = $(this).text()
    window.location.href = "http://www.domain.com/?="+q.replace(/ /g,"+")
}

you will use less html code on browser and this seems simply.

In addition you may need to add some css on em.title,like:

em.title{
     cursor:pointer;
}

2 Comments

This leads to some other problems, for example link not showing in statusbar makes some people don't want to click it.
You can add some css to decorate your em DOM, because usually hyperlink's default css can't finish our demand.
0

Something like this?

$(document).ready(function(){
    var link = $('em').text(); //or $('em.title') if you want
    var link2 = link.replace(/\s/g,"+");
    $('em').html('<a href="http://www.domain.com/?='+ link2 + '">' + link + '</a>');
});

Ofcourse you can replace the document ready with any type of handler

Comments

0
$('.title').each(function() {
  var $this = $(this),
    text = $this.text(),
    textEnc = encodeURIComponent(text);

  $this.empty().html('<a href="' + textEnc + '">' + text + '</a>');
});

DEMO

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.