Mouse over the <a> tag - javascript

There is a prompt in the lower left corner When I put the mouse over the tag,
and can u tell me how to forbid this phenomenon.enter image description here

As commented, the behaviour that you wish to stop is a browser's feature.
To avoid this, you will have to simulate anchor's behaviour on your own but as you said you have many anchors and you cannot manually convert them to buttons, you can try following code:
function maskAnchors() {
var els = document.querySelectorAll('a[href]');
console.log("Anchors Found: ", els.length)
for (var i = 0; i < els.length; i++) {
els[i].setAttribute("data-url", els[i].getAttribute('href'));
els[i].removeAttribute("href");
els[i].addEventListener("click", handleClick)
}
}
function handleClick() {
var url = this.getAttribute('data-url');
window.open(url)
}
document.getElementById('btnAdd').addEventListener("click", function() {
var container = document.querySelector('.content');
var link = document.createElement('a')
link.href = "www.google.com";
link.textContent = "This is a newly added link";
container.append(link)
})
document.getElementById('btnMask').addEventListener("click", maskAnchors)
window.addEventListener('load', maskAnchors)
.maskedAnchor {
color: -webkit-link;
text-decoration: underline;
cursor: auto;
}
<div class="content">
Google
Facebook
StackOverflow
YouTube
Example
<a>blabla</a>
</div>
<button id="btnAdd">Add Anchor</button>
<button id="btnMask">Run masking</button>
Note:
Removing href will change styling. You will also have to do that manually.
This will not handle any anchors added dynamically after execution of this function. You will have to call this function again. I have optimised function to only fetch anchors that has href
Hope it helps!

Related

Change Element href Right Before Drag

I'm creating an extension that allows me to drag photo links in some website that doesn't allow it. The element (photoCell) has a default href of "javascript://" and has a child element (photo) which holds the image.
I want to be able to change the href of the parent element to the src of the child image so when i drag, i drag the URL of the child image. (This works if i do it without a drag listener but then when i click on an element it loads the image and not the expected javascript function). So i need to change the href back to "javascript://" after drag is done.
However, even though the href changes the dragged URL still is "javascript://"
function dragstart() {
this.href = this.children[0].src;
}
function dragend() {
this.href = "javascript://";
}
function doForPicturedesk() {
var gallaryCells = document.getElementsByClassName("gallery-cell");
for (var i = 0; i < gallaryCells.length; i++) {
var gallaryCell = gallaryCells[i];
var photoCell = element.children[0];
photoCell.addEventListener("dragstart", dragstart);
photoCell.addEventListener("dragend",dragend);
}
}
Here's a sample of the HTML
<div class="gallery-cell jg-entry entry-visible" style="width: 534px; height: 345px; top: 10px; left: 10px;">
<a href="javascript://" onclick="openPictureDetail('343563491-516813675371465101')" class="gallery-cell__link gallery-cell__image--hoverable">
<img id="thumb_343563491-516813675371465101" class="gallery-cell__image " src="/bild-disp/diasdb/thumbnailextl.action?ref=343563491-516813675371465101&w=false" onerror="correctMissing(this, '343563491-516813675371465101');" style="width: 534px; height: 356px; margin-left: -267px; margin-top: -178px;">
</a>
</div>
enter code here
I didn't think was possible, but what do I know. All you have to do is use dataTransfer.setData to achieve your goal. Try it below:
let anchor = document.querySelector('a');
anchor.ondragstart = function(event) {
let urlWeWant = 'https://www.example.com';
event.dataTransfer.types.forEach(type => {
//Note that all you HAVE to do for this to work is:
//event.dataTransfer.setData(type, urlWeWant);
//BUT, I think checking the type and replace HTML is better
if (type.includes('html')) {
let clone = event.target.cloneNode(true);
clone.href = urlWeWant;
let dataHTML = clone.outerHTML
event.dataTransfer.setData(type, dataHTML);
} else {
event.dataTransfer.setData(type, urlWeWant);
};
});
};
<a href='javascript:void(0);'>Drag Me Into Another Window :)</a>

I've used setAttribute to modify the attributes of the <a> tag, but only partially. Why?

This is my code:
var links = document.querySelectorAll ("a");
for (let i = 0; i <links.length; i++) {
links[i].setAttribute("target", "_self");
}
My goal, obviously, is to have all the links open on the current page, but only some of them become _self and the rest remain _blank, why?
I'm providing you 2 ways to achieve what you want :
First code is what you provided, and the second one is an other way to add _self attribute value on links.
let links = document.querySelectorAll ("a");
for (let i = 0; i <links.length; i++) { //1st way
links[i].setAttribute("target", "_self");
}
links.forEach(link => { //2nd way
link.target = "_self";
});
<body>
Youtube
Google
Twitter
Netflix
</body>

How do you properly write a JavaScript "for" loop?

