Redirecting URLS from page document text - javascript

So i am working on a Userscript and there is one major step i'm trying to find the easiest resolve with since i am very new to Javascript coding...I'm trying to perform/code a function that will open a specified URL:
EXAMPLE: Homepage ("http://www.EXAMPLE.com")
(page can be opened as 'Window.open' = Blank, or _self);
...when the parent or (current) URL that is open
EXAMPLE: innner.href = ("www.EXAMPLE.com/new/01262016/blah/blah/blah");
...has a text on the HTML documnt page that reads:
EXAMPLE TEXT from page ("www.EXAMPLE.com/new/01262016/blah/blah/blah");:
"this is the end of the page, please refresh to return back to homepage"
(TEXT: not the real keyword, but want to use phase as a detection for a setTimeout function to return back to home.)
Any help will be much appreicated, you guys are veryinformative here. Thanks in advance.

I think I have the gist of you question. It is a straighforward, though quite intensive, task to scan the entire text content of a page for specific keywords with JavaScript. However, if the keywords appear more than once (on multiple pages that should not redirect) then your users will get undesirable results.
A simple solution would be to add a class="last-page" attribute to the body-tag of the final page and run a function that checks for this. Something like....
HTML
<body class="last-page"><!--page content--></body>
JS
window.onload = function() {
var interval = 5000; // five seconds
if (document.body.classList.contains('last-page')) {
setTimeout(function() {
window.location.assign('http://the-next-page.com/');
}, interval);
}
};
Alternatively, if you have the ability to wrap the specified text in a uniquely identified html-tag, such as...
<span id="last-page">EXAMPLE TEXT</span>
...then the presence of this tag can be checked on each page load - similar to the function above:
window.onload = function() {
var interval = 5000;
if (document.getElementById('last-page') {
setTimeout(/* code as before */);
}
};
Yet another solution is to check the page URL against a variable...
window.onload = function() {
var finalURL = 'http://the-last-page.com/blah/...';
if (window.location === finalURL) {
/* same as before */
}
};
If this kind of thing is not an option please leave a comment and I'll add a function that gathers a pages entire text content and compares adjacent words to a pre-defined set of keys.

Related

How can I create a dynamic product page using HTML, CSS, and Javascript

I currently only know javascript. But the thing is I looked up how to do it and some people talk about something called localStorage. I have tried this and for some reason when I jump to a new page those variables aren't kept. Maybe I am doing something wrong? I jump to a new page via
and all I want do do is select a certain image. take that image to a new page and add it to that page.
I tried using the localStorage variables and even turning it into JSON.stringify and doing JSON.parse when trying to call the localstorage to another script. It didn't seem to work for me. Is there another solution?
This is some of my code. There are two scripts.
document.querySelectorAll(".card").forEach(item => {
item.addEventListener("click", onProductClick);
})
var div;
var productImg;
var ratingElement;
var reviewCount;
var price;
function onProductClick(){
// This took a week to find out (this.id)
// console.log(this.id);
div = document.getElementById(this.id);
productImg = div.getElementsByTagName('img')[0];
ratingElement = div.getElementsByTagName('a')[2];
reviewCount = div.getElementsByTagName('a')[3]
price = div.getElementsByTagName('a')[4];
console.log(div.getElementsByTagName('a')[4]);
var productData = [div, productImg,ratingElement,reviewCount,price];
window.localStorage.setItem("price", JSON.stringify(price));
}
function TranslateProduct(){
console.log("Hello");
}
This is script 2
var productPageImage = document.getElementById("product-image");
var myData = localStorage['productdata-local'];
var value =JSON.parse(window.localStorage.getItem('price'));
console.log(value);
// function setProductPage(img){
// if(productImg != null){
// return;
// }
// console.log(window.price);
// }
To explain my thought process on this code in the first script I have multiple images that have event listeners for a click. I wanted to Click any given image and grab all the data about it and the product. Then I wanted to move that to another script (script 2) and add it to a dynamic second page. yet I print my variables and they work on the first script and somehow don't on the second. This is my code. in the meantime I will look into cookies Thank you!
Have you tried Cookies
You can always use cookies, but you may run into their limitations. These days, cookies are not the best choice, even though they have the ability to preserve data even longer than the current window session.
or you can make a GET request to the other page by attaching your serialized object to the URL as follows:
http://www.app.com/second.xyz?MyObject=SerializedData
That other page can then easily parse its URL and deserialize data using JavaScript.
you can check this answer for more details Pass javascript object from one page to other

Pure javascript from console: extract links from page, emulate click to another page and do the same

I'm curious if it is possible with pure (vanilla) javascript code, entered into the browser console, to extract all links this (first) page, then emulate a click to go to another page, extract links there and go to the third page.
Extract links means to write them into console.
The same question as 1 but link to go to another page makes just an ajax call to update the part of the page and does NOT actually go to another page.
P.S. All links belong to one domain.
Any ideas how can this be done based on pure javascript?
As example, if you go to Google and enter some word ("example"), you may then open the console and enter
var array = [];
var links = document.getElementsByTagName("cite");
for(var i=0; i<links.length; i++) {
array.push(links[i].innerHTML);
};
console.log(array);
to display the array of URLs (with some text, but that's OK).
It is possible to repeat it 3 times from page 1 to page 3 automatically with pure javascript?
P.S. I should actually extract tags in the code above, so tags I named "links". Sorry for confusion (that doesn't change the question).
Thank you again.
If you want to write all the links into the console, you can use a more specific command
FOR GOOGLES
// Firstly, you get all the titles
var allTitles = document.getElementById("ires").getElementsByTagName("h3");
for(var getTitle of allTitles ) { // For each title, we get the link.
console.log(getTitle.getElementsByTagName("a")[0].href)
}
Then, you only need to simulate a click on the nav.
var navLinks = document.getElementById("nav").getElementsByTagName("a");
navLinks [navLinks.length-1].click() // Click on the "Next" button.
FOR ALL SITES
If you want to get all the links, just do the same command, grab the div ID you want id you only want some part of the page, then use getElementsByTagName("a")
You can find out how to use XHR or other to make raw AJAX request
Simple example found on Google :
// jQuery
$.get('//example.com', function (data) {
// code
})
// Vanilla
var httpRequest = new XMLHttpRequest()
httpRequest.onreadystatechange = function (data) {
// code
}
httpRequest.open('GET', url)
httpRequest.send()

ReportViewer Web Form causes page to hang

I was asked to take a look at what should be a simple problem with one of our web pages for a small dashboard web app. This app just shows some basic state info for underlying backend apps which I work heavily on. The issues is as follows:
On a page where a user can input parameters and request to view a report with the given user input, a button invokes a JS function which opens a new page in the browser to show the rendered report. The code looks like this:
$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
}
});
The page that is then opened has the following code which is called from Page_Load:
rptViewer.ProcessingMode = ProcessingMode.Remote
rptViewer.AsyncRendering = True
rptViewer.ServerReport.Timeout = CInt(WebConfigurationManager.AppSettings("ReportTimeout")) * 60000
rptViewer.ServerReport.ReportServerUrl = New Uri(My.Settings.ReportURL)
rptViewer.ServerReport.ReportPath = "/" & My.Settings.ReportPath & "/" & Request("Report")
'Set the report to use the credentials from web.config
rptViewer.ServerReport.ReportServerCredentials = New SQLReportCredentials(My.Settings.ReportServerUser, My.Settings.ReportServerPassword, My.Settings.ReportServerDomain)
Dim myCredentials As New Microsoft.Reporting.WebForms.DataSourceCredentials
myCredentials.Name = My.Settings.ReportDataSource
myCredentials.UserId = My.Settings.DatabaseUser
myCredentials.Password = My.Settings.DatabasePassword
rptViewer.ServerReport.SetDataSourceCredentials(New Microsoft.Reporting.WebForms.DataSourceCredentials(0) {myCredentials})
rptViewer.ServerReport.SetParameters(parameters)
rptViewer.ServerReport.Refresh()
I have omitted some code which builds up the parameters for the report, but I doubt any of that is relevant.
The problem is that, when the user clicks the show report button, and this new page opens up, depending on the types of parameters they use the report could take quite some time to render, and in the mean time, the original page becomes completely unresponsive. The moment the report page actually renders, the main page begins functioning again. Where should I start (google keywords, ReportViewer properties, etc) if I want to fix this behavior such that the other page can load asynchronously without affecting the main page?
Edit -
I tried doing the follow, which was in a linked answer in a comment here:
$.ajax({
context: document.body,
async: true, //NOTE THIS
success: function () {
window.open(Address);
}
});
this replaced the window.open call. This seems to work, but when I check out the documentation, trying to understand what this is doing I found this:
The .context property was deprecated in jQuery 1.10 and is only maintained to the extent needed for supporting .live() in the jQuery Migrate plugin. It may be removed without notice in a future version.
I removed the context property entirely and it didnt seem to affect the code at all... Is it ok to use this ajax call in this way to open up the other window, or is there a better approach?
Using a timeout should open the window without blocking your main page
$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
setTimeout(function() {
window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
}, 0);
}
});
This is a long shot, but have you tried opening the window with a blank URL first, and subsequently changing the location?
$("#btnShowReport").click(function(){
If (CheckSession()) {
var pop = window.open ('', 'showReport');
pop = window.open ('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>', 'showReport');
}
})
use
`$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
window.location.href='<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>';
}
});`
it will work.

