Reference Url :http://snippets.dzone.com/posts/show/4349
Given a node this will return an array containing the XPath
Usage:
getXPath(document.getElementById('myelement'));
function getXPath(node, path) { path = path || []; if(node.parentNode) { path = getXPath(node.parentNode, path); } if(node.previousSibling) { var count = 1; var sibling = node.previousSibling do { if(sibling.nodeType == 1 && sibling.nodeName == node.nodeName) {count++;} sibling = sibling.previousSibling; } while(sibling); if(count == 1) {count = null;} } else if(node.nextSibling) { var sibling = node.nextSibling; do { if(sibling.nodeType == 1 && sibling.nodeName == node.nodeName) { var count = 1; sibling = null; } else { var count = null; sibling = sibling.previousSibling; } } while(sibling); } if(node.nodeType == 1) { path.push(node.nodeName.toLowerCase() + (node.id ? "[@id='"+node.id+"']" : count > 0 ? "["+count+"]" : '')); } return path; };
Get xpath expression for a document element
// given a document element returns the xpath string expression of that element.
function getElementXPath(elt) { var path = ""; for (; elt && elt.nodeType == 1; elt = elt.parentNode) { idx = getElementIdx(elt); xname = elt.tagName; if (idx > 1) xname += "[" + idx + "]"; path = "/" + xname + path; } return path; } function getElementIdx(elt) { var count = 1; for (var sib = elt.previousSibling; sib ; sib = sib.previousSibling) { if(sib.nodeType == 1 && sib.tagName == elt.tagName) count++ } return count; }
DOM mouseover element selection and isolation
DOM ISO.v.0.3.0.7.bookmarklet.js
bookmarklet for selecting and isolating an element on a page.
two sections:
section 1: Mouseover DOM, setup and handle mouse events and show information about element in informational div. Click to select, Any key to cancel.
section 2: Element Isolation with help of XPath. prompt user for XPath expression e.g., //DIV[@id='post-body']. then use XPath to select all elements not(ancestor or descendant or self), then delete those elements. also ignore self-or-descendants of head and title.
tools:
Ruderman's javascript development environment: https://www.squarefree.com/bookmarklets/webdevel.html#jsenv
Mielczarek's js to bookmarklet generator: http://ted.mielczarek.org/code/mozilla/bookmarklet.html
(function() { //GLOBALS //globals for classMausWork var gSelectedElement; //currently only one selection var gHoverElement; //whatever element the mouse is over var gHovering=false; //mouse is over something var gObjArrMW=[]; //global array of classMausWork objects. for removing event listeners when done selecting. //extended var infoDiv; //currently just container for InfoDivHover, might add more here var infoDivHover; //container for hoverText text node. var hoverText; //show information about current element that the mouse is over //const EXPERIMENTAL_NEW_CODE=true; //debugging. new features. //START SetupDOMSelection(); //(Section 1) Element Selection function SetupDOMSelection() { { //setup event listeners //var pathx="//div | //span | //table | //td | //tr | //ul | //ol | //li | //p"; var pathx="//div | //span | //table | //th | //td | //tr | //ul | //ol | //li | //p | //iframe"; var selection=$XPathSelect(pathx); for(var element, i=0;element=selection(i);i++) { if(element.tagName.match(/^(div|span|table|td|tr|ul|ol|li|p)$/i)) //redundant check. { var m = new classMausWork(element); gObjArrMW.push(m); attachMouseEventListeners(m); } } document.body.addEventListener('mousedown',MiscEvent,false); document.body.addEventListener('mouseover',MiscEvent,false); document.body.addEventListener('mouseout',MiscEvent,false); document.addEventListener('keypress',MiscEvent,false); } { //setup informational div to show which element the mouse is over. infoDiv=document.createElement('div'); var s=infoDiv.style; s.position='fixed'; s.top='0'; s.right='0'; s.display='block'; s.width='auto'; s.padding='0px'; document.body.appendChild(infoDiv); infoDivHover=document.createElement('div'); s=infoDivHover.style; s.fontWeight='bold'; s.padding='3px'; s.Opacity='0.8'; s.borderWidth='thin'; s.borderStyle='solid'; s.borderColor='white'; s.backgroundColor='black'; s.color='white'; infoDiv.appendChild(infoDivHover); hoverText=document.createTextNode('selecting'); infoDivHover.appendChild(hoverText); } } function CleanupDOMSelection() { for(var m; m=gObjArrMW.pop(); ) { detachMouseEventListeners(m); } ElementRemove(infoDiv); document.body.removeEventListener('mousedown',MiscEvent,false); document.body.removeEventListener('mouseover',MiscEvent,false); document.body.removeEventListener('mouseout',MiscEvent,false); document.removeEventListener('keypress',MiscEvent,false); } function attachMouseEventListeners(c) { //c is object of class classMausWork c.element.addEventListener("mouseover",c.mouse_over,false); c.element.addEventListener("mouseout",c.mouse_out,false); c.element.addEventListener("mousedown",c.mouse_click,false); } function detachMouseEventListeners(c) { //c is object of class classMausWork c.resetElementStyle(); c.element.removeEventListener("mouseover",c.mouse_over,false); c.element.removeEventListener("mouseout",c.mouse_out,false); c.element.removeEventListener("mousedown",c.mouse_click,false); } //mouse event handling class for element, el. function classMausWork(element) { //store information about the element this object is assigned to handle. element, original style, etc. this.element=element; var elementStyle=element.getAttribute('style'); var target; this.mouse_over=function(ev) { if(gHovering)return; var e=element; var s=e.style; s.backgroundColor='yellow'; s.borderWidth='thin'; s.borderColor='lime'; s.borderStyle='solid'; InfoMSG(ElementInfo(e),'yellow','blue','yellow'); gHoverElement=e; gHovering=true; target=ev.target; ev.stopPropagation(); }; this.mouse_out=function(ev) { if(!gHovering)return; if(gHoverElement!=element ||ev.target!=target)return; var e=element; e.setAttribute('style',elementStyle); InfoMSG('-','white','black','white'); gHoverElement=null; gHovering=false; target=null; //ev.stopPropagation(); }; this.mouse_click=function(ev) { if(!gHovering)return; if(gHoverElement!=element ||ev.target!=target)return; var e=element; e.setAttribute('style',elementStyle); ev.stopPropagation(); CleanupDOMSelection(); gHoverElement=null; gHovering=false; target=null; if(ev.button==0) { gSelectedElement=e; ElementSelected(e); //finished selecting, cleanup then move to next part (section 2), element isolation. } }; this.resetElementStyle=function() { element.setAttribute('style',elementStyle); }; } function MiscEvent(ev) //keypress, and mouseover/mouseout/mousedown event on body. cancel selecting. { if(ev.type=='mouseout' && !gHovering) { InfoMSG('-','white','black','white'); } else if(ev.type=='mouseover' && !gHovering) { InfoMSG('cancel','yellow','red','yellow'); } else //keypress on document or mousedown on body, cancel ops. { CleanupDOMSelection(); } } function InfoMSG(text,color,bgcolor,border) { var s=infoDivHover.style; if(color)s.color=color; if(bgcolor)s.backgroundColor=bgcolor; if(border)s.borderColor=border; if(text)hoverText.data=text; } //(Section 2) Element Isolation function ElementSelected(element) //finished selecting element. setup string to prompt user. { PromptUserXpath(ElementInfo(element)); } function PromptUserXpath(defaultpath) //prompt user, isolate element. { var userpath = prompt("XPath of elements to isolate : ", defaultpath); if(userpath && userpath.length>0) { var addPredicate = "[count(./ancestor-or-self::head)=0][count(./ancestor-or-self::title)=0]"; //exclude head & title elements from selection so they aren't removed var addPath = "//script | //form | //object | //embed"; //include these elements in selection for removal var pathx=TransformXPath_NoAncestorDescendentSelf(userpath, addPredicate, addPath); //the xpath selection of all elements to be removed/deleted. try { var element; var elements=$XPathSelect(pathx); for(var i=0;element=elements(i);i++) { if(!element.nodeName.match(/^(head|title)$/i)) //redundant check. { ElementRemove(element); } } } catch(err) { alert("wtf: "+err); } } } //support function $XPathSelect(p, context) { if (!context) context = document; var i, arr = [], xpr = document.evaluate(p, context, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); return function(x) { return xpr.snapshotItem(x); }; //closure. wooot! returns function-type array of elements (usually elements, or something else depending on the xpath expression). } function ElementRemove(e) { if(e)e.parentNode.removeChild(e); } function ElementInfo(element) { var txt=''; if(element) { txt=element.tagName.toLowerCase(); //txt=element.tagName; txt=attrib(txt,element,'id'); txt=attrib(txt,element,'class'); txt='//'+txt; } return txt; function attrib(t,e,a) { if(e.hasAttribute(a)) { t+="[@"+a+"='"+e.getAttribute(a)+"']"; } return t; } } //function to 'invert' the XPath by selecting all elements that are not ancestor and not descendent and not self. function TransformXPath_NoAncestorDescendentSelf(u, includePredicates, includePaths) { //sample input (u): //div[@class='sortbox'] //sample output //*[ not(./descendant-or-self::*=//div[@class='sortbox'])][ not(./ancestor-or-self::*=//div[@class='sortbox'])] //sample output with additional conditions: //*[ not(./descendant-or-self::*=//div[@class='sortbox'])][ not(./ancestor-or-self::*=//div[@class='sortbox'])][count(./ancestor-or-self::head)=0][count(./ancestor-or-self::title)=0] //obsolete method. much faster but can only be used for limited types of (simple) xpath expressions -- unlike the current version, which should be able to convert any xpath. //input: table[@id='topbar'] //output: //*[not(./descendant-or-self::table[@id='topbar']) and not(./ancestor-or-self::table[@id='topbar'])] //output (alternative): //*[count(./descendant-or-self::table[@id='topbar'])=0 and count(./ancestor-or-self::table[@id='topbar'])=0] var o1= './descendant-or-self::*='+gr(u); o1= 'not' + gr(o1); o1= nt(o1); var o2= './ancestor-or-self::*='+gr(u); o2= 'not' + gr(o2); o2= nt(o2); var o= '//*'+o1+o2; if(includePredicates && includePredicates.length>0) o += includePredicates; if(includePaths && includePaths.length>0) o += ' | ' + includePaths; return o; function nt(term){return wrap(term,'[]');} //node test; predicate - enclose with bracket. function gr(term){return wrap(term,'()');} //group - parenthesize. function wrap(term, enclosure){return enclosure.charAt(0)+term+enclosure.charAt(1);} } })();
Js code for random number
Math.randomMax = function(maxVal,asFloat){ var val = Math.random()*maxVal; return asFloat?val:Math.round(val); }For a random integer between 0 and 10 (inclusive), simply:
var theNumber = Math.randomMax( 10 );
For a random float value between 0 and 10, pass a truth value to the second parameter:
var theNumber = Math.randomMax( 10, true );
There is also an get path plugin for JQuery, check it out.