Javascript indexOf and replace - am I missing something - javascript

I have this javascript function;
i send it a number from a button and all go well untill the index-of method it has a problem.
CODE:
<script lang="ja" type="text/javascript">
function YellowChair(NumId)
{
if (document.getElementById("CheckBox" + NumId).checked)
{
document.getElementById("ChairImg" + NumId).src = "Images/YellowChair.png";
TypeTheNum(NumId, true);
}
else
{
document.getElementById("ChairImg" + NumId).src = "Images/BlueChair.png";
TypeTheNum(NumId, false);
}
}
function TypeTheNum(NumId,Add)
{
var Label = document.getElementById("SelectedSitsLabel");
var Hidden = document.getElementById("SelectedSitsHidden");
if (Label.innerHTML == "")
{
Label.textContent += NumId;
Hidden.textContent += NumId;
}
else
{
if (Add)
{
Label.textContent += "," + NumId;
}
else
{
// getting stuck here.
if (Label.indexOf((NumId + ",").toString()) != -1)
{
alert("1");
Label.replace((NumId + ",").toString(), "");
}
else
{
alert("ELSE");
Label.replace(("," + NumId).toString(), "");
}
}
}
Hidden.textContent = Label.textContent;
}
</script>
i thought maybe its because I insert text with textContent,
also , im pretty sure somthing is wrong with the replace.
Many thanks!

HTMLElement hasn't a method indexOf.String owned the method.remeber reset textContent if the textContent changed.
function YellowChair(NumId)
{
if (document.getElementById("CheckBox" + NumId).checked)
{
document.getElementById("ChairImg" + NumId).src = "Images/YellowChair.png";
TypeTheNum(NumId, true);
}
else
{
document.getElementById("ChairImg" + NumId).src = "Images/BlueChair.png";
TypeTheNum(NumId, false);
}
}
function TypeTheNum(NumId,Add)
{
var Label = document.getElementById("SelectedSitsLabel");
var Hidden = document.getElementById("SelectedSitsHidden");
if (Label.innerHTML == "")
{
Label.textContent += NumId;
Hidden.textContent += NumId;
}
else
{
if (Add)
{
Label.textContent += "," + NumId;
}
else
{
// getting stuck here.
if (Label.textContent.indexOf((NumId + ",").toString()) != -1)
{
alert("1");
Label.textContent=Label.textContent.replace((NumId + ",").toString(), "");
}
else
{
alert("ELSE");
Label.textContent=Label.textContent.replace(("," + NumId).toString(), "");
}
}
}
Hidden.textContent = Label.textContent;
}
<button onclick="TypeTheNum('foo')">Remove `foo`</button>
<div id="SelectedSitsLabel">foo,bar,baz</div>
<div id="SelectedSitsHidden"></div>

Label is a DOM element, not a string. So if you need to get characters from the text inside the element, you have to use something like var content = Label.textContent; content.indexOf() and then replace the textContent again after replacing it in the string.
Also as a sidenote, try to look up the differences between innerHTML, textContent and innerText so you can avoid future issues.

The function:
var element = document.getElementById(id);
Returns an Element object, or null but not an string.
Maybe you want to change your code to use textContent property which seems to be the one you are working on like:
if (Label.textContent.indexOf((NumId + ",").toString()) != -1){
alert("1");
Label.textContent.replace((NumId + ",").toString(), "");
}
else{
alert("ELSE");
Label.textContent.replace(("," + NumId).toString(), "");
}

You need to assign the replacement to something:
Label.textContent = Label.textContent.replace(…)

Related

How to replace only current wrong character on keyup for regex?

