Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A more efficient JavaScript code for a highlighting function?

So this is the functionality I need to clean up:

I need to create a function where viewers can click on any word in a sentence, and it will be highlighted. However, I need to make it so only one word is highlighted at a time. So for example, if you click the word 'you' and then you change your mind and click the word 'eagle', then the word 'you' will be deselected.

There's already existing code for it, but we're working on a very tight deadline and if we make edits and adjustments using this extremely long, extremely difficult-to-navigate code, then we will use up so many precious weeks producing a single 5-minute interactivity.

This is what it looks like:
http://bit.ly/PeKOxH

And this is a snippet of the JS (so you can glimpse the problem):
http://bit.ly/PeMY0l

(the HTML and JS codes are available upon request)

So instead of this long hell that we might need to put ourselves through, I was thinking something like passing each sentence through an array so each individual word would already be assigned to a name. So then we would be able to call each array via a for loop to print it out on the page, and use an arrayName[i] to call individual words for highlighting. And then maybe an if-else statement so only the selected word is highlighted.

I've been trying to push the actual HTML elements through the arrays, like, only get the <p> for every <div id="sentence1"> or something, but it doesn't seem to be possible... If it is, please tell me how it is done, or if it is not, I will still appreciate any other alternative for this.

I cannot for the life of me figure out all the hard-coding on my own, as I only know so much about JavaScript right now, but am very, very willing to learn! Any help with this would be deeply appreciated, as we're working on a very tight deadline.

Thank you so much in advance! Please, any help, or any suggestions would do!

EDIT

This is the code for our checkAns() function. It increments var correct when a correct answer is highlighted every time checkAns() runs. It is also responsible for marking specific numbers wrong or right.

function checkAns(){
    document.getElementById('alertMsg').style.visibility = "hidden";


    if(Ans1B == "selected"){
        correct++
        document.getElementById('marksymbol1').className = "smile";
    }
    else
    {
        document.getElementById('marksymbol1').className = "sad";
    }
    if(Ans2A == "selected"){
        correct++
        document.getElementById('marksymbol2').className = "smile";
    }
    else
    {
        document.getElementById('marksymbol2').className = "sad";
    }
    if(Ans3A == "selected"){
        correct++
        document.getElementById('marksymbol3').className = "smile";
    }
    else
    {
        document.getElementById('marksymbol3').className = "sad";
    }
    if(Ans4A == "selected"){
        correct++
        document.getElementById('marksymbol4').className = "smile";
    }
    else
    {
        document.getElementById('marksymbol4').className = "sad";
    }
    if(Ans5A == "selected"){
        correct++
        document.getElementById('marksymbol5').className = "smile";
    }
    else
    {
        document.getElementById('marksymbol5').className = "sad";
    }
like image 909
Willow Avatar asked Mar 20 '23 00:03

Willow


2 Answers

As per @DrewGoldsBerry's answer, with some example code. Here's a working fiddle of the code below: http://jsfiddle.net/E3D6T/1/

Set up your HTML with a class to indicate which lines should have the highlight functionality.

<p class="highlight">Each word will be wrapped in a span.</p>
<p class="highlight">A second paragraph here.</p>

In your JS, split the p elements into words wrapped in span tags, which can then be bound to a click function:

// wrap words in spans
$('p.highlight').each(function () {
    var $this = $(this);
    $this.html($this.text().replace(/\b(\w+)\b/g, "<span>$1</span>"));
});

// bind to each span
$('p.highlight span').click(function () {
    $(this).parent().find('span').css('background-color', '');
    $(this).css('background-color', '#ffff66');
});

edit:

http://jsfiddle.net/jorgthuijls/E3D6T/16/

I added all the answer checking to the click function itself. Should be fairly straight forward.

like image 163
Jorg Avatar answered Mar 22 '23 15:03

Jorg


Sorry to add to the noise... my answer is very similar to Jorgs and Roberts, and it also checks for valid answers.

JS Fiddle is here:

http://jsfiddle.net/M7faZ/3/

The checkAns function uses the ID of the sentence element, to map the answer object to the selectedAnswer object.

The HTML has carefully chosen ID and classnames:

<ul class='sentences'>
  <li class='sentence' id='ans1'>Can you draw an eagle?</li>
  <li class='sentence' id='ans2'>She is good in painting.</li>
</ul>

<div id='mark-symbol-ans1'></div>
<div id='mark-symbol-ans2'></div>

And the JS has a map of answers.

// get the list
var $sentences = $('.sentence'),
    answers = {
        ans1: 'you',
        ans2: 'She'
    },
    selectedAnswers = {};

function checkAns() {
    var correct;

    for (var i in answers) {
        correct = selectedAnswers[i] === answers[i]

        $('#mark-symbol-' + i).toggleClass('smile', correct);
        $('#mark-symbol-' + i).toggleClass('sad', !correct);
    }
}

If you care about people cheating, this part should be done on the server so it's not exposed to the client.

like image 34
Wheeyls Avatar answered Mar 22 '23 13:03

Wheeyls