To protect the ads, I thought of creating a protective layer, that is, a div
transparent one that activates after there are two or three clicks
given by the same user and thus avoid more clicks
from the same visitor.
But, of course, this can't be enough, so in addition to creating a layer, I would have to delete all the links that the link(s) contains iframe
and iframe
that my container has <div class="ads"></div>
.
$(document).ready(function() {
$(".ads iframe").load(function() {
$(".layer-protect").hide();
});
});
.ads {
position: relative;
}
.layer-protect {
position: absolute;
}
iframe {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ads">
<iframe src="https://es.stackoverflow.com/"></iframe>
</div>
<div class="layer-protect">
<p>Hi! Testing...</p>
</div>
iframe
I cannot modify the links within a , as you will already know that it is impossible.
The idea is to only allow the user to click on those ads only two or three times, for this you must create a type of click counter and store them in localStorage
since it is not recommended to use cookie
it because it can overload my server.
Storage localStorage
must be secure and last for a limited time of 24 or 48 hours, after that time that data is deleted, it is important that this expiration function works or not for the online user.
At the moment I have the following jQuery code:
let i = 0;
$("iframe *").each(function() {
this.pos = i;
$(this).on("click", (e) => {
if (localStorage.getItem("link"+i) == null) {
localStorage.setItem("link"+i, 1);
} else {
let clicks = localStorage.getItem("link"+i);
if (clicks >= 3) {
if (typeof e.target.getAttribute("href") == "string" && e.target.getAttribute("href").toLowerCase().search(location.hostname.toString().toLowerCase()) == -1) {
e.preventDefault();
}
} else {
localStorage.removeItem("link"+i);
clicks++;
localStorage.setItem("link"+i, clicks);
}
}
});
i++;
});
But it doesn't work, I've tried creating a page with the following structure:
<div>
<a href="https://example.com" target="_black">1</a>
<a href="https://example.com" target="_black">2</a>
<a href="https://example.com" target="_black">3</a>
<a href="https://example.com" target="_black">4</a>
<a href="https://example.com" target="_black">5</a>
<a href="https://example.com" target="_black">6</a>
<a href="https://example.com" target="_black">7</a>
<a href="https://example.com" target="_black">8</a>
</div>
And, I have wrapped/called it in a iframe
giving more than 4 clicks on said links, but they have not been removed or disabled.
How can I correctly employ this problem? Can you explain me how to solve it.
I have been looking at some references:
(reformed answer)
1. Same origin
If you have one
<iframe>
that has the same origin as your domain, no problem, you can do something simple like:In this way we obtain the window contained in the
<iframe>
1.1 - Getting the links
We can simply do a
querySelectorAll
, so that we will obtain those<a>
of the document of the<iframe>
Once we have obtained all the links, we can simply do a
display: none
1.2 - Integration with localStorage
You can add an eventListener to the window, so we will define a function and when the window loads we will call it, it will get all the links of the
<iframe>
, we will add a unique index to each link, so that we can recognize each one inlocalStorage
, we will add an eventListener to Each link, when clicking, will check if the number of clicks is greater than or equal to the one defined in the max constant , if it is greater than or equal, we will do a preventDefault so that it will no longer redirect1.3 - Expiration date
We can save the last day in the month (From 1 to 30 / From 1 to 31)
So we'll get today's day in a month (Same way: 1 - 30 / 1 - 31) And compare it to the date stored in localStorage , subtract both dates, the result, mathematically:
So we have the following code:
This cannot be done, if the user has not loaded the page, this cannot be done, the user will have to load the page for the scripts to run
2. Different origins
When we work with
<iframe>
from different origins, it will not be possible to access the DOM of this, due to security reasons, if we try to do acontentWindow.document
, it will give you the following errorTo fix this we can simply create an
<div>
invisible and have it show if the click counter has exceeded 3 clicksIn addition, apply the following styles, so that the
<div>
invisible one can be superimposed on<iframe>
it and it cannot be clicked2.1 - Demonstration
As you can see, the link is no longer clickable. We add, using javascript, a
<div>
when the window loads2.2 - Expiration date
The method is also similar
You can use a bit of ingenuity to get a click counter on iframes. Even if these are protected by CORS restrictions (origins other than your domain).
This is because, even for cross-origin access, the browser needs minimal communication between windows or frames.
By keeping focus on our main window, we can capture when we lose focus from it (in favor of the iframe the user clicked on) and assess whether the last active element on our site was the iframe we were looking for.
At this point it is important to bring the focus back to the main window ( invisible to the user ) in order to detect several clicks in a row.
I leave you a little developed the theory. If you have any doubt to implement it, do not hesitate to consult.
Update 01/21/2021, persistence in localStorage
Version with persistence. For reasons of restriction of use of localstorage in stackoverflow. Attached example in jsfiddle :
jsfiddle.net/qsaw23co/
Expiration is defined in seconds.
Old version, no persistence