How to open all links on a mouseover event in javascript? - javascript

I tried this:
for (i = 0; i < document.getElementsByTagName('a').length; i++) {
document.getElementsByTagName('a')[i].onmouseover= eval(function(){
window.open(document.getElementsByTagName('a')[i].href, "_blank");});
}
But it went wrong when reaching this part of the code: "window.open(document.getElementsByTagName('a')[i].href"
"Uncaught TypeError: Cannot read property 'href' of undefined "
EDIT 1:
I also tried this:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onmouseover = function(){window.open(links[i].href, "_blank")};
}
I got the same error: Uncaught TypeError: Cannot read property 'href' of undefined
When I change 'i' to 'i-1' for window.open every single link gets replaced with the last link on the page, see code:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onmouseover = function(){window.open(links[i-1].href, "_blank")};
}

This should work as expected:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onmouseover = (
function(h){
return function(){ window.open(h, "_blank") }
}
)(links[i].href);
}

Why you are getting Unable to get href of ...... is because the element is probably because the element is not YET defined. This means you should put the code at the end or add it to window.onload - using addEventListener instead of onload.
Well, #Arnauld's answer is probably good enough, but I suggest to use addEventListener and attachEvent, because it can probably make your coding easier :)
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++){
if(links[i].addEventListener){ // Check if addEventListener is available
links[i].addEventListener("mouseover", function(){
window.open(links[i].href, "_blank");
});
}else{
if(links[i].attachEvent){ // addEventListener not available; test attachEvent
links[i].attachEvent("onmouseover", function(){
window.open(links[i].href, "_blank");
});
}else{
// Neither attachEvent nor addEventListener is available; Throw error (You can try to use links[i].onmouseover)
throw new Error("!(addEventListener & attachEvent)");
}
}
}

Related

Uncaught TypeError: elements[i].attr is not a function

This is my code:
function () {
var container = document.getElementById('data-table');
var elements = container.getElementsByTagName("input");
for (i = 0; i < elements.length; i++) {
elements[i].on("ifChanged", handle_company_state(elements[i].attr('id')));
}
}
function handle_company_state(element_id) {
//....
}
When I'm trying to run it I' getting this error:
Uncaught TypeError: elements[i].attr is not a function
Why?
I think you are looking for something like:
function () {
var elements = $("#data-table input");
for (i = 0; i < elements.length; i++) {
$(elements[i]).on("ifChanged", handle_company_state($(elements[i]).attr('id')));
}
}
function handle_company_state(element_id) {
//....
}
Use getattribute method instead .attr and addEventListener instead .on. And you might not need jquery.
function () {
var container = document.getElementById('data-table');
var elements = container.getElementsByTagName("input");
for (i = 0; i < elements.length; i++) {
elements[i].addEventListener("ifChanged", handle_company_state(elements[i].getAttribute('id')));
}
}
function handle_company_state(element_id) {
//....
}
Use
$(elements[i]).attr()
$.attr() is jQuery method. The same fix applies for your .on() function
$(elements[i]).on("ifChanged", handle_company_state($(elements[i]).attr('id')));
And since you're using jQuery here.
You can write less.
var container = $('#data-table'),
elements = container.find('input'); // container is a jQuery object; thus, $.find() works as traversing method in the DOM. see http://api.jquery.com/find/
$(elements).on("ifChanged", function(){
handle_company_state($(this).attr('id'))); // use `this` as reference to changed element.
});

Get the specific div id from an onclick event (Pure JS no Jquery)

