I'm really a newbie to everything around programming ok. So...
I want to hide an AdSense div when accessing from a specific source (for example: ?utm_source=www.test.com) for the time a user is still moving around on my site or 120 seconds after that.
PS: I'm in a partnership with another advertising company and I have to show their ads when visitors come through this referral.
I have an AdSense code:
<div class="td-all-devices">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Test -->
<ins class="adsbygoogle"
style="display:inline-block;width:300px;height:600px"
data-ad-client="ca-pub-0000000000000"
data-ad-slot="000000"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
I tried this, but AdSense keep showing in footer:
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++)
{
var pair = vars[i].split("=");
if (pair[0] == variable)
{
return pair[1];
}
}
return -1; //not found
}
if ( getQueryVariable('utm_source') == 'www.test.com' )
{
im.getAds(pozice);
var ads = 1;
document.getElementsByClassName("td-all-devices").style.display = 'none';
}
else
{
var ads = 0;
}
Can anyone help?
In here:
if ( getQueryVariable('utm_source') == 'www.test.com' )
{
im.getAds(pozice);
var ads = 1;
document.getElementsByClassName("td-all-devices").style.display = 'none';
}
document.getElementsByClassName returns an array of objects. Therefore you need to iterate through it to change the value of something in it. Well, you don't HAVE TO ITERATE through it... as long as you can specify which index of the collection you want to play with.
Something like this:
if ( getQueryVariable('utm_source') == 'www.test.com' )
{
im.getAds(pozice);
var ads = 1;
var theElements = document.getElementsByClassName("td-all-devices");
for(var i = 0; i < theElements.length; i++)
{
theElements[i].style.display = 'none';
}
}
else
{
var ads = 0;
}
document.getElementById() returns 1 element you could have modified using this
document.getElementById("whatever unique id").style.display = 'none';
document.getElementsByClassName() returns a collection of elements you could have modified like this
document.getElementsByClassName("whatever class name")[index position].style.display = 'none';
Since you are a self proclaimed newbie, I will invite you to discover the many Developer tools your preferred browser likely has to offer you. Most browsers have a console you can look at. The console will help you tremendously in troubleshooting your code. In console, you would have picked your problem almost instantly because you would have seen an entry like this:
TypeError: document.getElementsByClassName(...).style is undefined
In Firefox, with unmodified keyboard shortcuts, you can bring up the developers palette using ctrl + shift + s.
Related
I use a training site, that has a lot of courses. It is rather annoying that it does not remember the scroll position of your last course. I am trying to write a tampermonkey userscript to scroll to the first image with an alt tag of "Not Started" but it does not seem to work.
Here is what I have tried so far
var myList = document.getElementsByTagName("img");
for(var i=0;i<myList.length;i++)
{
if(myList[i].alt == "Not Started")
{
var pos = myList[i].offsetTop;
}
}
window.scrollTo(0,pos);
Two things here:
var pos
if you declare (mention for the first time) the variable pos in a for loop, it won't work. You have to declare it before where the rest of the function can read it.
window.addEventListener('load', (event) => {
i'm not sure why but at least in the snippet below this was needed. Perhaps the js starts running before the window loads and therefore cannot set window.scrollTo. If you have any questions leave it in the comments.
window.addEventListener('load', (event) => {
var myList = document.querySelectorAll('img');
var pos;
for (var i = 0; i < myList.length; i++) {
if (myList[i].alt == "Not Started") {
pos = myList[i].offsetTop;
break;
}
}
window.scrollTo(0, pos);
});
<img src='https://placekitten.com/800/800'>
<img src='https://placekitten.com/800/800' alt='Not Started'>
<img src='https://placekitten.com/700/800' alt='Not Started'>
I have some programming knowledge, however I didn't work extensively in Javascript or dealt with Chrome extensions before. I'm looking to build a Chrome extension that opens up the selected links in new tabs (that is the initial goal I want to achieve, as my final goal is to open the links in frames of the same tab - if possible -, in order to save the images from those links, similar to what the Save Images extension for Firefox is doing).
I have a problem though: the selected links from my popup are not being "remembered" in order to open them using a delay, after the popup window is closed (due to opening the new tabs). I guess this is related to not making a background script to perform the operation, instead of popup.js? Perhaps some message passing between those two Javascipt files? Just guessing here...
Here is my code so far:
manifest.json
{
"name": "Get links",
"version": "1.0",
"manifest_version": 2,
"description": "Get links from a page",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": ["tabs", "downloads", "<all_urls>"]
}
popup.html
<!DOCTYPE html>
<html>
<head>
<script src="popup.js"></script>
</head>
<body style="width:400px;">
<form id="linksform">
<p>
<label for="matchregex" style="margin-left: 7px;">RegEx Match: </label>
<input id="regextext" type="text" style="width:90px;" name="matchregex" value="" />
<input id="togglematches" type="button" value="Toggle Matches" />
<input id="openselected" type="button" value="Open Selected" />
</p>
<table id='links'>
<th></th>
</table>
</form>
</body>
</html>
popup.js
var alllinks = [];
var visiblelinks = [];
var selectedlinks = [];
var delay = 1000;
// Display all visible links.
function showlinks()
{
var togglematchesbutton = document.getElementById('togglematches');
var openselectedbutton = document.getElementById('openselected');
var linkstable = document.getElementById('links');
while (linkstable.children.length > 1)
{
linkstable.removeChild(linkstable.children[linkstable.children.length - 1])
}
for (var i = 0; i < visiblelinks.length; ++i)
{
var row = document.createElement('tr');
var col0 = document.createElement('td');
var col1 = document.createElement('td');
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = 'check' + i;
checkbox.checked = false;
checkbox.value = visiblelinks[i];
col0.appendChild(checkbox);
col1.innerText = visiblelinks[i];
col1.style.whiteSpace = 'nowrap';
col1.onclick = function()
{
checkbox.checked = !checkbox.checked;
}
row.appendChild(col0);
row.appendChild(col1);
linkstable.appendChild(row);
}
togglematchesbutton.onclick = function()
{
var regex = new RegExp(document.getElementById("regextext").value);
var getinputs = document.getElementsByTagName("input");
for (var i = 0, max = getinputs.length; i < max; i++)
{
if ((getinputs[i].type === 'checkbox') && (regex.test(getinputs[i].value))) getinputs[i].checked = !getinputs[i].checked;
}
}
openselectedbutton.onclick = function()
{
var getinputs = document.getElementsByTagName("input");
for (var i = 0, max = getinputs.length; i < max; i++)
{
if ((getinputs[i].type === 'checkbox') && (getinputs[i].checked))
{
selectedlinks.push(getinputs[i].value);
}
}
for (var i = 0, max = selectedlinks.length; i < max; i++)
{
window.setTimeout(function() {chrome.tabs.create({url: selectedlinks[i]});}, delay);
//chrome.tabs.create({url: selectedlinks[i]});
}
}
}
// Add links to alllinks and visiblelinks, sort and show them. Sendlinks.js is
// injected into all frames of the active tab, so this listener may be called
// multiple times.
chrome.extension.onMessage.addListener
(
function(links)
{
for (var index in links)
{
alllinks.push(links[index]);
}
alllinks.sort();
visiblelinks = alllinks;
//console.log(links);
showlinks();
}
);
// Set up event handlers and inject sendlinks.js into all frames in the active
// tab.
window.onload = function()
{
chrome.windows.getCurrent
(
function (currentWindow)
{
chrome.tabs.query
(
{active: true, windowId: currentWindow.id},
function(activeTabs)
{
chrome.tabs.executeScript(activeTabs[0].id, {file: 'sendlinks.js', allFrames: true});
}
);
}
);
};
sendlinks.js
// Send back to the popup a sorted deduped list of valid link URLs on this page.
// The popup injects this script into all frames in the active tab.
console.log("Injected");
var links = [].slice.apply(document.getElementsByTagName('a'));
console.log(links);
links = links.map
(
function(element)
{
// Return an anchor's href attribute, stripping any URL fragment (hash '#').
// If the html specifies a relative path, chrome converts it to an absolute
// URL.
var href = element.href;
var hashIndex = href.indexOf('#');
if (hashIndex >= 0)
{
href = href.substr(0, hashIndex);
}
return href;
}
);
links.sort();
// Remove duplicates and invalid URLs.
var kBadPrefix = 'javascript';
for (var i = 0; i < links.length;)
{
if (((i > 0) && (links[i] == links[i - 1])) || (links[i] == '') || (kBadPrefix == links[i].toLowerCase().substr(0, kBadPrefix.length)))
{
links.splice(i, 1);
}
else
{
++i;
}
}
console.log(links);
chrome.extension.sendMessage(links);
Note: The most part of this code is taken from somewhere else, and has been modified to suit to my needs.
The main issue is in this code snippet from popup.js:
for (var i = 0, max = selectedlinks.length; i < max; i++)
{
window.setTimeout(function() {chrome.tabs.create({url: selectedlinks[i]});}, delay);
//chrome.tabs.create({url: selectedlinks[i]});
}
If I comment the setTimeout line and uncomment the following line, it works (e.g. the extension opens the tabs successfully), but it doesn't use a delay between opening successive tabs - which is required for avoiding 'Too many requests' error on some sites. If I let this as it is, it opens the number of tabs that it is supposed to open (using the specified delay), but the urls of those tabs don't match the selected values (basically, they're blank). What I want is the latter to happen, but opening the selected links instead of blank tabs.
Could you please point where my mistake is, and suggest the code modifications to make this work? If doable, by keeping the existing code as close as possible to the posted version (aka perfoming only minor modifications to the source). Thank you.
Nevermind, I solved the issue. It turns out that, for some reason, Chrome didn't remember the i variable inside the for loop (maybe because of settimeout() working asynchronously compared to the for loop, due to the delay?), so it couldn't reference the correct array element.
All I had to do was replace the above
window.setTimeout(function() {chrome.tabs.create({url: selectedlinks[i]});}, delay);
with
window.setTimeout(function() {chrome.tabs.create({url: selectedlinks.shift()});}, delay);
and it worked flawlessly. Basically, instead of referencing the array element using the i variable, the updated code is always referencing the first array element, while removing it at the same time, thus "navigating" through the whole array and eliminating the elements for which tabs have been created.
I picked up this great javascript from MS-Potilas of http://yabtb.blogspot.com/ which gives me my next and previous blog titles appended to the prev and next icons by calling the title information from the blog feed. And if that somehow fails, it has a backup, which is to pull the information off the urls and turn that into the title in its PseudoTitle mode.
Thing is, it only works for about the newest half of my blog posts. After that, it switches into PseduoTitle mode.
Here's what I don't understand. It's supposed to work for 500 posts. My site only has 350+. So why does it seem to work properly for only the newest 100+ posts?
Also, is there something I can do so that I can increase the number of posts that this script will work for after I go past 500 posts?
Thanks a lot for your help.
Here's the script;
<script type='text/javascript'>
// Post titles to Older Post and Newer Post links (without stats skew)
// by MS-potilas 2012. See http://yabtb.blogspot.com/
//<![CDATA[
var urlToNavTitle = {};
function getTitlesForNav(json) {
for(var i=0 ; i < json.feed.entry.length ; i++) {
var entry = json.feed.entry[i];
var href = "";
for (var k=0; k<entry.link.length; k++) {
if (entry.link[k].rel == 'alternate') {
href = entry.link[k].href;
break;
}
}
if(href!="") urlToNavTitle[href]=entry.title.$t;
}
}
document.write('<script type="text/javascript" src="//'+window.location.hostname+'/feeds/posts/summary?redirect=false&max-results=500&alt=json-in-script&callback=getTitlesForNav"/>');
function urlToPseudoTitle(href) {
var title=href.match(/\/([^\/_]+)(_.*)?\.html/);
if(title) {
title=title[1].replace(/-/g," ");
title=title[0].toUpperCase() + title.slice(1);
if(title.length > 28) title=title.replace(/ [^ ]+$/, "...")
}
return title;
}
$(window).load(function() {
window.setTimeout(function() {
var href = $("a.blog-pager-newer-link").attr("href");
if(href) {
href = href.replace(/\http\:[^/]+\//, "https");
var title=urlToNavTitle[href];
if(!title) title=urlToPseudoTitle(href);
if(title) $("a.blog-pager-newer-link").html("<< Newer<br />" + title);
}
href = $("a.blog-pager-older-link").attr("href");
if(href) {
href = href.replace(/\http\:[^/]+\//, "https");
var title=urlToNavTitle[href];
if(!title) title=urlToPseudoTitle(href);
if(title) $("a.blog-pager-older-link").html("Older >><br />" + title);
}
}, 500);
});
//]]>
</script>
Seems I managed to figure it out.
Apparently, even though the script says max-results=500, the script is really only pulling 150 posts. I don't know why that is.
So I just added more retrieval scripts like this to cover the rest.
document.write('<script type="text/javascript" src="//'+window.location.hostname+'/feeds/posts/summary?redirect=false&max-results=150&start-index=151&alt=json-in-script&callback=getTitlesForNav"/>');
function urlToPseudoTitle(href) {
var title=href.match(/\/([^\/_]+)(_.*)?\.html/);
if(title) {
title=title[1].replace(/-/g," ");
title=title[0].toUpperCase() + title.slice(1);
if(title.length > 28) title=title.replace(/ [^ ]+$/, "...")
}
return title;
}
Many thanks to Adam over at http://too-clever-by-half.blogspot.com/ for providing the solution to the &start-index=151 extension.
I have a page that is pulling in a Facebook RSS feed. Unfortunately, the feed contains both relative and absolute paths. I want to give users the ability to click on any given story and read it on Facebook. One of the generated links is relative, so what should be:
http://www.facebook.com/ShannonBaumGraphics/photos/a.253345034707618.56302.102938249748298/805807439461372/?type=1
is converted to
http://www.shannonbaumsigns.com/ShannonBaumGraphics/photos/a.253345034707618.56302.102938249748298/805807439461372/?type=1&relevant_count=1
I tried the following:
<script type="text/javascript">
window.onload = function() {
var aEls = document.getElementsByTagName('a');
for (var i = 0, aEl; aEl = aEls[i]; i++) {
aEl.href = aEl.href.replace("/ShannonBaumGraphics/photos/","http://www.facebook.com/ShannonBaumGraphics/photos/");
}
};
</script>
But ended up with
http://www.shannonbaumsigns.comhttp//www.facebook.com/ShannonBaumGraphics/photos/a.253345034707618.56302.102938249748298/805807439461372/?type=1&relevant_count=1
I know it's something simple, but I'm not strong enough with Javascript to pinpoint the problem.
you can simply assigning new url.try using this :
aEl.href ="http://www.facebook.com/ShannonBaumGraphics/photos/";
aaEl.href = aEl.href.replace('http://www.shannonbaumsigns.com/ShannonBaumGraphics/photos/','http://www.facebook.com/ShannonBaumGraphics/photos/');
// http://www.facebook.com/ShannonBaumGraphics/photos/a.253345034707618.56302.102938249748298/805807439461372/?type=1&relevant_count=1
Thanks for your help. It pointed me in the right direction. Part of the problem is that the site uses multiple domain names (I should have mentioned that). So I added some PHP to grab the domain name to search for the address, and then replaced it with the Facebook link.
Here's what it looks like now:
<script type="text/javascript">
window.onload = function() {
var aEls = document.getElementsByTagName('a');
for (var i = 0, aEl; aEl = aEls[i]; i++) {
aEl.href = aEl.href.replace("<?php echo $_SERVER['SERVER_NAME']; ?>/ShannonBaumGraphics/photos/","www.facebook.com/ShannonBaumGraphics/photos/");
}
};
</script>
Maybe there are better approaches, but this seems to work.
Please take a look at this screenshot first:
I would like to move the highlighted block in the image, i.e. the the 'Result Info' (the "About 5 results (0.40 seconds) text)" and the 'powered by Google Custom Search', to the bottom of the search results.
Removing them maybe against Google's terms, but moving them to the bottom doesn't appear to be so, as many websites are doing it.
Here's the javascript code that I use for the search results page:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1', {language : 'en', style : google.loader.themes.V2_DEFAULT});
google.setOnLoadCallback(function() {
var customSearchOptions = {};
var googleAnalyticsOptions = {};
googleAnalyticsOptions['queryParameter'] = 'q';
googleAnalyticsOptions['categoryParameter'] = '';
customSearchOptions['googleAnalyticsOptions'] = googleAnalyticsOptions;
customSearchOptions['adoptions'] = {'layout': 'noTop'};
var customSearchControl = new google.search.CustomSearchControl(
'XXXXCANTGIVEITAWAYXXXXX', customSearchOptions);
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
var options = new google.search.DrawOptions();
options.enableSearchResultsOnly();
customSearchControl.draw('cse', options);
function parseParamsFromUrl() {
var params = {};
var parts = window.location.search.substr(1).split('\x26');
for (var i = 0; i < parts.length; i++) {
var keyValuePair = parts[i].split('=');
var key = decodeURIComponent(keyValuePair[0]);
params[key] = keyValuePair[1] ?
decodeURIComponent(keyValuePair[1].replace(/\+/g, ' ')) :
keyValuePair[1];
}
return params;
}
var urlParams = parseParamsFromUrl();
var queryParamName = "q";
if (urlParams[queryParamName]) {
customSearchControl.execute(urlParams[queryParamName]);
}
}, true);
</script>
Can someone who knows JavaScript and/or has used Google Custom Search Engine, modify the aforementioned JS code accordingly?
PS: I don't know JavaScript, so some kind of spoon-feeding will help. Thanks.
Are you already using jQuery on that page? If so, you can move that section around by doing this:
$( '.gsc-result-info' ).appendTo( '.gsc-control-cse' );
That will be fragile and could break anytime Google changes things.
I'm not sure sure that is quite moving the part you want moved (and your layout might be a little different than the demo. Just replace gsc-result-info with the class of the div you want to move gsc-control-cse with the div you want to move it to.
Google has some documentation about changing the look and feel of the results page. It looks like you can do a lot more than just mvoe the header down to the bottom.
I think you might want to look at the Setting the Search Element Layout section. There is an option called "Results Only" that may be close to what you are looking for.