$description can broke your option in several ways. I's better to define a function to be called onclick, but going further, it's better to trigger the function onchange the select.
Take a look to this example:
<?php
$description3 = '<p>This is a single quote: \'</p>'; //Escape ' with \
$myOptions = array(
    'val1' => array(
        'text' => 'Option 1',
        'url' => 'https://url1.com',
        'title' => 'This is Option 1',
        'description' => '<p>This is description for <b>Option 1</b>.</p>',
    ),
    'val2' => array(
        'text' => 'Option 2',
        'url' => 'https://url2.com',
        'title' => 'This is Option 2',
        'description' => '<p>This is description for <b>Option 2</b>.</p>',
    ),
    'val3' => array(
        'text' => 'Option 3',
        'url' => 'https://url3.com',
        'title' => 'This is Option 3',
        'description' => $description3, //No need to escape anything
    ),
);
?>
<script>
var myOptions = <?php echo json_encode($myOptions); ?>;
function mySelectChanged(value)
{
    //Call your original function
    updateTotals(myOptions[value].url, myOptions[value].title, myOptions[value].description);
}
</script>
<select id="mySelect" onchange="mySelectChanged(this.value);">
<?php
foreach ($myOptions as $value=>$option) {
    printf('<option value="%s">%s</option>', $value, $option['text']);
}
</select>