When I try the code referenced in SO #1, I get the console logging a blank string:
installChoices() {
var choices = this.game.page.options;
for (var i = 0; i < choices.length; i++) {
var choice = choices[i];
var choiceDiv = document.createElement("choice" + i);
choiceDiv.innerText = choice[0];
choiceDiv.onclick = function() {
console.log(this.id);
}
this.choicesContainer.appendChild(choiceDiv);
}
}
I want to bind to my class function clicked
installChoices() {
var choices = this.game.page.options;
for (var i = 0; i < choices.length; i++) {
var choice = choices[i];
var choiceDiv = document.createElement("choice" + i);
choiceDiv.innerText = choice[0];
choiceDiv.onclick = this.clicked;
this.choicesContainer.appendChild(choiceDiv);
}
}
clicked(e) {
console.log(e.parentNode); //this is undefined
console.log(e.srcElement);
}
But that shows undefined. When I log srcElement, I get the full element
<choice0>path 1</choice0>
I want to get just the div id when I click, so I can parse that and do logic.
I'd recommend the following approach, as it is the standard:
//assign the event
choiceDiv.addEventListener('click', clicked)
//define the listener
function clicked(event) {
console.log(event.currentTarget)
}
update:
I'm tempted to offer a fix to your code, because I don't think you're achieving what are you trying to actually do:
function installChoices() {
var choices = this.game.page.options;
for (var i = 0; i < choices.length; i++) {
var choice = choices[i];
var choiceDiv = document.createElement("div");
choiceDiv.id = "choice" + i;
choiceDiv.innerText = choice[0];
choiceDiv.addEventListener("click", clicked);
this.choicesContainer.appendChild(choiceDiv);
}
}
function clicked(ev) {
console.log(ev.currentTarget.id); //this will log "choice0"
}
Your "clicked" function are receiving an Event rather than a HTML Element. This is the default behavior when an onClick event triggered.
The click event have a srcElement property, indicating the source element the click event occurred upon. This event object have no parentNode property.
Use e.srcElement.parentNode instead.
BTW, in the SO #1 example, it assign "showIt(this)" to onClick, so browser pass "this", the target element rather than the event object, to the onClick function.

why is the console giving me an exception, when startsWith is defined?

ok i am trying to run the following code and i am getting back an exception that startsWith method is undefined. shouldnt this automatically be defined within javascript?
var mailArchive = retrieveMails();
var livingCats = {"Spot": true};
for (var mail = 0; mail < mailArchive.length; mail++) {
var paragraphs = mailArchive[mail].split("\n");
for (var paragraph = 0;
paragraph < paragraphs.length;
paragraph++) {
if (startsWith(paragraphs[paragraph], "born")) {
var names = catNames(paragraphs[paragraph]);
for (var name = 0; name < names.length; name++)
livingCats[names[name]] = true;
}
else if (startsWith(paragraphs[paragraph], "died")) {
var names = catNames(paragraphs[paragraph]);
for (var name = 0; name < names.length; name++)
delete livingCats[names[name]];
}
}
}
show(livingCats);
Some versions of javascript (an experimental method in Firefox) have a .startsWith() string method that you would use like:
if (paragraphs[paragraph].startsWith("died"))
Regular javascript does not have a global function startsWith() like you are trying to use so unless you're loading some library that has that function in it, that's why the browser is telling you it's undefined.
A recommended solution that would work in any version of JS, would be:
if (paragraphs[paragraph].indexOf("died") === 0)
instead.
Or, you could define the global function you're using:
function startsWith(src, find) {
return src.substr(0, find.length) == find;
}
It's a method of String, not a global function.
It should be:
paragraphs[paragraph].startsWith("born")

Changing CSS via Javascript does NOT work in IE8 for me