Copy content from <div> into a form field every time it changes using javascript

What i need to do is copy the content of a div with id #logo to a form field with id #input_2_15.
The content in the div is an image (<img src.../>), but this changes... I have the code to copy the content to the input field when the page loads, but i need a code which copies the content every time the image changes (and it does so without refreshing the page). How can i do this?
Also, is it possible to get the function to only copy the image name eg. 12345.png rather than the whole <img src=..../>?
Miro
You mean
function getUrl(id) {
// function to return the source of an image inside an object with given ID
return $("#"+id).find("img").attr("src");
}
$(document).ready(function() {
var currentImage = getUrl("logo"); // get the url of the div now (empty I guess)
$("#ajaxtrigger").click(function() { // some link with ID ajaxtrigger
$("#logo").load("someurlreturningsomehmtl",function(){ // loads the image
if (currentImage != getUrl("logo")) { // did it change?
currentImage = getUrl("logo"); // save the name
$("#input_2_15").val(currentImage); // update the field
}
})
});
});
$('#logo').find('img').attr('src');
This will give you the image location.. now just append this to your img src in the second div
I see this as a case for a "publish and subscribe" ("Pub/Sub") approach.
In this article, we learn four ways to do Pub/Sub with jQuery 1.7, and I chose Option 1 which exploits a new feature of jquery 1.7, namely its $.Callbacks feature. The article gives a good understanding, which I will not try to better here.
The code below is a slightly modified version of Option 1, avoiding need for a global var:
$.Topic = function(id) {
var callbacks, topic = id && $.Topic.topics[id];
if (!topic) {
callbacks = $.Callbacks();
topic = {
publish: callbacks.fire,
subscribe: callbacks.add,
unsubscribe: callbacks.remove
};
if (id) {
$.Topic.topics[id] = topic;
}
}
return topic;
};
$.Topic.topics = {};//avoid global var by making `topics` a property of the static function `jQuery.Topic`.
$(function() {
//A function to change the logo and fire a publisher.
function changeLogoSrc(src) {
$("#logo img").attr('src', src);
$.Topic('logoSrcChanged').publish(src);
}
// A subscriber which listenes for the 'logoSrcChanged' publisher
// and responds by writing the src string to the required form field
$.Topic('logoSrcChanged').subscribe(function(src) {
$("#input_2_15").val(src);
});
});
Demo here
Thus the code for changing the logo and for updating the form field are, to use the correct jargon, effectively "decoupled".
This approach is arguably overblown for something simple, but would be useful in a more extensive environment where many pub/subs are required.

