I am developing an extension for Mozilla Firefox. A main function is to get the URL that the user is visiting and process it later. I tried the following Javascript code:
window.onload = function(){
alert(document.referrer);
}
That didnt work so I tried to inject an onclick event to every link using this:
window.onload = function(){
var links = document.links;
for(var i=0;i<links.length;++i){
links[i].onclick = show_href();
}
}
function show_href(){
alert(this.href);
}
But that also doesnt work. Any other approach?
Try this:
linktextx
linktexty
linktextz
<script>
window.onload = function() {
var links = document.links;
for(var i=0;i<links.length;i++){
links[i].onclick = function(){alert(this.href)};
}
}
</script>
See: http://jsfiddle.net/uXmWj/ for working demo
In the second approach, the problem could be the for loop.
window.onload = function(){
var links = document.links,
max,
i;
for(var i=0, max = links.length; i < max; i += 1) {
(function() {
var link = links[i];
link.onclick = function() {
alert(this.href);
}
})();
}
};
var anchors = document.getElementsByTagName('a');
for(var i=0,l=anchors.length;i<l;i++)
if(anchors[i].hasAttribute('href'))
anchors[i].onclick = function(){
alert(anchors[i].getAttribute('href'));
}
Related
I have code:
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', function() {
event.preventDefault();
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox= this.getAttribute('data-lightbox');
console.log(); //next element after "this." something like "links[i+1]" or i don't know...
}, false);
}
I want to get 'data-lightbox' attribute for next element which I clicked currently. How to do it?
Using a IIFE can do the trick to preserve the i scope
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
(function(i){
links[i].addEventListener('click', function() {
event.preventDefault();
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox= this.getAttribute('data-lightbox');
console.log(links[i + 1]);
}, false);
})(i)
}
This is a scope issue.
You can use bind (which would fix the scope issue) for the onclick event binding,while this you can send i to the method and you can access the next element using i+1
check the following snippet
window.onload = function() {
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', onclick.bind(links[i], i));
}
function onclick(i) {
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox = this.getAttribute('data-lightbox');
if(links[i+1]!=undefined){
var nextLightbox = links[i + 1].getAttribute('data-lightbox');
}
console.log(imgLink);
console.log(dataLightbox);
console.log(nextLightbox);
}
}
<a href="#" data-lightbox=10>link1</a>
<a href="#" data-lightbox=20>link2</a><a href="#" data-lightbox=30>link3</a><a href="#" data-lightbox=40>link4</a><a href="#" data-lightbox=50>link5</a>
Hope it helps
You can try to get the next element in the way you thought: links[i + 1], although the i is an unique hoisted variable by this loop. You can, however, re-generate this i in the loop body, using variable declaration of let (only supported in ES6+) or using a new function scope inside that loop.
let acts like we were in a new scope, but not. It won't affect the previous i in this example, it'll only replace its presence at the block statement.
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
let i = i;
links[i].addEventListener('click', function() {
event.preventDefault();
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox= this.getAttribute('data-lightbox');
console.log(links[i + 1]);
}, false);
}
In addition to what others have mentioned, another way to go about this is using nextSibling on this.
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', function() {
event.preventDefault();
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox= this.getAttribute('data-lightbox');
console.log(this.nextElementSibling);
}, false);
}
I am trying to write a click event for an anchor tag in my tampermonkey script.
var contentTag = document.getElementsByTagName("pre")[0];
var fileContents = contentTag.innerHTML;
contentTag.innerHTML = "";
var lines = fileContents.split("\n");
window.alert("Number of lines:"+lines.length);
for(var i=0; i<20; i++) {
if(i!==15)
contentTag.innerHTML+=(lines[i]+"<br>");
else {
contentTag.innerHTML+=("<a id=link1>Click me</a>");
var link = document.getElementById('link1');
link.addEventListener("click", function() {
window.alert('I am clicked');
}, false);
}
}
The alert message never gets triggered when I click on the link in the page dispalyed, even though I have a a click event listener defined. What am I doing wrong here?
It's the way you're adding HTML, you're reappending the link when you do this in the next iteration.
link.innerHTML += something
So the event handler is lost, and you can actually prove that by adding the event handler to the last element instead.
If you do it the proper way, creating elements and appending them, it works fine
var contentTag = document.getElementsByTagName("pre")[0];
var fileContents = contentTag.innerHTML;
contentTag.innerHTML = "";
var lines = fileContents.split("\n");
for (var i = 0; i < 20; i++) {
if (i !== 15) {
var txt = document.createTextNode(lines[i] || ''),
br = document.createElement('br');
contentTag.appendChild(txt);
contentTag.appendChild(br);
} else {
var link = document.createElement('a');
link.id = 'link1';
link.innerHTML = 'Click me';
link.addEventListener("click", function () {
alert('clicked')
}, false);
contentTag.appendChild(link)
}
}
FIDDLE
Shoud be contentTag.innerHTML+=("<a id='link1'>Click me</a>");
Try this:
<script>
var contentTag = document.getElementsByTagName("pre")[0];
var fileContents = contentTag.innerHTML;
contentTag.innerHTML = "";
var lines = fileContents.split("\n");
window.alert("Number of lines:"+lines.length);
for(var i=0; i<20; i++) {
if(i!==15)
contentTag.innerHTML+=(lines[i]+"<br>");
else {
contentTag.innerHTML+=("<a id=link"+i+">Click me</a>");
var link = document.getElementById('link'+i);
var att=document.createAttribute('onclick');
att.value="alert('Clicked !')";
link.setAttributeNode(att);
}
}
</script>
Demo: http://jsfiddle.net/TmJ38/
How can I select all a and form tags without needing to include jQuery?
I ultimately am trying to do the following:
$("a").click(function {
window.onbeforeunload = null;
});
$("form").submit(function {
window.onbeforeunload = null;
});
But I really would rather not include jQuery (or even Sizzle.js), if there's a more compact way to do that.
You can use document.querySelectorAll() like this:
var els = document.querySelectorAll( 'a' );
for( var i=els.length; i--; ) {
els[i].addEventListener( 'click', function(){ window.onbeforeunload = null; } );
}
Similar for the <form> tags.
It is available in most modern browsers (caniuse.com).
This should do it:
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
links[i].addEventListener("click", function() { console.log("Clicked"); window.onbeforeunload = null; });
}
To get the form submit, you can do something like this:
<script>
do_function() { window.onbeforeunload = null; }
</script>
<form action="" onsubmit="do_function()" method="">
EDIT:
To combine the two:
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
links[i].addEventListener("click", function() { console.log("Clicked"); window.onbeforeunload = null; });
}
var forms = document.getElementsByTagName("form");
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener("submit", function() { console.log("Submitted"); window.onbeforeunload = null; });
}
Fiddle
I am trying to direct after user click on "Finish" on a sharepoint survey. But the following code executes when user click on "Respond to this survey". Any idea what is happening.
<script type="text/javascript">
function redirect()
{
var inputcCtrls = document.getElementsByTagName("input");
for(var m=0; m<inputcCtrls.length; m++)
if(inputcCtrls[m].type=='button'&&inputcCtrls[m].value=='Finish')
var funcOnClick = inputcCtrls[m].onclick;
inputcCtrls[m].onclick = window.location = "http://www.google.com/";
}
redirect();
</script>
I don't know about javascript, but in c# the code block
var funcOnClick = inputcCtrls[m].onclick;
inputcCtrls[m].onclick = window.location = "http://www.google.com/";
would need to be in parenthesis as the if statement only applies to the next line of code, so the following would work
if(inputcCtrls[m].type=='button'&&inputcCtrls[m].value=='Finish')
{
var funcOnClick = inputcCtrls[m].onclick;
inputcCtrls[m].onclick = window.location = "http://www.google.com/";
}
Edit thanks to graham's answer.
Change:
for(var m=0; m<inputcCtrls.length; m++)
if(inputcCtrls[m].type=='button'&&inputcCtrls[m].value=='Finish')
var funcOnClick = inputcCtrls[m].onclick;
inputcCtrls[m].onclick = window.location = "http://www.google.com/";
to
for(var m=0; m<inputcCtrls.length; m++) {
if(inputcCtrls[m].type=='button'&&inputcCtrls[m].value=='Finish') {
var funcOnClick = inputcCtrls[m].onclick;
inputcCtrls[m].onclick = function () { window.location = "http://www.google.com/" };
}
}
onclick wants a function. This is why I always use parathesis no matter if it's one line or not.
It's easier to assign a unique class name to the button and use document.getElementsByClassName than it is to loop through all the inputs to get the right one.
var inputcCtrls = document.getElementsByClassName("finalButton");
inputcCtrls[0].onclick = function() {
window.location = "http://www.google.com/";
}
I am looping through a list of links. I can correctly get the title attribute, and want it displayed onclick. When the page is loaded and when I click on a link, all of the link titles are alerted one by one. What am I doing wrong?
function prepareShowElement () {
var nav = document.getElementById('nav');
var links = nav.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onclick = alert(links[i].title);
}
}
What you were doing was actually running the alert function.
enclosing the whole thing in an anonymous function will only run it when it is clicked
for (var i = 0; i < links.length; i++) {
links[i].onclick = function () {
alert(this.title);
}
}
You are assigning the onclick to the return value of alert(links[i].title); which doesn't make any sense, since onclick is supposed to be a function.
What you want instead is somethig like onclick = function(){ alert('Hi'); };
But
Since you are using a variable i in that loop you need to create a local copy of it
onclick = function(){ alert(links[i].title); }; would just use the outer scope i and all your links would alert the same message.
To fix this you need to write a function that localizes i and returns a new function specific to each link's own onclick:
onclick = (function(i){ return function(e){ alert(links[i].title); }; })(i);
Final result:
function prepareShowElement () {
var nav = document.getElementById('nav');
var links = nav.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onclick = (function(i){ return function(e){ alert(links[i].title); }; })(i);
}
}
You can use jquery. To display title of the link on click.
$("#nav a").click(function() {
var title = $(this).attr('title');
alert(title);
});
links.forEach(function(link) {
link.onclick = function(event) {
alert(link.title);
};
}
Also note that your original solution suffered from this problem:
JavaScript closure inside loops – simple practical example
By passing in our iteration variable into a closure, we get to keep it. If we wrote the above using a for-loop, it would look like this:
// machinery needed to get the same effect as above
for (var i = 0; i < links.length; i++) {
(function(link){
link.onclick = function(event) {
alert(link.title);
}
})(links[i])
}
or
// machinery needed to get the same effect as above (version 2)
for (var i = 0; i < links.length; i++) {
(function(i){
links[i].onclick = function(event) {
alert(links[i].title);
}
})(i)
}
You need change .onclick for a eventlistener same:
function prepareShowElement () {
var nav = document.getElementById('nav');
var links = nav.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click',function() {
alert(links[i].title);
},false);
}
}