I wish to replace any character not in the passport format(A9999999) from my input text. I have written the following (jsfiddle here):
HTML
Doc Type <input id='docType' value = 'PASS'/> <br>
Doc ID <input id='docId'/>
JS:
$(document).ready(function () {
var docTypeVal = $("#docType").val();
$('#docId').keyup(function() {
if(docTypeVal == "PASS") {
var $th = $(this);
$th.attr("maxlength","8");
if($th.val().length <= 1) {
$th.val().replace(/[^a-zA-Z]/g, function(str) {
alert('You typed " ' + str + ' ".\n\nPlease use correct format.');
return '';
})
}
else if($th.val().length <= 8 && $th.val().length > 1) {
$th.val().replace(/^(?!.*^([a-zA-Z]){1}([0-9]){7}$)/, function(str) {
alert('You typed " ' + str + ' ".\n\nPlease use correct format.');
return '';
})
}
}
});
});
However, firstly, this doesn't replace any characters (wrong/right). Secondly, it gives the alert the moment I enter 2nd character onwards. It should accept the 1st char if it is alphabet (replace otherwise), from 2nd till 8th char it should accept only numbers (replace otherwise).
You can test this with 1 Regular Expression.
/^[a-z]?\d{0,7}$/i
This pattern will look A9 up to A9999999. It will fail on AA or 99.
Example: https://jsfiddle.net/Twisty/awL0onjg/20/
JavaScript
$(function() {
var docTypeVal = $("#docType").val();
$('#docId').keyup(function(e) {
var exc = [
11, // Tab
127, // Del
];
if (exc.indexOf(e.which) > -1) {
return true;
}
var term = $(this).val();
var re = /^[a-z]?\d{0,7}$/i;
console.log("Testing:", term, re.test(term));
if (re.test(term)) {
$(this).removeClass("invalid");
return true;
} else {
$(this).addClass("invalid");
}
});
});
Consider using .keydown() if you want to prevent the User from typing outside of that pattern. See More.
Fiddle Demo
Referred the JS of Twisty's and realized it should be as shown below:
if(docTypeVal == "PASS") {
$(this).attr("maxlength","8");
var term = $(this).val();
var re = /^[a-zA-Z]{1}\d{0,7}$/i;
if (re.test(term)) {
$(this).removeClass("invalid");
return true;
} else {
$(this).addClass("invalid");
$(this).val(term.replace(term.charAt(term.length-1),
function(str) {
alert('You typed " ' + str + ' ".\n\nPlease use correct format.');
return '';
}));
return false;
}
}

Checking a div for duplicates before appending to the list using jQuery