I have a small snippet of code that I'm running to switch some DIV tags on and off contingent upon events happening on the page. This code is as follows:
function toggleBack() {
var list = document.getElementsByClassName('innerContentForEmailCapture');
var list2 = document.getElementsByClassName('mpRight');
var list3 = document.getElementsByClassName('mpBtns');
try {
for (var i = 0; i < list.length; i++) {
list.item(i).style.display = 'none';
}
for (var ii = 0; ii < list2.length; ii++) {
list.item(ii).style.display = 'block';
}
for (var iii = 0; iii < list3.length; iii++) {
list.item(iii).style.display = 'block';
}
} catch(err) {
alert(err);
}
}
Mind you, this code does exactly what I want it to do when it's called, Except when dealing with ie8. When using this code there I receive an error message that states:
TypeError: Object doesn't support this property or method
I'm not entirely sure what I am doing wrong here. The idea is to turn the display to none for any DIV with the class "innerContentForEmailCapture" and turn the display to block for any DIV with the classes of "mpRight" and "mpBtns".
Is there a simpler way? One that would allow the behavior to work in ie8?
The problem is with your
document.getElementsByClassName
this function is not supported on IE8. You'd better use
document.querySelectorAll
so you would have:
document.querySelectorAll('.innerContentForEmailCapture')
document.querySelectorAll('.mpBtns')
document.querySelectorAll('.mpRight')
Or, if you need to use getElementsByClassName you can use some polyfills like this

Canot get the href value

Hi I need to valid the href is empty or not on my page using javascript. I searched the site and found some example, but it didn't worked for me. I must miss something that I didn't notice. Would someone point me the good direction and my mistake. I got the error" Unable to get property 'getattribute' of undefined or null reference. The <a> element is like that <a name="playback" href=""> on html file.
Thanks in advance.
There is my code which is run on load event:
var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++)
{
anchors[i].onclick = function() {
if (anchors == null) {
alert('null');
}
else {
var link = anchors[i].getAttribute("href");
//var link= anchors[i].attributes['href'] this line doesn't work too.
}
}
}
}
In your code, the call to getAttribute is inside a closure (that is, a function defined "inline" without a name) that is assigned to the onlick event handler of the link. Therefore that code isn't execxuted right away - it doesn't run before the onclick handler triggers.
When the onclick header triggers, two things are passed to the callback function: the element on which the event was triggered is assigned to the this variable of the functions context - and the event itself is passed as first parameter. anchors however is undefined in the scope of that callback.
So, use either of those:
anchors[i].onclick = function () {
var link = this.getAtrribute("href");
}
 
anchors[i].onclick = function (event) {
var link = event.target.getAttribute("href");
}
You have got a scope problem.
The following code will output 3:
for (var i = 0; i < 3; i++) {
}
console.log(i); // 3
Similar to the example above your onclick is fired after the loop is done.
So i in your example would equal to anchors.length.
And anchors[anchors.length] === undefined.
To solve this problem you have to create a new scope.
For example you could use an Immediately-Invoked Function Expression (IIFE):
var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++)
{
(function(j){
anchors[j].onclick = function() {
if (anchors == null) {
alert('null');
}
else {
var link = anchors[j].getAttribute("href");
}
}
}
}(i));
}
You need to use closure if you want to do it this way since you are using the shared i variable which would have been having last value of iteration when your handler runs on click. But since you are looking at that particular anchor, try binding it with bind an event listener and access it using this.href:
You can use addEventListener and for older browser support attachEvent
var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++) {
anchors[i].addEventListener('click', function () {
var link = this.getAttribute("href");
})
};
Demo
Or :
var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++) {
anchors[i].onclick = getHandler(i);
}
function getHandler(i) {
return function () { //Now each of your handler has its own `i`
var link = anchors[i].getAttribute("href");
}
}
Demo
I have never seen getAttribute before so I performed some tests on it. It turns out that href and getAttribute("href") are quite different. Namely href is the absolute url and getAttribute("href") is the relative url to the page. See this fiddle.
The problem with your code is that the var is captured in the closure of onclick and when the onclick function runs the value will of i will be anchors.length.
Solution, Scratch that use the code from Johannes H. His is better
var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++) {
(function () {
var current = anchors[i]; //Capture the anchor element
current.onclick = function() {
var link = current.getAttribute("href");
};
} ());
}
See this w3 schools page for how to get the href attribute from anchor tags.
http://www.w3schools.com/jsref/prop_anchor_href.asp
var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++)
{
anchors[i].onclick = function() {
if (anchors == null) {
alert('null');
}
else {
var link = this.href;
}
}
}

Categories

Resources