Navigating / scraping hashbang links with javascript (phantomjs)

I'm trying to download the HTML of a website that is almost entirely generated by JavaScript. So, I need to simulate browser access and have been playing around with PhantomJS. Problem is, the site uses hashbang URLs and I can't seem to get PhantomJS to process the hashbang -- it just keeps calling up the homepage.
The site is http://www.regulations.gov. The default takes you to #!home. I've tried using the following code (from here) to try and process different hashbangs.
if (phantom.state.length === 0) {
if (phantom.args.length === 0) {
console.log('Usage: loadreg_1.js <some hash>');
phantom.exit();
}
var address = 'http://www.regulations.gov/';
console.log(address);
phantom.state = Date.now().toString();
phantom.open(address);
} else {
var hash = phantom.args[0];
document.location = hash;
console.log(document.location.hash);
var elapsed = Date.now() - new Date().setTime(phantom.state);
if (phantom.loadStatus === 'success') {
if (!first_time) {
var first_time = true;
if (!document.addEventListener) {
console.log('Not SUPPORTED!');
}
phantom.render('result.png');
var markup = document.documentElement.innerHTML;
console.log(markup);
phantom.exit();
}
} else {
console.log('FAIL to load the address');
phantom.exit();
}
}
This code produces the correct hashbang (for instance, I can set the hash to '#!contactus') but it doesn't dynamically generate any different HTML--just the default page. It does, however, correctly output that has when I call document.location.hash.
I've also tried to set the initial address to the hashbang, but then the script just hangs and doesn't do anything. For example, if I set the url to http://www.regulations.gov/#!searchResults;rpp=10;po=0 the script just hangs after printing the address to the terminal and nothing ever happens.
The issue here is that the content of the page loads asynchronously, but you're expecting it to be available as soon as the page is loaded.
In order to scrape a page that loads content asynchronously, you need to wait to scrape until the content you're interested in has been loaded. Depending on the page, there might be different ways of checking, but the easiest is just to check at regular intervals for something you expect to see, until you find it.
The trick here is figuring out what to look for - you need something that won't be present on the page until your desired content has been loaded. In this case, the easiest option I found for top-level pages is to manually input the H1 tags you expect to see on each page, keying them to the hash:
var titleMap = {
'#!contactUs': 'Contact Us',
'#!aboutUs': 'About Us'
// etc for the other pages
};
Then in your success block, you can set a recurring timeout to look for the title you want in an h1 tag. When it shows up, you know you can render the page:
if (phantom.loadStatus === 'success') {
// set a recurring timeout for 300 milliseconds
var timeoutId = window.setInterval(function () {
// check for title element you expect to see
var h1s = document.querySelectorAll('h1');
if (h1s) {
// h1s is a node list, not an array, hence the
// weird syntax here
Array.prototype.forEach.call(h1s, function(h1) {
if (h1.textContent.trim() === titleMap[hash]) {
// we found it!
console.log('Found H1: ' + h1.textContent.trim());
phantom.render('result.png');
console.log("Rendered image.");
// stop the cycle
window.clearInterval(timeoutId);
phantom.exit();
}
});
console.log('Found H1 tags, but not ' + titleMap[hash]);
}
console.log('No H1 tags found.');
}, 300);
}
The above code works for me. But it won't work if you need to scrape search results - you'll need to figure out an identifying element or bit of text that you can look for without having to know the title ahead of time.
Edit: Also, it looks like the newest version of PhantomJS now triggers an onResourceReceived event when it gets new data. I haven't looked into this, but you might be able to bind a listener to this event to achieve the same effect.

Categories

Resources