This should be trivial but I'm having issues...
Basically what I am trying to do is append a new "div" to "selected-courses" when a user clicks on a "course". This should happen if and only if the current course is not already in the "selected-courses" box.
The problem I'm running into is that nothing is appended to the "selected-courses" section when this is executed. I have used alert statements to make sure the code is in fact being run. Is there something wrong with my understanding of the way .on and .each work ? can I use them this way.
Here is a fiddle http://jsfiddle.net/jq9dth4j/
$(document).on("click", "div.course", function() {
var title = $( this ).find("span").text();
var match_found = 0;
//if length 0 nothing in list, no need to check for a match
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (matched == 0) {
var out = '<div class="selected-course">' + '' + title + ''+'</div>';
$("#selected-box").append(out);
}
});
//checks to see if clicked course is already in list before adding.
function match(str) {
$(".selected-course").each(function() {
var retval = 0;
if(str == this.text()) {
//course already in selected-course section
retval = 1;
return false;
}
});
return retval;
}
There was a couple of little issues in your fiddle.
See fixed fiddle: http://jsfiddle.net/jq9dth4j/1/
function match(str) {
var retval = 0;
$(".selected-course").each(function() {
if(str == $(this).text()) {
retval = 1;
return false;
}
});
return retval;
}
You hadn't wrapped your this in a jquery object. So it threw an exception saying this had no method text().
Second your retval was declared inside the each so it wasn't available to return outside the each, wrong scope.
Lastly the if in the block:
if (matched== 0) {
var out = '';
out += '<div class="selected-course">' + '' + title + ''+'</div>';
$("#selected-box").append(out);
}
was looking at the wrong variable it was looking at matched which didn't exist causing an exception.
Relying on checking what text elements contain is not the best approach to solve this kind of question. It is prone to errors (as you have found out), it can be slow, it gives you long code and it is sensitive to small changes in the HTML. I would recommend using custom data-* attributes instead.
So you would get HTML like this:
<div class="course" data-course="Kite Flying 101">
<a href="#">
<span>Kite Flying 101</span>
</a>
</div>
Then the JS would be simple like this:
$(document).on('click', 'div.course', function() {
// Get the name of the course that was clicked from the attribute.
var title = $(this).attr('data-course');
// Create a selector that selects everything with class selected-course and the right data-course attribute.
var selector = '.selected-course[data-course="' + title + '"]';
if($(selector).length == 0) {
// If the selector didn't return anything, append the div.
// Do note that we need to add the data-course attribute here.
var out = '<div class="selected-course" data-course="' + title + '">' + title + '</div>';
$('#selected-box').append(out);
}
});
Beware of case sensitivity in course names, though!
Here is a working fiddle.
Try this code, read comment for where the changes are :
$(document).on("click", "div.course", function () {
var title = $(this).find("span").text().trim(); // use trim to remove first and end whitespace
var match_found = 0;
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (match_found == 0) { // should change into match_found
var out = '';
out += '<div class="selected-course">' + '' + title + '' + '</div>';
$("#selected-box").append(out);
}
});
function match(str) {
var retval = 0; // this variable should place in here
$(".selected-course").each(function () {
if (str == $(this).find('a').text().trim()) { // find a tag to catch values, and use $(this) instead of this
retval = 1;
return false;
}
});
return retval; // now can return variable, before will return undefined
}
Updated DEMO
Your Issues are :
1.this.text() is not valid. you have to use $(this).text().
2.you defined var retval = 0; inside each statement and trying to return it outside each statement. so move this line out of the each statement.
3.matched is not defined . it should be match_found in line if (matched == 0) {.
4. use trim() to get and set text, because text may contain leading and trailing spaces.
Your updated JS is
$(document).on("click", "div.course", function () {
var title = $(this).find("span").text();
var match_found = 0;
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (match_found == 0) {
var out = '<div class="selected-course">' + '' + title + '' + '</div>';
$("#selected-box").append(out);
}
});
function match(str) {
var retval = 0;
$(".selected-course").each(function () {
if (str.trim() == $(this).text().trim()) {
retval = 1;
return false;
}
});
return retval;
}
Updated you Fiddle

Why html-element text doesn't replace?

I use javascript (jQuery) to toggle text of html-element (span):
function TextToogle(element, text) {
if (element.html() == '-' + text) {
element.html(text.replace(element.html(), '+' + text));
}
else {
element.html(text.replace(element.html(), '-' + text));
}
}
I give two arguments for my function:
1) element - html Object
2) text - default text of span
My goal is toggle the span text from "+text" to "-text" and vice versa.
But script doesn't work correctly. When function toggle text to "+text", as result I see "text". The toggle to "-text" works correctly.
I would just replace inside a callback, seems so much simpler
element.text(function(_, txt) {
return txt.replace(/[+-]/g, function(x) {
return x == '+' ? '-' : '+';
});
});
FIDDLE
Based on you is comparison (element.html() == '-' + text) your function can be simpler. You don't need text.replace(element.html(), '+' + text) part:
function TextToogle(element, text) {
if (element.text() == '-' + text) {
element.text('+' + text);
}
else {
element.text('-' + text);
}
}
However relying on text comparison is not ideal. I would use CSS which is not text dependent:
$('.text-toggle').click(function() {
$(this).toggleClass('active');
});
CSS
.text-toggle:before {
content: '+';
}
.text-toggle.active:before {
content: '-';
}
There is obvious advantage here is that you can style your +/- easily, you can set a background image, chage font-size, etc. While you would'n be able this with your original approach.
Demo: http://jsfiddle.net/dfsq/mvj5c/
function toggleText(text) {
return {'-':'+', '+':'-'}[text[0]]+text.slice(1);
}
element.html(toggleText(element.html()));
See simple example.
You've text -abc. Now it's fail on both of the checks.
Why not do this
function TextToogle(element, text) {
var check = text.splice(0, 1);
if (check === "-") {
element.html("+" + text.substring(1, text.length));
}
else {
element.html("-" + text.substring(1, text.length));
}
}
try this code
$('span').click(function(){
var
$this = $(this),
thisText = $this.text();
$this.text($this.text() === "-" + thisText ? ("+" + thisText) : ("-" + thisText));
});

Text area validation in javascript for html image tag