The GitHub Repository that I have linked will not be used for any other questions (it will not be changed except to help THIS question.... IT WILL ONLY BE USED FOR THIS QUESTION
Note: I have done my research and I believe that my code should work
Ok, so if you require the rest of my code to make a good judgement on this, feel free to go to: My Github Repository which is only going to be used for this 1 question. In the GitHub Repository, there is also a CSS file, but there is no problem with it, just included it so that you can see ALL the code.
Yes, I know that many people on this website do not like it when people include "GitHub" links; however, it is easier for me to explain if I do not have all the code sitting here making a mess (it is easier if I can narrow down what code is giving me an error
Ok, so this "for" loop:
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
dropdown[i].addEventListener("click", something());
alert("Please work");
}
is not actually running. When I put an "alert" above the for loop like:
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
alert("This works");
for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
dropdown[i].addEventListener("click", something());
alert("This does not work");
}
The alert is called as soon as the method that the "for" loop is in, is called. I guess to explain my question, is there anything wrong with my "for" loop? (This works in a different .html file, so I am not sure why it is not working in my current workspace.)
UPDATE (February 18, 2019):
Ok so I found what is causing the error.
For the person that commented and suggested that I use "console.log(dropdown.length);", this brought up an unexpected error:
function something(){
this.classList.toggle("active");
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
}
As I originally said, this works in another file, but for some reason, it says that in "this.classList.toggle("active);", "toggle" is undefined. Is this supposed to be defined in this file, or is it like i think and a default "function"? Through all of my research, and through all the knowledge I have of the language of JavaScript, I am confident that it is a default "function", and unless someone can prove me wrong, I don't understand why this is not working.
The problem is that you are passing a function in as a parameter without wrapping it in a calling function.
There are two ways you would make this work.
Remove the () from the something function and call the alert inside of something
for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
dropdown[i].addEventListener("click", something)
}
something () {
alert('this is working')
...
}
Put a single function call in your event handler and place both function calls inside
for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
dropdown[i].addEventListener("click", function () {
something();
alert("This works");
})
}
Here is an example:
You are calling something instead of just passing the callable function when trying to add the eventListener. Remove the parentheses.
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
dropdown[i].addEventListener("click", something);
}
function something() {
this.classList.toggle("active");
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
}
<a class="dropdown-btn" href="#">Button 1</a>
<div style="display:none;">Dropdown Content Here</div>
<br />
<a class="dropdown-btn" href="#">Button 2</a>
<div style="display:none;">Dropdown Content Here</div>
I was watching the repository on GitHub, and I saw that there are a lot of errors in your html part, so that the JS part can not work.
Just about this loop, the current html part is:
<button class="dropdown-btn" onclick="drop()">OUR STORY
<i class="fa-caret-down"></i>
</button>
So that the first time the drop () function creates a new event listener on the button, but does not call it.
If there is a second click on this button then 2 actions are then launched: the first adds again a new event listener click on the button,
the second is the triggering of the event listener created the first time.
There are 2 possible solutions
Solution 1
<button class="dropdown-btn" onclick="something()">OUR STORY
<i class="fa-caret-down"></i>
</button>
Solution 2
<button class="dropdown-btn" >OUR STORY
<i class="fa-caret-down"></i>
</button>
With in the part JS = ( ! remove function drop() declaration ! )
var dropdown = document.getElementsByClassName("dropdown-btn");
for (let i = 0, iMax=dropdown.length ; i < iMax ; i++) {
dropdown[i].addEventListener("click", something);
}
for helping understand why your code is wrong, please try this sample code
var Compteur = 0;
function something(){
console.log('call on something()', ++Compteur);
}
function drop(){
var dropdown = document.getElementsByClassName("dropdown-btn");
for (let i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", something);
console.log( 'adding event Listener on one dropdown-btn ', ++Compteur);
}
}
<button class="dropdown-btn" onclick="drop()">OUR STORY </button>
Here is your problem.
Ask yourself why are you getting this.classList as undefined?
If you looked further you would find that this is the window object which has no classList . Now ask yourself why the window object?
It is because something() is an event listener that should be called in response to an event. In the line dropdown[i].addEventListener("click", something()); , you aren't assigning something() as an event handler, you are calling the method, without an event, so there is no this.classList as this is the window object.
As other answers have mentioned you need to change this to:
dropdown[i].addEventListener("click", something);
Which will assign the event something() to the click event, without calling it.
Complete Example
function something(){
console.log(this); //For Debug prurposes
this.classList.toggle("active");
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
}
/* Loop through all dropdown buttons to toggle between hiding and showing its dropdown content - This allows the user to have multiple dropdowns without any conflict */
function drop(){
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
dropdown[i].addEventListener("click", something);
console.log("Please wokrk");
}
}
.sidenav a, .dropdown-btn {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 20px;
color: #818181;
display: block;
border: none;
background: none;
width: 100%;
text-align: left;
cursor: pointer;
outline: none;
}
.active {
background-color: green;
color: white;
}
.dropdown-container {
display: none;
background-color: #262626;
padding-left: 8px;
}
<button class="dropdown-btn" onclick="drop()">OUR STORY
<i class="fa-caret-down"></i>
</button>
<div class="dropdown-container">
ABOUT US
COMMUNITY
HUMANITARIAN ACTION
</div>
On a side note, it is quite unusual to use inline events like onClick=drop() to then bind other event listeners to the same element. It is actually best practice to avoid inline javascript all together.
In the future, please include all code relevant to the question, in the question itself. As I mentioned in a comment it makes it easier for us to help you.

