Click on some element based on its text content in CasperJS - javascript

I have the following retrieved from the web page:
next page
the onclick=onClkRdMsg is constantly changing, is there any method to click on the next page button directly?
since the onclick selector is keep changing, and the href=# if not working, sorry for not having code included here.
just want to know how to click on the next page...
casper.then(function (){
this.click("[????='next page']");
});
what is the ????

casper.click("[????='next page']"); invokes a click using a CSS selector. CSS selectors are not capable of matching an element based on its content (text).
It's easy with XPath expressions, though:
var x = require('casper').selectXPath;
...
casper.click(x('//*[contains(text(),"next page")]'));
If you're sure that there is no whitespace around the search text, then you can also use casper.clickLabel():
casper.clickLabel('next page');

You have to check every link on the page for text "next page":
casper.evaluate(function(){
var tags = document.getElementsByTagName("a");
var searchText = "next page";
var found;
for (var i = 0; i < tags.length; i++) {
if (tags[i].textContent == searchText) {
found = tags[i];
found.click();
break;
}
}
})
Based on How to get element by innerText

Related

How to get css selector of clicked-on element?

I'm new to javascript and css and I'm trying to develop a chrome extension which when the user clicks on an element of a specific class in the webpage, it automatically clicks also the next 5 elements.
I found that the css selectors of all the elements of that class are identical up to a number, so I tried the following:
for (i = 1; i <= 5; ++i) {
document.querySelector(
'#selector_first_part... > div:nth-child('+
i +
') > selector_second_part).click();
}
The code above works fine when I manually set i.
The problem is that I need to extract "i" from the clicked-on element, and in order to do that I thought that I need to get the css selector of the clicked-on element.
I tried to inject a script to the source code that adds an eventListener to each element of that class, which sends the ID of the clicked-on element, and using the ID i thought that I could extract the css selector. here is the code:
var actualCode = `
var elements = document.getElementsByClassName('someClass');
var onClickFunction = function() {
var id = this.getAttribute('id');
alert("This object's ID is " + id);
};
for (var i=0; i<elements.length; i++) {
elements[i].addEventListener('click', onClickFunction, false);
}
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
When running this code the alert says "This object's ID is null", meaning that I can't get the css selector using the ID, because it seems that the elements have no ID.
So my question is: how could I click (with JS) the surrounding elements of the clicked-on element?
Thanks!
1st of all, placing your code into a DOM load event like #eytienne already mentioned is used to make sure the page is loaded before attaching your event.
2nd: you should not need to attach several handler, just one click handler on document- then use the target to get the actual element that was clicked, e.g.
const handler = function(e) {
const elem = e.target;
}
document.addEventListener('click', handler, false);
3rd: you don't need an id, just compare all elements, e.g. (in your handler):
const target = e.target;
for (let i=0,elems=document.querySelectorAll(..);i<elems.length;i++) {
if(elems[i] === target) {
... do something ...
}
I did not test the code.. just to give you an idea.
I hope this will help you!
I think you should replace your script manipulation with that:
window.addEventListener('DOMContentLoaded', function(){
// put your actualCode here
});
Look at this ressource in detail (on Mozilla Developper Network, the official documentation):
https://developer.mozilla.org/fr/docs/Web/Events/DOMContentLoaded
I think you did not understand the purpose of an 'id' in the HTML context so discover it (MDN is always a good resource ;) ):
https://www.google.com/search?q=id+mdn

How to access the rendered page instead of the loaded page like the window.document object?

I'm new to Javascript so apologies if some of the terminology is incorrect.
I've written a piece of javascript that I'm running from the address bar in Chrome.
It simply displays the first 5 links/anchors on the current page however it only recognises <a> tags that were in the HTML page that was originally loaded so with most pages (that are javascript generated) it comes back either undefined or with no anchors.
Javascript:
var len = document.anchors.length > 5 ? 5 : document.anchors.length;
if (len > 0){
var i;
for (i=0;i<len;i++){
alert(document.anchors[i]);
}
}
else {
alert("There are no anchors on this page");
}
I infer from this that windows.document is the loaded html not the rendered html. So, is there an equivalent of the document object for the rendered document instead of the loaded one?
Thanks.
If you're executing the script in the URL bar, then the document is already loaded. Try this code:
var anchors = document.querySelectorAll("a");
for(var i = 0; i < 5; i += 1) {
if (!anchors[i]) break;
alert("Found anchor with href: " + anchors[i].href);
}
alert("Found at least " + i + " anchors");
Fiddle: http://jsfiddle.net/kqa4p57z/
document.anchors only refers to anchor links with the attribute name, could it be that the anchors added after does not have any name attribute? If so add the name attribute.

Enabling and Disabling hyperlinks in JavaScript

I'm working on a project where I need to temporarily disable all hyperlinks, and then enable them again once my pop-up div is gone. I am able to successfully disable all the links using this function I wrote:
function disableHyperlinks(){
link_targets = Array();
var anchors = document.getElementsByTagName("a");
for(var i = 0; i < anchors.length; i++){
link_targets.push(anchors[i].href);
anchors[i].href= "#";
}
}
Which also saves all the URLs so it can put them back later using this function:
function enableHyperlinks(){
var anchors = document.getElementsByTagName("a");
for(var i = 0; i < anchors.length; i++){
anchors[i].href= link_targets[i];
}
}
The above code seems to work just fine, it removes all the links, and then puts them all back without any issues, however the problem is that if I run the 'enable' code after a link is clicked, its almost as if the javascript is setting the link back to the original destination and then registering the click. So despite being 'disabled' in this fashion, the link still ends up leaving the page.
The problem is demonstrated here
Click the red "L" with the white background to enable the javascript I made for selection, you'll notice anything you bring your mouse over will get a blue dashed border, I need to be able to "select" parts of the web page without redirecting to another page if a link is also clicked.. any idea how I could go about doing this properly?
(Please note I am trying to avoid JQuery)
Work on the onClick listener:
var areEnabled = false;
function toggleLinks(){
var anchors = document.getElementsByTagName('a');
for(var i=0; i < anchors.length; i++)
anchors[i].onclick = (areEnabled) ? null : function(e){ return false };
areEnabled = !areEnabled;
};
Instead of searching for many links and disabling them (which, BTW, won't help you against other clickable objects), you can create another invisible div, just below your popup on z-index that would cover entire page and catch all clicks instead of elements underneath. You can even make it semi-transparent instead of completely invisible for visual effect alerting user that "lower-level" is disabled.
I was finally able to solve my own problem by manipulating the onclick property of each hyperlink, then setting it back to what it was previously. The only problem with bokonic's response was that the onclick property was set to null to "re-enable" the link, which would then disable any javascript functionality the link had previously.
var onclickEvents;
function disableHyperlinks(){
onclickEvents = Array();
var anchors = document.getElementsByTagName("a");
for(var i = 0; i < anchors.length; i++){
onclickEvents.push(anchors[i].onclick);
anchors[i].onclick=function(){return false;};
}
}
function enableHyperlinks(){
var anchors = document.getElementsByTagName("a");
for(var i = 0; i < anchors.length; i++){
anchors[i].onclick = onclickEvents[i];
}
}

How do I make the entire div clickable using plain javascript?

I don't need to write this in jQuery but I'm not versed enough in plain javascript to figure it out. Chris Coyier wrote a nice explanation of what I'm talking about here.
The reason I want to convert it is because I don't need to include an entire jQuery library for this one piece of code. I can save that extra request by using plain old javascript.
This is the example code that I want to convert:
$(document).ready(function() {
$(".featured").click(function(){
window.location=$(this).find("a").attr("href"); return false;
});
});
Here's what I've come up with so far:
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll("div.feature").click(function(){
window.location=$(this).find("a").setAttribute("href");
return false;
});
});
One thing which isn't correct in this, as far as I know, are the querySelectorAll, which is looking for just a div element, right? The other thing is the $(this), which I don't know how to translate into plain javascript.
Assuming...
you know the browser support for querySelectorAll and yet you still use it
that addEventListener only works for standards compliant browsers
I believe you meant:
//get all a's inside divs that have class "featured"
var feat = document.querySelectorAll("div.featured a"),
featlen = feat.length,
i;
//loop through each
for(i=0;i<featlen;++i){
//add listeners to each
feat[i].addEventListener('click',function(){
window.location = this.href;
},false);
}
Or you can have the <div> wrapped in <a>. No JS required. It's perfectly valid HTML and browsers do work as intended despite the rule that inline elements should not contain block elements. Just make sure to have display:block on <a> as well as adjust its size.
<a href="location">
<div> content </div>
</a>
You can select with this.querySelectorAll(...):
IE8:
window.onload = function() {
// get all dom elements with class "feature"
var aFeatures = document.querySelectorAll(".feature");
// for each selected element
for (var i = 0; i < aFeatures.length; i++) {
// add click handler
aFeatures[i].onclick = function() {
// get href of first anchor in element and change location
window.location = this.querySelectorAll("a")[0].href;
return false;
};
}
};
IE9 and other current browser:
document.addEventListener("DOMContentLoaded", function() {
// get all dom elements with class "feature"
var aFeatures = document.querySelectorAll(".feature");
// for each selected element
for (var i = 0; i < aFeatures.length; i++) {
// add click handler
aFeatures[i].addEventListener('click', function() {
// get href of first anchor in element and change location
window.location = this.querySelectorAll("a")[0].href;
return false;
});
}
});
=== UPDATE ===
For IE7 support you should add following (untested) script before (also see here):
(function(d){d=document,a=d.styleSheets[0]||d.createStyleSheet();d.querySelectorAll=function(e){a.addRule(e,'f:b');for(var l=d.all,b=0,c=[],f=l.length;b<f;b++)l[b].currentStyle.f&&c.push(l[b]);a.removeRule(0);return c}})()
It is possible that it only supports document.querySelectorAll not element.querySelectorAll.

How to stop browser window from jumping on a #ID hash link - simplest javascript required

Got a client who is strictly no javascript, but in this particular circumstance, I don't think I can avoid it.
I've got a "next / previous" featured area situation going on using CSS (overflow: hidden and position: absolute) - where the click next or previous (a href="#section...") then brings the relevant div ID into view -but, the browser jumps to the top of the screen which is really very annoying.
What's the simplest possible way to prevent this jumping from happening (with javascript) - yet still be usable for users with javascript turned off?
You can only solve this problem by a) Using JS or b) Getting rid of those anchor links.
If you chose choice a:
var links = document.getElementsByTagName('a');
var link;
for(var i = 0, j = links.length; i < j; i++) {
link = links[i];
if(link.href.substring(0, 1) == '#') {
link.onclick = function(e) {
var ev = e || event;
ev.preventDefault();
};
}
}
Just replace '#' link to 'javascript:void(0)' and your page will not gona scroll
HTML
Link // if you want no link, just like '#' link.
Link // for link that you don't want to show.
JS
function page()
{ window.location.assign("home.html"); }

Categories

Resources