I want to validate a text area for img tag when it is duplicated. example, if i entered the image tag with src i should enter the same source with tag again i need to show alert how it could be done. my snippet to check whether the image is there or not. but i need to do for above validation also...
function validateEditor() {
var editor_val = $('#asset_html').val(), iSrc;
// Check for empty string
if(!string_IsEmpty(editor_val)) {
// Check whether img is available
if(editor_val.match(/img/g)) {
var src_cnt = (editor_val.match(/img/g).length);
//console.log(editor_val.match(/src/g).length);
$('#asset_html_preview').html(editor_val);
for(var j = 1; j <= src_cnt; j++) {
if($('#asset_html_preview img:nth-child(1)').attr('src')) {
iSrc = $('#asset_html_preview img:nth-child(1)').attr('src');
if(iSrc.indexOf('http://') != -1) {
$('#asset_html_preview img:nth-child(' + j + ')')
.error(function() { alert('Check ur image src'); });
//break;
}
}
}
}
}
}
You may be looking for this:
var arr = {};
var $div = $('<div />').html($('textarea').val());
$div.find('img').each(function (i) {
var src = $(this).attr('src');
if (src.indexOf('http://') >= 0 && arr[src] == undefined) {
arr[src] = 'foobar';
} else if (arr[src] !== undefined) {
alert('This url `' + src + '` already exists');
} else {
alert('This url `' + src + '` is wrong');
}
});
Demo: http://jsfiddle.net/LXgWU/3/
Assuming that your var src_cnt work perfect.
var src_cnt = (editor_val.match(/img/g).length);
if(src_cnt == 1)
{
alert("Plz choose Unique Image");
return false;
}

Get the DOM path of the clicked <a>

