Get the hash value which was before hashchange - javascript

Suppose my html is
One
Two
and Js is
$(window).on("hashchange"){
alert(document.location.hash);
}
I want to get the hash value which was before hash change .Is it Possible?If yes ,How?

use that
$(window).on("hashchange", function(e){
console.log(e.originalEvent.oldURL)
console.log(e.originalEvent.newURL)
})​;
Demo: http://jsbin.com/ulumil/

You have to track the last hash, for example:
var currentHash = function() {
return location.hash.replace(/^#/, '')
}
var last_hash
var hash = currentHash()
$(window).bind('hashchange', function(event){
last_hash = hash
hash = currentHash()
console.log('hash changed from ' + last_hash + ' to ' + hash)
});

Actually the solution provided by Amit works but with jquery library and crossplatform as well.
Here is a more simplified solution using core javascript and crossbrowser as well. (checked with latest version of IE/FF/Chrome/Safari)
window.onhashchange = function(e){
console.log(e);
var oldURL = e.oldURL;
var newURL = e.newURL;
console.log("old url = " + oldURL);
console.log("new url = " + newURL);
var oldHash = oldURL.split("#")[1];
var newHash = newURL.split("#")[1];
console.log(oldHash);
console.log(newHash);
};

Don't use
$(window).on("hashchange", function(e){
console.log(e.originalEvent.oldURL)
console.log(e.originalEvent.newURL)
})​;
It won't work on IE and probably elsewhere too.
Use this rather.
(function(w, $){
var UrlHashMonitor = {};
UrlHashMonitor.oldHash = '';
UrlHashMonitor.newHash = '';
UrlHashMonitor.oldHref = '';
UrlHashMonitor.newHref = '';
UrlHashMonitor.onHashChange = function(f){
$(window).on('hashchange', function(e){
UrlHashMonitor.oldHash = UrlHashMonitor.newHash;
UrlHashMonitor.newHash = w.location.hash;
UrlHashMonitor.oldHref = UrlHashMonitor.newHref;
UrlHashMonitor.newHref = w.location.href;
f(e);
});
};
UrlHashMonitor.init = function(){
UrlHashMonitor.oldHash = UrlHashMonitor.newHash = w.location.hash;
UrlHashMonitor.oldHref = UrlHashMonitor.newHref = w.location.href;
};
w.UrlHashMonitor = UrlHashMonitor;
return UrlHashMonitor;
})(window, window.jQuery);
/*
* USAGE EXAMPLE
*/
UrlHashMonitor.init();
UrlHashMonitor.onHashChange(function(){
console.log('oldHash: ' + UrlHashMonitor.oldHash);
console.log('newHash: ' + UrlHashMonitor.newHash);
console.log('oldHref: ' + UrlHashMonitor.oldHref);
console.log('newHref: ' + UrlHashMonitor.newHref);
//do other stuff
});
This should work in all modern browsers.
DEMO: https://output.jsbin.com/qafupu#one

Related

Use dropdown selection in URL

I'm following the answer here to use the selection from a dropdown in a URL. I am using asp.net core, using:
asp-page="/Page" asp-page-handler="Action"
To do the redirect
The script below (from the link above) works great, except if you select an item from the dropdown then select a different one (and on and on), it appends both to the URL.
<script>
$("[name=selectedAnalyst]").on("change", function () {
var analystId = $(this).val();
var accept = $(this).closest('td').next().find("a")[0];
var oldUrl = accept.href;
var newUrl = oldUrl + "&analystid=" + analystId;
$(accept).attr("href", newUrl);
})
I tried scrubbing the parameter in question (using params.delete) but it's not working:
<script>
$("[name=selectedAnalyst]").on("change", function () {
var analystId = $(this).val();
var accept = $(this).closest('td').next().find("a")[0];
var oldUrl = accept.href;
let params = new URLSearchParams(oldUrl.search);
params.delete('analystid')
var newUrl = oldUrl + "&analystid=" + analystId;
$(accept).attr("href", newUrl);
})
Is there a way to get the above script to work how I envision, or a better way to do this?
Thank you
it seems that
let params = new URLSearchParams(oldUrl.search);
params.delete('analystid')
does not work
I tried with the codes and it could work
<script>
$("[name=selectedAnalyst]").on("change", function () {
var analystId = $(this).val();
var accept = $(this).closest('td').next().find("a")[0];
var oldUrl = accept.href;
var a = oldUrl.indexOf("analystid");
console.log(a);
if (a == -1)
{
var newUrl = oldUrl + "&analystid=" + analystId;
}
else
{
var newUrl= oldUrl.substring(0, oldUrl.length - 1) + analystId;
}
console.log(newUrl);
console.log(oldUrl);
$(accept).attr("href", newUrl);
})
</script>
Building on what Ruikai Feng posted I think this is working:
$("[name=selectedAnalyst]").on("change", function () {
var analystId = $(this).val();
var accept = $(this).closest('td').next().find("a")[0];
var oldUrl = accept.href;
var a = oldUrl.indexOf("analystId ");
if (a == -1) {
var newUrl = oldUrl + "&analystId =" + analystId ;
}
else {
var newUrl = oldUrl.substring(0, a - 1) + "&analystId =" + analystId;
}
$(accept).attr("href", newUrl);
})

Looping through array and clicking each link via CasperJS [duplicate]

I'm having trouble clicking all JavaScript based links in a DOM and saving the
output. The links have the form
<a id="html" href="javascript:void(0);" onclick="goToHtml();">HTML</a>
the following code works great:
var casper = require('casper').create();
var fs = require('fs');
var firstUrl = 'http://www.testurl.com/test.html';
var css_selector = '#jan_html';
casper.start(firstUrl);
casper.thenClick(css_selector, function(){
console.log("whoop");
});
casper.waitFor(function check() {
return this.getCurrentUrl() != firstUrl;
}, function then() {
console.log(this.getCurrentUrl());
var file_title = this.getTitle().split(' ').join('_') + '.html';
fs.write(file_title, this.getPageContent());
});
casper.run();
However, how can I get this to work with a selector of "a", clicking all
available links and saving content? I'm not sure how to get the clickWhileSelector to remove nodes from the selector as is done here: Click on all links matching a selector
I have this script that first will get all links from a page then save 'href' attributes to an array, then will iterate over this array and then open each link one by one and echo the url :
var casper = require('casper').create({
logLevel:"verbose",
debug:true
});
var links;
casper.start('http://localhost:8000');
casper.then(function getLinks(){
links = this.evaluate(function(){
var links = document.getElementsByTagName('a');
links = Array.prototype.map.call(links,function(link){
return link.getAttribute('href');
});
return links;
});
});
casper.then(function(){
this.each(links,function(self,link){
self.thenOpen(link,function(a){
this.echo(this.getCurrentUrl());
});
});
});
casper.run(function(){
this.exit();
});
rusln's answer works great if all the links have a meaningful href attribute (actual URL). If you want to click every a that also triggers a javascript function, you may need to iterate some other way over the elements.
I propose using the XPath generator from stijn de ryck for an element.
You can then sample all XPaths that are on the page.
Then you open the page for every a that you have the XPath for and click it by XPath.
Wait a little if it is a single page application
Do something
var startURL = 'http://localhost:8000',
xPaths
x = require('casper').selectXPath;
casper.start(startURL);
casper.then(function getLinks(){
xPaths = this.evaluate(function(){
// copied from https://stackoverflow.com/a/5178132/1816580
function createXPathFromElement(elm) {
var allNodes = document.getElementsByTagName('*');
for (var segs = []; elm && elm.nodeType == 1; elm = elm.parentNode) {
if (elm.hasAttribute('id')) {
var uniqueIdCount = 0;
for (var n=0;n < allNodes.length;n++) {
if (allNodes[n].hasAttribute('id') && allNodes[n].id == elm.id) uniqueIdCount++;
if (uniqueIdCount > 1) break;
};
if ( uniqueIdCount == 1) {
segs.unshift('id("' + elm.getAttribute('id') + '")');
return segs.join('/');
} else {
segs.unshift(elm.localName.toLowerCase() + '[#id="' + elm.getAttribute('id') + '"]');
}
} else if (elm.hasAttribute('class')) {
segs.unshift(elm.localName.toLowerCase() + '[#class="' + elm.getAttribute('class') + '"]');
} else {
for (i = 1, sib = elm.previousSibling; sib; sib = sib.previousSibling) {
if (sib.localName == elm.localName) i++; };
segs.unshift(elm.localName.toLowerCase() + '[' + i + ']');
};
};
return segs.length ? '/' + segs.join('/') : null;
};
var links = document.getElementsByTagName('a');
var xPaths = Array.prototype.map.call(links, createXPathFromElement);
return xPaths;
});
});
casper.then(function(){
this.each(xPaths, function(self, xpath){
self.thenOpen(startURL);
self.thenClick(x(xpath));
// waiting some time may be necessary for single page applications
self.wait(1000);
self.then(function(a){
// do something meaningful here
this.echo(this.getCurrentUrl());
});
// Uncomment the following line in case each click opens a new page instead of staying at the same page
//self.back()
});
});
casper.run(function(){
this.exit();
});

Want to put all words at the site with the color blue and uppercase

I'm building one site at JOOMLA and at this site i want to put all the word "Inovflow" on the site, at the color blue and upercase. Like this "INOVFLOW".
I put this code on the js folder of the site:
jQuery(document).fn.findText = function(params){
var phrases = params.query,
ignorance = params.ignorecase;
wrapper = $(this);
var source = wrapper.html();
selection_class_name = params.style;
source = source.replace(/[\n|\t]+/gi, '');
source = source.replace(/\s+/gi, ' ');
source = source.replace(/> /gi, '>');
source = source.replace(/(\w)</gi, function(m, w){return(w + " <");});
phrases.forEach(function(str){
var regexp = makeRegexp(str);
source = source.replace(regexp, function (m){
return (emulateSelection(m));
});
});
wrapper.html(source);
var res_array = wrapper.find("[search=xxxxx]")
return(res_array);
};
function makeRegexp(s){
var space = '( )?(<span[^>]*>)?(</span[^>]*>)?( )?';
var result = s.replace(/\s/gi, space);
result = new RegExp(space + result + space, "gi");
return(result);
}
function emulateSelection (htmlPiece){
htmlPiece = htmlPiece.replace(/(?!=>)[^><]+(?=<)/g, function(w){
return(wrapWords(w));}
);
htmlPiece = htmlPiece.replace(/^[^><]+/, function(w){
return(wrapWords(w));}
);
htmlPiece = htmlPiece.replace(/[^><]+$/, function(w){
return(wrapWords(w));}
);
htmlPiece = htmlPiece.replace(/^[^><]+$/, function(w){
return(wrapWords(w));}
);
return( htmlPiece );
}
function wrapWords(plainPiece){
console.log("plain: " + plainPiece);
var start = '<span search="xxxxx">',
stop = '</span>';
return(start + plainPiece + stop);
}
jQuery(document).each($('.container').findText({query: ['INOVFLOW']}), function (){
$(this).addClass("changeColorInovflow");
});
After this, the page seems to get on a Infinite loop and doesn't load.
if instead of jQuery(document) I use $. the JS returns a error and doesn't run.
Am I doing something wrong?
If findText is intended to be a jQuery plugin, you'll need to update the way the function is declared.
$.fn.findText = function(params) {
var phrases = params.query;
// removed unused 'ignorance' var
var wrapper = this; // this is already a jQuery object
var source = wrapper.html();
selection_class_name = params.style;
source = source.replace(/[\n|\t]+/gi, '');
source = source.replace(/\s+/gi, ' ');
source = source.replace(/> /gi, '>');
source = source.replace(/(\w)</gi, function(m, w){return(w + " <");});
phrases.forEach(function(str){
var regexp = makeRegexp(str);
source = source.replace(regexp, function (m){
return (emulateSelection(m));
});
});
wrapper.html(source);
var res_array = wrapper.find("[search=xxxxx]")
return this; // return 'this' to make it chainable
}
Here are the relevant docs:
https://learn.jquery.com/plugins/basic-plugin-creation/
Then, when you call findText, you can use a much simpler selector:
$('.container').each(function() {
$(this).findText({query: ['INOVFLOW']}).addClass("changeColorInovflow");
});
The original code wouldn't work because each() takes either a function or an array with a callback as parameters, not a selector.
.each(): http://api.jquery.com/each/
jQuery.each(): http://api.jquery.com/jquery.each/

How to follow all links in CasperJS?

I'm having trouble clicking all JavaScript based links in a DOM and saving the
output. The links have the form
<a id="html" href="javascript:void(0);" onclick="goToHtml();">HTML</a>
the following code works great:
var casper = require('casper').create();
var fs = require('fs');
var firstUrl = 'http://www.testurl.com/test.html';
var css_selector = '#jan_html';
casper.start(firstUrl);
casper.thenClick(css_selector, function(){
console.log("whoop");
});
casper.waitFor(function check() {
return this.getCurrentUrl() != firstUrl;
}, function then() {
console.log(this.getCurrentUrl());
var file_title = this.getTitle().split(' ').join('_') + '.html';
fs.write(file_title, this.getPageContent());
});
casper.run();
However, how can I get this to work with a selector of "a", clicking all
available links and saving content? I'm not sure how to get the clickWhileSelector to remove nodes from the selector as is done here: Click on all links matching a selector
I have this script that first will get all links from a page then save 'href' attributes to an array, then will iterate over this array and then open each link one by one and echo the url :
var casper = require('casper').create({
logLevel:"verbose",
debug:true
});
var links;
casper.start('http://localhost:8000');
casper.then(function getLinks(){
links = this.evaluate(function(){
var links = document.getElementsByTagName('a');
links = Array.prototype.map.call(links,function(link){
return link.getAttribute('href');
});
return links;
});
});
casper.then(function(){
this.each(links,function(self,link){
self.thenOpen(link,function(a){
this.echo(this.getCurrentUrl());
});
});
});
casper.run(function(){
this.exit();
});
rusln's answer works great if all the links have a meaningful href attribute (actual URL). If you want to click every a that also triggers a javascript function, you may need to iterate some other way over the elements.
I propose using the XPath generator from stijn de ryck for an element.
You can then sample all XPaths that are on the page.
Then you open the page for every a that you have the XPath for and click it by XPath.
Wait a little if it is a single page application
Do something
var startURL = 'http://localhost:8000',
xPaths
x = require('casper').selectXPath;
casper.start(startURL);
casper.then(function getLinks(){
xPaths = this.evaluate(function(){
// copied from https://stackoverflow.com/a/5178132/1816580
function createXPathFromElement(elm) {
var allNodes = document.getElementsByTagName('*');
for (var segs = []; elm && elm.nodeType == 1; elm = elm.parentNode) {
if (elm.hasAttribute('id')) {
var uniqueIdCount = 0;
for (var n=0;n < allNodes.length;n++) {
if (allNodes[n].hasAttribute('id') && allNodes[n].id == elm.id) uniqueIdCount++;
if (uniqueIdCount > 1) break;
};
if ( uniqueIdCount == 1) {
segs.unshift('id("' + elm.getAttribute('id') + '")');
return segs.join('/');
} else {
segs.unshift(elm.localName.toLowerCase() + '[#id="' + elm.getAttribute('id') + '"]');
}
} else if (elm.hasAttribute('class')) {
segs.unshift(elm.localName.toLowerCase() + '[#class="' + elm.getAttribute('class') + '"]');
} else {
for (i = 1, sib = elm.previousSibling; sib; sib = sib.previousSibling) {
if (sib.localName == elm.localName) i++; };
segs.unshift(elm.localName.toLowerCase() + '[' + i + ']');
};
};
return segs.length ? '/' + segs.join('/') : null;
};
var links = document.getElementsByTagName('a');
var xPaths = Array.prototype.map.call(links, createXPathFromElement);
return xPaths;
});
});
casper.then(function(){
this.each(xPaths, function(self, xpath){
self.thenOpen(startURL);
self.thenClick(x(xpath));
// waiting some time may be necessary for single page applications
self.wait(1000);
self.then(function(a){
// do something meaningful here
this.echo(this.getCurrentUrl());
});
// Uncomment the following line in case each click opens a new page instead of staying at the same page
//self.back()
});
});
casper.run(function(){
this.exit();
});

.load not working in IE8

I have been looking into this issue for the past few days and cannot figure it out. The code below, searches an external file for content based off current page class, then loads content into any matching ID's on the page. It works in Chrome, Firefox, IE9 but recently stopped working in IE8 and I cannot figure out why. Any thoughts would be much appreciated.
HTML looks like this
<body class="jms">
<div id="mainHomeContent" class="shared"></div>
</body>
jquery running on ready
$("div.shared").each(function(){
var Body = $(document).find("body");
var contentID = ("#" + $(this).attr("id"));
var pathname = ""
if(Body.hasClass("pigman")){
var pathname = "/dev/jmsracing/content/pigman/shared-content-include.html"
} else if(Body.hasClass("marion-arts")){
var pathname = "/dev/jmsracing/content/marion-arts/shared-content-include.html"
} else if(Body.hasClass("jms")){
var pathname = "/dev/jmsracing/content/jms/shared-content-include.html"
alert('hello');
}
$(contentID).load(pathname + " " + contentID);
});
What i think is he is iterating with same id where ie is very strict about it so this should be the solution:
$(function() {
var Body = $(document).find("body");
var contentID = ("#" + $(this).attr("id"));
var pathname = ""
if (Body.hasClass("pigman")) {
var pathname = "/dev/jmsracing/content/pigman/shared-content-include.html"
} else if (Body.hasClass("marion-arts")) {
var pathname = "/dev/jmsracing/content/marion-arts/shared-content-include.html"
} else if (Body.hasClass("jms")) {
var pathname = "/dev/jmsracing/content/jms/shared-content-include.html"
alert('hello');
}
$(contentID).load(pathname + " " + contentID);
});​
Try this:
$("div.shared").each(function () {
//combined into one var statement...not really necessary.
var $body = $("body"),
contentId = "#" + $(this).attr("id"),
pathname = "";
//you've declared pathname above no need for "var" each time below
//also added missing semi colons
if ($body.hasClass("pigman")) {
pathname = "/dev/jmsracing/content/pigman/shared-content-include.html";
} else if ($body.hasClass("marion-arts")) {
pathname = "/dev/jmsracing/content/marion-arts/shared-content-include.html";
} else if ($body.hasClass("jms")) {
pathname = "/dev/jmsracing/content/jms/shared-content-include.html";
alert('hello');
}
// $(this) and $(contentId) are the same element
// since you are getting the "id" from "this"
// us $(this) instead
$(this).load(pathname + " " + contentId);
});

Categories