Trying to replace every href on the document

i'm completely new to Javascript and I wanted to create an Greasemonkey Script that replaced "/text/othertext/" to "/text2/text3" on all the href elements of the document. That's what i came up with, and as expected, it doesn't work:
var links = document.getElementsByTagName('a');
for (i=0; i<links.length; i++)
{
var gethref = links[i].getAttribute('href');
gethref = gethref.replace(/text\/othertext/g,'text2\/text3');
links[i].setAttribute("href", gethref);
}
Thanks in advance!
Edit: ok, i know why my script is not working, but i don't know if it can be fixed, i'm trying to replace elements that load after the page is completely loaded (maybe with ajax?)
http://i.imgur.com/7n5V7Bi.png
This code works. Your code looks okay too. Perhaps you are loading the script before the document elements? Note how my elements are listed before my script:
link
link
<script>
var links = document.getElementsByTagName('a');
for(var i = 0; i < links.length; i++) {
var href = links[i].getAttribute('href');
href = href.replace('before', '#');
links[i].setAttribute('href', href);
}
</script>
Edit, based on your comments a dirty fix to cause delay in your app before running a script is to use the setTimeout function. To delay five seconds for example, you might use it like this:
link
link
<script>
setTimeout(function() {
var links = document.getElementsByTagName('a');
for(var i = 0; i < links.length; i++) {
var href = links[i].getAttribute('href');
href = href.replace('before', '#');
links[i].setAttribute('href', href);
}
}, 5000); // < --- note the time in ms here
</script>
Not too sure why your code wouldn't be working.
I've put together the following snippet which might help.
(function() {
var anchors = document.querySelectorAll('a');
for(var i = 0; i < anchors.length; i++) {
var newHref = anchors[i].getAttribute('href').replace(/text\/othertext/g,'text2\/text3');
anchors[i].setAttribute('href', newHref);
}
}());
a {
display: block;
}
<!DOCTYPE html>
<head></head>
<body>
Some link
Some other link
</body>
If you run this snippet you'll see only one anchor is updated correctly as intended.
Hope that helps you out!
The easiest solution would be to wrap your code in this:
window.onload = function(){
/* your code here */
};
This will ensure that your code (especially if you've placed your script in the of the document, won't load until the whole page is loaded (including text, images, etc).
window.onload = function() {
document.body.innerHTML = document.body.innerHTML
.replace('<a href="text/othertext/"', '<a href="text2/text3"');
};
<!DOCTYPE html>
<head></head>
<body>
Some link
Some other link
</body>

Is there a way to open all <a href> links on a page in new windows?

I have a bunch of <a href=".html"> links and want to make them all open in new windows.
I know I can do a search and replace all to add target="_blank" to all my <a href="..."> links.
However, is there a quick way, such as setting a CSS style, or adding some JavaScript code, to accomplish the same thing?
If you have a page consisting of only links, consider <base target="_blank">. This opens every link in a new window (but also includes the targets of forms, unless overridden with <form target="_self">.
As others have shown, without modifying the HTML source, you can use Javascript to iterate through all <a> tags and add the target attribute or add an event listener that sets the target attribute dynamically.
If you have jQuery it's simple
$("a").attr("target", "_blank");
Or regular Javascript
var links = document.links;
for (var i = 0; i < links.length; i++) {
links[i].target = "_blank";
}
As per #Lekensteyn's suggestion, without Javascript (added for Completeness)
<base target="_blank">.
CSS: No.
JavaScript: Delegate a click event, which adds a target="_blank" attribute on click of a link.
document.body.addEventListener(function(e) {
if (e.target.nodeName.toUpperCase() === 'A' && e.target.href) {
e.target.target = '_blank';
}
}, true);
Note: If the <a> element contains other elements, you might want to traverse the tree to find out whether an anchor element is clicked:
document.body.addEventListener(function(e) {
var target = e.target;
do {
if (target.nodeName.toUpperCase() === 'A' && target.href) {
target.target = '_blank';
break;
}
} while (target = target.parentElement);
}, true);
Or, if you're a jQuery-lover:
$('body').on('click', 'a', function(e) {
e.target.target = '_blank';
});
yep, u can add attribute with JS to all links in HTML document named 'target' with value '_blank' ;)
You could also open replace href's of all links from url to javascript:openInWindow(url) using this, and writing function in JS that opens new window and set's it's location to url ;) Google will help you with both.
Just add a html base element to the page using Javascript:
var e = document.createElement("base");
e.target = "_blank";
document.head.appendChild(e);
I've used pure vanilla JavaScript to create a script that makes all the links open in a new window.
<script type="text/javascript">
var all_links = document.querySelectorAll("a");
for (let index in all_links) {
try {
all_links[index].setAttribute("target", "_blank");
}
catch (error) {
//console.log(error);
}
}
</script>

Categories

Resources