HTML
<body>
<div class="lol">
<a class="rightArrow" href="javascriptVoid:(0);" title"Next image">
</div>
</body>
Pseudo Code
$(".rightArrow").click(function() {
rightArrowParents = this.dom(); //.dom(); is the pseudo function ... it should show the whole
alert(rightArrowParents);
});
Alert message would be:
body div.lol a.rightArrow
How can I get this with javascript/jquery?
Here is a native JS version that returns a jQuery path. I'm also adding IDs for elements if they have them. This would give you the opportunity to do the shortest path if you see an id in the array.
var path = getDomPath(element);
console.log(path.join(' > '));
Outputs
body > section:eq(0) > div:eq(3) > section#content > section#firehose > div#firehoselist > article#firehose-46813651 > header > h2 > span#title-46813651
Here is the function.
function getDomPath(el) {
var stack = [];
while ( el.parentNode != null ) {
console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
if ( el.hasAttribute('id') && el.id != '' ) {
stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
} else if ( sibCount > 1 ) {
stack.unshift(el.nodeName.toLowerCase() + ':eq(' + sibIndex + ')');
} else {
stack.unshift(el.nodeName.toLowerCase());
}
el = el.parentNode;
}
return stack.slice(1); // removes the html element
}
Using jQuery, like this (followed by a solution that doesn't use jQuery except for the event; lots fewer function calls, if that's important):
$(".rightArrow").click(function () {
const rightArrowParents = [];
$(this)
.parents()
.addBack()
.not("html")
.each(function () {
let entry = this.tagName.toLowerCase();
const className = this.className.trim();
if (className) {
entry += "." + className.replace(/ +/g, ".");
}
rightArrowParents.push(entry);
});
console.log(rightArrowParents.join(" "));
return false;
});
Live example:
$(".rightArrow").click(function () {
const rightArrowParents = [];
$(this)
.parents()
.addBack()
.not("html")
.each(function () {
let entry = this.tagName.toLowerCase();
const className = this.className.trim();
if (className) {
entry += "." + className.replace(/ +/g, ".");
}
rightArrowParents.push(entry);
});
console.log(rightArrowParents.join(" "));
return false;
});
<div class=" lol multi ">
Click here
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
(In the live examples, I've updated the class attribute on the div to be lol multi to demonstrate handling multiple classes.)
That uses parents to get the ancestors of the element that was clicked, removes the html element from that via not (since you started at body), then loops through creating entries for each parent and pushing them on an array. Then we use addBack to add the a back into the set, which also changes the order of the set to what you wanted (parents is special, it gives you the parents in the reverse of the order you wanted, but then addBack puts it back in DOM order). Then it uses Array#join to create the space-delimited string.
When creating the entry, we trim className (since leading and trailing spaces are preserved, but meaningless, in the class attribute), and then if there's anything left we replace any series of one or more spaces with a . to support elements that have more than one class (<p class='foo bar'> has className = "foo bar", so that entry ends up being p.foo.bar).
Just for completeness, this is one of those places where jQuery may be overkill, you can readily do this just by walking up the DOM:
$(".rightArrow").click(function () {
const rightArrowParents = [];
for (let elm = this; elm; elm = elm.parentNode) {
let entry = elm.tagName.toLowerCase();
if (entry === "html") {
break;
}
const className = elm.className.trim();
if (className) {
entry += "." + className.replace(/ +/g, ".");
}
rightArrowParents.push(entry);
}
rightArrowParents.reverse();
console.log(rightArrowParents.join(" "));
return false;
});
Live example:
$(".rightArrow").click(function () {
const rightArrowParents = [];
for (let elm = this; elm; elm = elm.parentNode) {
let entry = elm.tagName.toLowerCase();
if (entry === "html") {
break;
}
const className = elm.className.trim();
if (className) {
entry += "." + className.replace(/ +/g, ".");
}
rightArrowParents.push(entry);
}
rightArrowParents.reverse();
console.log(rightArrowParents.join(" "));
return false;
});
<div class=" lol multi ">
Click here
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
There we just use the standard parentNode property (or we could use parentElement) of the element repeatedly to walk up the tree until either we run out of parents or we see the html element. Then we reverse our array (since it's backward to the output you wanted), and join it, and we're good to go.
I needed a native JS version, that returns CSS standard path (not jQuery), and deals with ShadowDOM. This code is a minor update on Michael Connor's answer, just in case someone else needs it:
function getDomPath(el) {
if (!el) {
return;
}
var stack = [];
var isShadow = false;
while (el.parentNode != null) {
// console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
// get sibling indexes
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
// if ( el.hasAttribute('id') && el.id != '' ) { no id shortcuts, ids are not unique in shadowDom
// stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
// } else
var nodeName = el.nodeName.toLowerCase();
if (isShadow) {
nodeName += "::shadow";
isShadow = false;
}
if ( sibCount > 1 ) {
stack.unshift(nodeName + ':nth-of-type(' + (sibIndex + 1) + ')');
} else {
stack.unshift(nodeName);
}
el = el.parentNode;
if (el.nodeType === 11) { // for shadow dom, we
isShadow = true;
el = el.host;
}
}
stack.splice(0,1); // removes the html element
return stack.join(' > ');
}
Here is a solution for exact matching of an element.
It is important to understand that the selector (it is not a real one) that the chrome tools show do not uniquely identify an element in the DOM. (for example it will not distinguish between a list of consecutive span elements. there is no positioning/indexing info)
An adaptation from a similar (about xpath) answer
$.fn.fullSelector = function () {
var path = this.parents().addBack();
var quickCss = path.get().map(function (item) {
var self = $(item),
id = item.id ? '#' + item.id : '',
clss = item.classList.length ? item.classList.toString().split(' ').map(function (c) {
return '.' + c;
}).join('') : '',
name = item.nodeName.toLowerCase(),
index = self.siblings(name).length ? ':nth-child(' + (self.index() + 1) + ')' : '';
if (name === 'html' || name === 'body') {
return name;
}
return name + index + id + clss;
}).join(' > ');
return quickCss;
};
And you can use it like this
console.log( $('some-selector').fullSelector() );
Demo at http://jsfiddle.net/gaby/zhnr198y/
The short vanilla ES6 version I ended up using:
Returns the output I'm used to read in Chrome inspector e.g body div.container input#name
function getDomPath(el) {
let nodeName = el.nodeName.toLowerCase();
if (el === document.body) return 'body';
if (el.id) nodeName += '#' + el.id;
else if (el.classList.length)
nodeName += '.' + [...el.classList].join('.');
return getDomPath(el.parentNode) + ' ' + nodeName;
};
I moved the snippet from T.J. Crowder to a tiny jQuery Plugin. I used the jQuery version of him even if he's right that this is totally unnecessary overhead, but i only use it for debugging purpose so i don't care.
Usage:
Html
<html>
<body>
<!-- Two spans, the first will be chosen -->
<div>
<span>Nested span</span>
</div>
<span>Simple span</span>
<!-- Pre element -->
<pre>Pre</pre>
</body>
</html>
Javascript
// result (array): ["body", "div.sampleClass"]
$('span').getDomPath(false)
// result (string): body > div.sampleClass
$('span').getDomPath()
// result (array): ["body", "div#test"]
$('pre').getDomPath(false)
// result (string): body > div#test
$('pre').getDomPath()
Repository
https://bitbucket.org/tehrengruber/jquery.dom.path
I've been using Michael Connor's answer and made a few improvements to it.
Using ES6 syntax
Using nth-of-type instead of nth-child, since nth-of-type looks for children of the same type, rather than any child
Removing the html node in a cleaner way
Ignoring the nodeName of elements with an id
Only showing the path until the closest id, if any. This should make the code a bit more resilient, but I left a comment on which line to remove if you don't want this behavior
Use CSS.escape to handle special characters in IDs and node names
~
export default function getDomPath(el) {
const stack = []
while (el.parentNode !== null) {
let sibCount = 0
let sibIndex = 0
for (let i = 0; i < el.parentNode.childNodes.length; i += 1) {
const sib = el.parentNode.childNodes[i]
if (sib.nodeName === el.nodeName) {
if (sib === el) {
sibIndex = sibCount
break
}
sibCount += 1
}
}
const nodeName = CSS.escape(el.nodeName.toLowerCase())
// Ignore `html` as a parent node
if (nodeName === 'html') break
if (el.hasAttribute('id') && el.id !== '') {
stack.unshift(`#${CSS.escape(el.id)}`)
// Remove this `break` if you want the entire path
break
} else if (sibIndex > 0) {
// :nth-of-type is 1-indexed
stack.unshift(`${nodeName}:nth-of-type(${sibIndex + 1})`)
} else {
stack.unshift(nodeName)
}
el = el.parentNode
}
return stack
}
All the examples from other ответов did not work very correctly for me, I made my own, maybe my version will be more suitable for the rest
const getDomPath = element => {
let templateElement = element
, stack = []
for (;;) {
if (!!templateElement) {
let attrs = ''
for (let i = 0; i < templateElement.attributes.length; i++) {
const name = templateElement.attributes[i].name
if (name === 'class' || name === 'id') {
attrs += `[${name}="${templateElement.getAttribute(name)}"]`
}
}
stack.push(templateElement.tagName.toLowerCase() + attrs)
templateElement = templateElement.parentElement
} else {
break
}
}
return stack.reverse().slice(1).join(' > ')
}
const currentElement = document.querySelectorAll('[class="serp-item__thumb justifier__thumb"]')[7]
const path = getDomPath(currentElement)
console.log(path)
console.log(document.querySelector(path))
console.log(currentElement)
var obj = $('#show-editor-button'),
path = '';
while (typeof obj.prop('tagName') != "undefined"){
if (obj.attr('class')){
path = '.'+obj.attr('class').replace(/\s/g , ".") + path;
}
if (obj.attr('id')){
path = '#'+obj.attr('id') + path;
}
path = ' ' +obj.prop('tagName').toLowerCase() + path;
obj = obj.parent();
}
console.log(path);
hello this function solve the bug related to current element not show in the path
check this now
$j(".wrapper").click(function(event) {
selectedElement=$j(event.target);
var rightArrowParents = [];
$j(event.target).parents().not('html,body').each(function() {
var entry = this.tagName.toLowerCase();
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}else if(this.id){
entry += "#" + this.id;
}
entry=replaceAll(entry,'..','.');
rightArrowParents.push(entry);
});
rightArrowParents.reverse();
//if(event.target.nodeName.toLowerCase()=="a" || event.target.nodeName.toLowerCase()=="h1"){
var entry = event.target.nodeName.toLowerCase();
if (event.target.className) {
entry += "." + event.target.className.replace(/ /g, '.');
}else if(event.target.id){
entry += "#" + event.target.id;
}
rightArrowParents.push(entry);
// }
where $j = jQuery Variable
also solve the issue with .. in class name
here is replace function :
function escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
Thanks
$(".rightArrow")
.parents()
.map(function () {
var value = this.tagName.toLowerCase();
if (this.className) {
value += '.' + this.className.replace(' ', '.', 'g');
}
return value;
})
.get().reverse().join(", ");

Categories