Javascript word highlighting in a text - javascript

I have a variable called output in Javascript, which has the following content.
var output = "something."
I want to search and highlight the words "word1" and "word2" in them when I display the content of output. The above content is dynamic. Assuming I have a variable output which has the text and an array called arr1 which has the elements to be searched and highlighted, how can I display the entire content with words highlighted in javascript?Please let me know. Thanks in advance.

Assuming you want literal phrases that are generally just words (no special characters or punctuation), you could use a regular expression similar to this (I've also added case insensitivity):
var output = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
var arr1 = ['eiusmod tempor', 'consectetur'];
var regex = new RegExp('('+arr1.join('|')+')', 'gi');
output = output.replace(regex, "<b>$1</b>");
// the following line is for debug purposes only. I've added it
// to better display what's happening just for the Stackoverflow
// code snippet editor.
document.body.innerHTML = output;
b {
background: yellow;
font-weight: normal;
}
Edit:
Quick edit to include logic that ensures "consectrtur" is matched, but "consecteturs" is not. It just needs a simple look ahead of (?!\\w) and a "look behind" (not a real look behind because javascript doesn't support it) of (\\W+|^) ensuring the matched term is not surrounded by word characters, and thus not part of a different word.
var output = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse consecteturs cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum";
var arr1 = ['eiusmod tempor', 'consectetur', 'orem', 'laborum'];
var regex = new RegExp('(\\W+|^)('+arr1.join('|')+')(?!\\w)', 'gi');
output = output.replace(regex, "$1<b>$2</b>");
// the following line is for debug purposes only. I've added it
// to better display what's happening just for the Stackoverflow
// code snippet editor.
document.body.innerHTML = output;
b {
background: yellow;
font-weight: normal;
}

You can wrap the words you want highlighted with a <span> tag then add a class or inline styling to the tag for your highlight color. This would require that you identify the words you want highlighted and add the opening tag before and closing tag after with a String.replace(word, tag + word + closing_tag) or something similar.

To wrap something in HTML using Javascript, you should be looking at Regex. For example:
str = str.replace(/(neoplasm)/ig, "<b>$1</b>");
To replace from an array, you could do something like connecting your strings with a join using the regex OR: | to generate a custom regex string, matching those words.
EDIT: Like Joseph just suggested, just one minut before me.

Related

How to get textContent including childNodes?

I have some plain text content in paragraphs inside a <main> HTML element.
the paragraphs are separated by new lines (\n), not in <p> tags, and I would like to automatically wrap them in <p> tags using JavaScript.
Example content:
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<img src="img/testimg.jpg"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
Inside of <main> there may be <img> elements.
I want the script to watch for these and leave them untouched. It breaks the HTML (no image is rendered, and dev tools show overflow) if the script tries to wrap them like: <p><img src="img/testimg.jpg"></p> (assuming that is what it is doing).
My script so far:
var maintext = document.getElementsByTagName('main')[0]; // get the first (0th) <main> element
var arr = maintext.textContent.split(/[\r?\n]+/); // split the text inside into an array by newline
// regex matches one OR MORE consecutive newlines, which prevents empty <p></p> being captured
arr.forEach(function(part, index) {
if (!this[index].includes("<img ")) {
this[index] = "<p>" + this[index] + "</p>"; // wrap each paragraph with <p> tags
}
}, arr);
var rejoined = arr.join("\r\n"); // join the array to remove commas, with newlines as separators
maintext.innerHTML = rejoined; // replace contents of our <main> element with the new text
I believe the problem may be that <img> is not captured as text along with the textContent of <main>, but instead remains recognized as a child node and it's messing up the array.
You can see my attempt to only wrap in <p> if that array element does not (!) contain "<img " ...however, this is not working. It seems the enclosed HTML elements do not get matched as string data by includes.
What's the best way to go about this?
To retain non-text content like images, you'll need to process the text nodes of the main element rather than using textContent, since that's just the text content of the element.
Assuming you only want to do this with the text nodes, you can loop through the element's nodes, split text nodes on line breaks, and if you get more than one segment, insert paragraphs for them. Something like this (see inline comments):
function convertLineBreaksToParagraphs(element) {
// Get a snapshot of the child nodes of the element; we want
// a snapshot because we may change the element's contents
const nodes = [...element.childNodes];
// Loop through the snapshot
for (const node of nodes) {
// Is this a text node?
if (node.nodeType === Node.TEXT_NODE) {
// Yes, split it on line breaks
const parts = node.nodeValue.split(/\r\n|\r|\n/);
// Did we find any?
if (parts.length > 1) {
// Yes, loop through the "paragraphs"
for (const part of parts) {
// Create an actual paragraph for it
const p = document.createElement("p");
p.textContent = part;
// Insert in in front of the text node it came from
element.insertBefore(p, node)
}
// Remove the text node we've replaced with paragraphs
element.removeChild(node);
}
}
}
}
convertLineBreaksToParagraphs(document.querySelector("main"));
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<img src="img/testimg.jpg"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
You may need to tweak that a bit, depending on how you want to handle that image just before the fifth paragraph. The above leaves the image outside the paragraph. But if you wanted it to be inside the paragraph, you could add some logic to do that.
function convertLineBreaksToParagraphs(element) {
let img = null;
// Get a snapshot of the child nodes of the element; we want
// a snapshot because we may change the element's contents
const nodes = [...element.childNodes];
// Loop through the snapshot
for (const node of nodes) {
// Is this a text node?
if (node.nodeType === Node.TEXT_NODE) {
// Yes, split it on line breaks
const parts = node.nodeValue.split(/\r\n|\r|\n/);
// Did we find any?
if (parts.length > 1) {
// Yes, loop through the "paragraphs"
for (const part of parts) {
// Create an actual paragraph for it
const p = document.createElement("p");
p.textContent = part;
// If we *just* saw an image before this text node,
// move it into the paragraph
if (img) {
p.insertBefore(img, element.firstChild);
img = null;
}
// Insert in in front of the text node it came from
element.insertBefore(p, node)
}
// Remove the text node we've replaced with paragraphs
element.removeChild(node);
}
} else if (node.nodeName === "IMG") {
img = node;
} else {
img = null;
}
}
}
convertLineBreaksToParagraphs(document.querySelector("main"));
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<img src="img/testimg.jpg"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
You may have people telling you to do this by manipulating the HTML from innerHTML, but the problem with doing that is you run the risk of introducing tags in the middle of a tag (and you will remove any event handlers when you set innerHTML on main). For instance, if you have:
<img
src="/path/to/something">
you'd end up with
<img
<p> src="/path/to/something"></p>
...which is obviously not good.

JavaScript; highlight all occurrences of a particular string in a textarea

Let's say I have this code:
<textarea style="width:300px;height:200px">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do ipsum eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ipsum ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in ipsum reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur ipsum sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit ipsum anim id est laborum.</textarea>
I want to highlight all occurrences of the string ipsum. I already googled but only found scripts that highlight a single occurrence only.
Does anybody have a hint for me?
You need to get a plugin that tokenize your textarea content into balise;
See http://codersblock.com/blog/highlight-text-inside-a-textarea/

AngularJS ng-show is not working

I'm trying to make the button "Detalhes" to toggle a div to show a message.
Apparently there's nothing wrong.
First... my HTML
<tr ng-repeat="chamado in cabertos">
<td>{{chamado.numero}}</td>
<td>{{chamado.user}}</td>
<td>{{chamado.assunto}}</td>
<td>{{chamado.status_chamado}}</td>
<td><button ng-click="mostra()">Detalhes</button></td>
</tr>
</tbody>
<div ng-show="{{visivel}}">
<h3>Mensagem enviada:</h3>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</table>
</div>
My Script:
app.controller('mostra',function($scope){
$scope.visivel = false;
$scope.mostra = function() {
if($scope.visivel==false) $scope.visivel=true;
else if($scope.visivel == true) $scope.visivel=false;
};
});
And the when I press F12 in my page, for an unknown reason there is a ng-hide not allowing me to toggle my div:
<div ng-show="false" class="ng-hide">
<h3>Mensagem enviada:</h3>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
Change
<div ng-show="{{visivel}}">
To
<div ng-show="visivel">
Edit - adding explanation why this is the case. I am quoting Evan, as I could not explain this any better than he.
Why is this?
The $scope.visive1 variable does not need to be interpolated through
the use of double-brackets in the ng-show directive. In short
Directives do not need braces, while expressions DO need them
- #Evan Bechtol
You should do this
ng-show="visivel"
and not
ng-show="{{visivel}}"
Reason why you see class="ng-hide"
since your ng-show is false, angular applies class ng-hide which hides the element as it is opposite of show, if ng-show was true it would have removed the class.
Also you do not need to use the curly braces (interpolation) along with pre defined angular JS directives like ng-show, ng-hide, ng-if, ng-repeat. Angular knows by itself what you passing to these directives
When you refresh the page you reset the App and therefore you do this:
$scope.visivel = false;
making the div invisible..
Try initializing $scope.visivel = {} in the controller.
app.controller('mostra',function($scope){
$scope.visivel = {};
$scope.visivel = false;
$scope.mostra = function() {
if($scope.visivel==false) $scope.visivel=true;
else if($scope.visivel == true) $scope.visivel=false;
};
});
Also in the HTML use
ng-show="visivel" instead of ng-show="{{visivel}}"

InfoWindow with Bootstrap layout

I'm creating an info window and generating its content in javascript, and I want to have a two-column setup inside the window. However, the second div is showing up under the first, not beside (still pulled right though)
Here's a simplified version of what's getting passed to the setContent for the infowindow
var contentString ='<div class="info-window"><div class="row"><div class="pull-left span4">'
contentString += "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
contentString += '</div>';
contentString += "<div class='pull-right span1'>";
contentString += "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
contentString += "</div></div></div>";
Do infoWindows simply not play nice with the bootstrap scaffolding? Or is there a way to make this work as it should?
It looks like the problem was coming up because the right column was too tall. Fixing the height of the div and setting the overflow css to auto seems to have mostly fixed things, although I still seem to be somewhat constrained in what I can use for my span widths if I want things to line up properly

Trigger opening of a Zurb Foundation Accordion via URL hash link

I'd really like to be able to "activate" / "open" a Zurb Foundation Accordion via the URL with the accordion pane in questions hash.
So like example.com/page#accordion1
Is this possible already with Foundation or is it easy to implement? I honestly haven't got a clue :-/
Thanks in advance for any help given!
You can do this by adding an unique attribute to each accordion title <div class="title" data-ref="panel-1"> In this case I added a data-ref attribute. Then you will need to add some jQuery to look at the hash and if it is a accordion panel, then click that panel.
HTML
<ul class="accordion">
<li class="active">
<div class="title" data-ref="panel-1">
<h5>Accordion Panel 1</h5>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</li>
<li>
<div class="title" data-ref="panel-2">
<h5>Accordion Panel 2</h5>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</li>
<li>
<div class="title" data-ref="panel-3">
<h5>Accordion Panel 3</h5>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</li>
</ul>​
jQuery
jQuery(function() { // Document ready shorthand
// Get the hash and remove the #
var hash = window.location.hash.replace('#', '');
if (hash != '') {
// Cache targeted panel
$target = $('.title[data-ref="' + hash + '"]');
// Make sure panel is not already active
if (!$target.parents('li').hasClass('active')) {
// Trigger a click on item to change panel
$target.trigger('click');
}
}
});​
View in action
Edit code
One note: When in jsfiddle edit the hash will not work. Need to view in the full mode.
UPDATE
If you want to have a link that opens up a panel and updates hash. You will need to add a specific class to the link. In my example I add panel-btn
HTML
Goto Panel 2
jQuery
$('.panel-btn').click(function(e){
// Get the links href and remove the #
target_hash = $(this).attr('href').replace('#','');
// Click targeted panel
$('.title[data-ref="' + target_hash + '"]').trigger('click');
// Update hash, so that if page is refreshed, target panel will open
window.location.hash = target_hash;
// Stop all default link functionality
return false;
});
Updated jsfiddle view
Updated jsfiddle code
If you are looking for more of a history thing when each panel is clicked. You will need to add a click event to each .title and get its data-ref and change the hash to that, like this:
$('.title').click(function(){
// Get the data-ref
hash = $(this).attr('data-ref');
// Set hash to panels hash
window.location.hash = hash;
});
If you are using Foundation 5:
Foundations Accordion has a custom event click.fndtn.accordion you can use. It will take care of the proper open/closed states:
jQuery(document).ready(function($) {
var hash = window.location.hash;
if (hash != '') {
$('[data-accordion] [href="' + hash + '"]').trigger('click.fndtn.accordion');
}
});
See the example here, it will programatically open the second tab upon page load by detecting a window hash (simulated by a dummy hash in the code):
http://jsfiddle.net/ynyrrm99/
Link to the page without setting the a link to data-tab or any other settings. As of foundation 5.5.1 it will parse the uri with a hash on page load... meaning it doesn't matter how you set the originating link.
Set a variable to the hash in the URL, give the content panel div the same id as in your hash. Then add a class of .active to the panel with the same id as your link.
if(window.location.hash) {
var hash = window.location.hash;
$( hash ).addClass( "active" );
}

Categories

Resources