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.
Related
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
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
I have an anchor tag element coming in the html like:
Now in the javascript function, I have written:
function handleEvent(sourceElement, txt) {
console.log(sourceElement);
}
the consoled element is coming as the window in this case.
I tried sourceElement.document.activeElement but it doesnt seem to work in chrome, where it is coming as body element.
I cannot change the structure of the anchor tag to 'onClick' function as this is coming from some other source.
Is there some way to find the calling element in this scenario?
The real answer here is to change the HTML, which you've said you can't do. I'd push back on that if you can. If you're writing the function, and the function name is in the HTML, how is it you can't change the HTML??
But if you really, really can't, you can update the DOM once it's loaded:
var list = document.querySelectorAll('a[href^="javascript:"]');
var x, link;
for (x = 0; x < list.length; ++x) {
link = list[x];
link.onclick = new Function(link.href.substring(11));
link.href = "javascript:;";
}
Live Copy | Live Source
This is fairly naughty, as it uses the Function constructor (which is very much like eval), but if you trust the source of the HTML, that should be okay.
Or of course, if you don't have to use whatever was in the href to start with, just hook up your event handler in the code above and don't use new Function.
try something like this, use jQuery
just select the link tag with your selector
$(function(){
var href = $('a').attr('href');
href = href.replace('javascript:','');
$('a').attr('href','#');
$('a').attr('onclick',href);
})
This is just workaround solution.
If you have access to the js, you could do something like this:
document.addEventListener('DOMContentLoaded', function(){
var link = document.querySelectorAll('a');
link[0].addEventListener('click', function(e){
console.log(e.target);
});
});
With this, you would be just not be doing anything with the inline href event and just be appending your own handler.
And if no other answer here works for you because you can't update the DOM after it's loaded (try doing any of them if you want to modify a squarespace lightbox - not saying it's impossible, but...), here's an out of the box thinking:
Sometimes there will be something hinting where the a href is. So you could use it.
<div class="hint current">
<a href="javascript:handleEvent('.hint')">
In my case, I even knew the hint without needing a parameter, which made things even simpler:
function handleEvent (hint) {
if(!hint) {
hint = $("div.current");
}
hrefElement = $(hint).find('a[href^=javascript]');
}
This of course will make sense if your DOM is constantly being changed by a script you have no access to.
But even if there is nothing hinting on the a href, you still could do something like this:
<a href="javascript:var x=1;handleEvent(1)">
function handleEvent (uniqueId) {
hrefElement = $('a[href^=javascript:var x='+uniqueId);
}
i am working on a mobile website with html,js and css.i have created tag through HTML5 DOM & assigned functions to it. It's not working.
My html code(which i have tried thro' DOM method);
<script>
var addExhibits = document.getElementById('mycontent');
function mytest()
{
var div = document.createElement('div');
div.id = 'rateMe';
var anchor = document.createElement('a');
anchor.id="_1";
anchor.onclick = rateIt(this);
anchor.onmouseover=rating(this);
anchor.onmouseout=off(this);
div.appendChild(anchor);
addExhibits.appendChild(div);
}
</script>
<body><div id='mycontent' title="Rate Me..."></body>
Code(statically created tag - works fine)
<div id="rateMe" title="Rate Me...">
<a onclick="rateIt(this)" id="_1" onmouseover="rating(this)" onmouseout="off(this)"></a>
</div>
rate(this) is a function in external JS(http://reignwaterdesigns.com/ad/tidbits/rateme/)
Your event handler just assign the result of the respective function calls here:
anchor.onclick = rateIt(this);
anchor.onmouseover=rating(this);
anchor.onmouseout=off(this);
I assume you want them to execute in case of the event instead:
var that = this;
anchor.onclick = function(){ rateIt(that); };
anchor.onmouseover = function(){ rating(that); };
anchor.onmouseout= function(){ off(that); };
You don't call your mytest() function anywhere. That's the first thing I see. The other thing is that you are putting your script above your div (mycontent) so the div has not yet been created when your script is read. But I don't completely understand what your aim is here or what exactly your problem is.
You don't need to pass this.
you can access your element inside the function in many ways.
var addExhibits=document.getElementById('mycontent'),
rateIt=function(e){
e=e||window.event;
var target=e.target||e.srcElement;//polyfill for older browser
console.log(this,target);
},
rating=function(e){
console.log(this,e.target);
},
off=function(e){
console.log(this,e.target);
},
mytest=function(){
var div=document.createElement('div'),
a=document.createElement('a');
div.id='rateMe';
a.id="_1"; // id's shouldn't contain _ - & numbers(1st letter) even if it works.
a.onclick=rateIt;
a.onmouseover=rating;
a.onmouseout=off;
div.appendChild(a);
addExhibits.appendChild(div);
};
this way you also don't create memory leaks.
ps.: that external js example you using is written very bad.
to make your example work you need to change the strange me/num/sel variables in the external js with the proper one (this/e.target/e.srcElement).
I need to make a set of links open in a new window - the good thing is they all have the same css style - what do i need to do in css to get these links opened in new window?
As per the comments:
and how can i specify window size? i want it a little smaller than the original page. also, can i make all links in the page, open in the SAME new window, of a smaller size?
You can't use CSS or HTML to do this. You need to use JavaScript's window.open(). You can get all links by element.getElementsByTagName() on a and you can determine the link's class attribute by element.className:
window.onload = function() {
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
var link = links[i];
if (link.className == 'someClass') {
link.onclick = function() {
window.open(this.href, 'chooseYourName', 'width=600,height=400');
return false;
}
}
}
}
Or if you're already using jQuery, you can use $('a.someClass') to select all links which has the specified class someClass:
$(document).ready(function() {
$('a.someClass').click(function() {
window.open(this.href, 'chooseYourName', 'width=600,height=400');
return false;
});
});
The window's name as specified in chooseYourName will take care that all links are (re)opened in the same window. You also see that you can specify the width and height over there.
You can't use CSS to do this. You need to use <a target="_blank"></a>.
Edit: Javascript's window.open command.
You can't do this with CSS. You should do this with a small script such as:
<script type="text/javascript">
function newwindow()
{
var load = window.open('http://www.domain.com');
}
</Script>