Creating a dynamic popup for Disqus comments for different threads - javascript

Edit: It seems Disqus is using the current page URL as the comment thread identifier despite me being explicit and stating:
<script type="text/javascript">
var disqus_developer = 1;
var disqus_identifier = "#Model.UniqueThreadIdentifier"; <--- HERE
var disqus_shortname = 'foo';
/* * * DON'T EDIT BELOW THIS LINE * * */
(function () {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
Read below for more details.
Disqus says that I can identify a "page" with a unique identifier.
Now in this particular page there are about 10 items and I'd like each item to have a personal Disqus discussion thread.
So here's the actual page that gets loaded:
#foreach (var strong in Model.StrongAgainst)
{
<div class="pick">
<div class="actions">
<a href="#modalDialogue" data-toggle="modal"
id="#strong.UniqueThreadIdentifier" class="btn btn-comment">
<i class="icon-comment"></i>
999
</a>
</div>
</div>
</div>
}
That #UniqueThreadIdentifier is what I'm using to let Disqus load the appropriate thread.
Next, in that same HTML view, I have this Javascript line, which using the UniqueIdentifier returns a PartialView with the appropriate Disqus configuration and HTML:
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$(document).on("click", "#strong-against .pick .data .actions .btn-comment", function () {
var commentUniqueVar = $(this).attr("id");
$.ajax({
url: '/Counterpicks/GetCommentThread',
data: { uniqueidentifier: commentUniqueVar },
success: function (data) {
$('#strongAgainstCommentModal').html(data);
alert("Finished loading.");
}
});
});
});
</script>
And up to here it's 100% confirmed that the right values are being loaded into the HTML.
Here is the PartialView:
<div class="modal-body">
<div id="disqus_thread">
</div>
<script type="text/javascript">
var disqus_developer = 1;
var disqus_identifier = "#Model.UniqueThreadIdentifier";
var disqus_shortname = 'foobar';
/* * * DON'T EDIT BELOW THIS LINE * * */
(function () {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>
Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments
powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">
Disqus</span></a>
</div>
Notice how I set the disqus_identifier using a strongly typed model with the correct value.
My only guess is that when declaring a variable like that, it's created globally? (I think?) And the Disque javascript library is always going to use the first value I assigned to it. Correct?
How can I appropriately load the correct identifier to the Disqus javascript library?

What the identifier allows you to do is display the same thread on multiple URLs, but you can't display multiple threads on the same URL using a new identifier alone (this is a common misconception). We developed a method for reloading a thread with AJAX called Disqus.Reset, which is documented here: http://docs.disqus.com/help/85/
You can also hack it without Disqus.Reset, and that's demonstrated on this post: http://collaborable.com/blog/disqus-jquery-hack-awesome-ux

Related

Searching on a website returns a sooqr popup with results, how do I scrape this?

There is a site (https://www.schoolmaterialen.nl) I would like to scrape for specific items using beautifulsoup python. I can query the item I want using the url: https://www.schoolmaterialen.nl/#sqr:(q[9789053001813]), but instead of showing a page with results, it shows a popup using sooqr and the results can't be found in the html code I obtained using beautifulsoup. The only mention of the sooqr popup in the found code is this:
<!-- Start Sooqr.com on-site search and navigation code -->
<script>
document.addEventListener("DOMContentLoaded", function() {
document.getElementsByClassName("keywords")[0].setAttribute("id", "search");
});
var _wssq = _wssq || [];
_wssq.push(['_load', {'suggest': {"account":"SQ-119341-1","fieldId":"search","version":4}}]);
_wssq.push(['suggest._setPosition', 'screen-middle']);
_wssq.push(['suggest._setLocale', 'nl_NL']);
_wssq.push(['suggest._excludePlaceholders', 'Search..']);
(function () {
var ws = document.createElement('script');
ws.type = 'text/javascript';
ws.async = true;
ws.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'static.sooqr.com/sooqr.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ws, s);
})();
</script>
<!-- End Sooqr.com on-site search and navigation code -->
I already tried to directly use the url of the page I want, but it needs the title of the book which is one of the things I want to find using the isbn. Is there a way to somehow still get the link to the page that is in the popup?

How to render HTML file using JavaScript [duplicate]

I want home.html to load in <div id="content">.
<div id="topBar"> HOME </div>
<div id ="content"> </div>
<script>
function load_home(){
document.getElementById("content").innerHTML='<object type="type/html" data="home.html" ></object>';
}
</script>
This works fine when I use Firefox. When I use Google Chrome, it asks for plug-in. How do I get it working in Google Chrome?
I finally found the answer to my problem. The solution is
function load_home() {
document.getElementById("content").innerHTML='<object type="text/html" data="home.html" ></object>';
}
Fetch API
function load_home (e) {
(e || window.event).preventDefault();
fetch("http://www.yoursite.com/home.html" /*, options */)
.then((response) => response.text())
.then((html) => {
document.getElementById("content").innerHTML = html;
})
.catch((error) => {
console.warn(error);
});
}
XHR API
function load_home (e) {
(e || window.event).preventDefault();
var con = document.getElementById('content')
, xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (e) {
if (xhr.readyState == 4 && xhr.status == 200) {
con.innerHTML = xhr.responseText;
}
}
xhr.open("GET", "http://www.yoursite.com/home.html", true);
xhr.setRequestHeader('Content-type', 'text/html');
xhr.send();
}
based on your constraints you should use ajax and make sure that your javascript is loaded before the markup that calls the load_home() function
Reference - davidwalsh
MDN - Using Fetch
JSFIDDLE demo
You can use the jQuery load function:
<div id="topBar">
HOME
</div>
<div id ="content">
</div>
<script>
$(document).ready( function() {
$("#load_home").on("click", function() {
$("#content").load("content.html");
});
});
</script>
Sorry. Edited for the on click instead of on load.
Fetching HTML the modern Javascript way
This approach makes use of modern Javascript features like async/await and the fetch API. It downloads HTML as text and then feeds it to the innerHTML of your container element.
/**
* #param {String} url - address for the HTML to fetch
* #return {String} the resulting HTML string fragment
*/
async function fetchHtmlAsText(url) {
return await (await fetch(url)).text();
}
// this is your `load_home() function`
async function loadHome() {
const contentDiv = document.getElementById("content");
contentDiv.innerHTML = await fetchHtmlAsText("home.html");
}
The await (await fetch(url)).text() may seem a bit tricky, but it's easy to explain. It has two asynchronous steps and you could rewrite that function like this:
async function fetchHtmlAsText(url) {
const response = await fetch(url);
return await response.text();
}
See the fetch API documentation for more details.
I saw this and thought it looked quite nice so I ran some tests on it.
It may seem like a clean approach, but in terms of performance it is lagging by 50% compared by the time it took to load a page with jQuery load function or using the vanilla javascript approach of XMLHttpRequest which were roughly similar to each other.
I imagine this is because under the hood it gets the page in the exact same fashion but it also has to deal with constructing a whole new HTMLElement object as well.
In summary I suggest using jQuery. The syntax is about as easy to use as it can be and it has a nicely structured call back for you to use. It is also relatively fast. The vanilla approach may be faster by an unnoticeable few milliseconds, but the syntax is confusing. I would only use this in an environment where I didn't have access to jQuery.
Here is the code I used to test - it is fairly rudimentary but the times came back very consistent across multiple tries so I would say precise to around +- 5ms in each case. Tests were run in Chrome from my own home server:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
</head>
<body>
<div id="content"></div>
<script>
/**
* Test harness to find out the best method for dynamically loading a
* html page into your app.
*/
var test_times = {};
var test_page = 'testpage.htm';
var content_div = document.getElementById('content');
// TEST 1 = use jQuery to load in testpage.htm and time it.
/*
function test_()
{
var start = new Date().getTime();
$(content_div).load(test_page, function() {
alert(new Date().getTime() - start);
});
}
// 1044
*/
// TEST 2 = use <object> to load in testpage.htm and time it.
/*
function test_()
{
start = new Date().getTime();
content_div.innerHTML = '<object type="text/html" data="' + test_page +
'" onload="alert(new Date().getTime() - start)"></object>'
}
//1579
*/
// TEST 3 = use httpObject to load in testpage.htm and time it.
function test_()
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
{
content_div.innerHTML = xmlHttp.responseText;
alert(new Date().getTime() - start);
}
};
start = new Date().getTime();
xmlHttp.open("GET", test_page, true); // true for asynchronous
xmlHttp.send(null);
// 1039
}
// Main - run tests
test_();
</script>
</body>
</html>
try
async function load_home(){
content.innerHTML = await (await fetch('home.html')).text();
}
async function load_home() {
let url = 'https://kamil-kielczewski.github.io/fractals/mandelbulb.html'
content.innerHTML = await (await fetch(url)).text();
}
<div id="topBar"> HOME </div>
<div id="content"> </div>
When using
$("#content").load("content.html");
Then remember that you can not "debug" in chrome locally, because XMLHttpRequest cannot load -- This does NOT mean that it does not work, it just means that you need to test your code on same domain aka. your server
You can use the jQuery :
$("#topBar").on("click",function(){
$("#content").load("content.html");
});
$("button").click(function() {
$("#target_div").load("requesting_page_url.html");
});
or
document.getElementById("target_div").innerHTML='<object type="text/html" data="requesting_page_url.html"></object>';
<script>
var insertHtml = function (selector, argHtml) {
$(document).ready(function(){
$(selector).load(argHtml);
});
var targetElem = document.querySelector(selector);
targetElem.innerHTML = html;
};
var sliderHtml="snippets/slider.html";//url of slider html
var items="snippets/menuItems.html";
insertHtml("#main",sliderHtml);
insertHtml("#main2",items);
</script>
this one worked for me when I tried to add a snippet of HTML to my main.html.
Please don't forget to add ajax in your code
pass class or id as a selector and the link to the HTML snippet as argHtml
There is this plugin on github that load content into an element. Here is the repo
https://github.com/abdi0987/ViaJS
load html form a remote page ( where we have CORS access )
parse the result-html for a specific portion of the page
insert that part of the page in a div on current-page
//load page via jquery-ajax
$.ajax({
url: "https://stackoverflow.com/questions/17636528/how-do-i-load-an-html-page-in-a-div-using-javascript",
context: document.body
}).done(function(data) {
//the previous request fails beceaus we dont have CORS on this url.... just for illlustration...
//get a list of DOM-Nodes
var dom_nodes = $($.parseHTML(data));
//find the question-header
var content = dom_nodes.find('#question-header');
//create a new div and set the question-header as it's content
var newEl = document.createElement("div");
$(newEl).html(content.html());
//on our page, insert it in div with id 'inserthere'
$("[id$='inserthere']").append(newEl);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>part-result from other page:</p>
<div id="inserthere"></div>
Use this simple code
<div w3-include-HTML="content.html"></div>
<script>w3.includeHTML();</script>
</body>```
This is usually needed when you want to include header.php or whatever page.
In Javascript it's easy especially if you have HTML page and don't want to use php include function but at all you should write php function and add it as Javascript function in script tag.
In this case you should write it without function followed by name Just. Script rage the function word and start the include header.php
i.e convert the php include function to Javascript function in script tag and place all your content in that included file.
I use jquery, I found it easier
$(function() {
$("#navigation").load("navbar.html");
});
in a separate file and then load javascript file on html page
showhide.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function showHide(switchTextDiv, showHideDiv)
{
var std = document.getElementById(switchTextDiv);
var shd = document.getElementById(showHideDiv);
if (shd.style.display == "block")
{
shd.style.display = "none";
std.innerHTML = "<span style=\"display: block; background-color: yellow\">Show</span>";
}
else
{
if (shd.innerHTML.length <= 0)
{
shd.innerHTML = "<object width=\"100%\" height=\"100%\" type=\"text/html\" data=\"showhide_embedded.html\"></object>";
}
shd.style.display = "block";
std.innerHTML = "<span style=\"display: block; background-color: yellow\">Hide</span>";
}
}
</script>
</head>
<body>
<a id="switchTextDiv1" href="javascript:showHide('switchTextDiv1', 'showHideDiv1')">
<span style="display: block; background-color: yellow">Show</span>
</a>
<div id="showHideDiv1" style="display: none; width: 100%; height: 300px"></div>
</body>
</html>
showhide_embedded.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function load()
{
var ts = document.getElementById("theString");
ts.scrollIntoView(true);
}
</script>
</head>
<body onload="load()">
<pre>
some text 1
some text 2
some text 3
some text 4
some text 5
<span id="theString" style="background-color: yellow">some text 6 highlight</span>
some text 7
some text 8
some text 9
</pre>
</body>
</html>
If your html file resides locally then go for iframe instead of the tag. tags do not work cross-browser, and are mostly used for Flash
For ex : <iframe src="home.html" width="100" height="100"/>

Is it possible to get Google Ads separately (to be used for scripting) for a specific search term using an API?

Aim: Getting Google ads separately to be embedded to a site.
What I tried so far:
1.) Google Custom Search API
→ does not deliver ads but search result
Coding information:
https://developers.google.com/custom-search/v1/cse/list
Code for getting search results:
function requestSearchResult() {
jQuery.get("https://www.googleapis.com/customsearch/v1/", {
q: SearchTerm,
cx: "01042***5fgs",
key: "AL***Xra",
},
function(items, status) {
document.getElementById("content").innerHTML += "" + items.items[0].htmlTitle + "";
document.getElementById("content").innerHTML += "<br>" + items.items[0].displayLink;
document.getElementById("content").innerHTML += "<br>" + items.items[0].htmlSnippet;
document.getElementById('content').innerHTML += "<br>" + '<img src="' + items.items[0].pagemap.cse_thumbnail[0].src + '" alt="text mode" />';
...
...
});
2.) Custom Search Element Control API
→ does not deliver ads separately but it is possible to embed a search box and/or search results together (not separately) with ads to a site, the search results and ads cannot be handled for further scripting
Coding information:
https://developers.google.com/custom-search/docs/element
Code for a search box:
<script>
(function() {
var cx = '01743***hxm';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<gcse:searchbox-only></gcse:searchbox-only>
Code for search results:
<script>
(function() {
var cx = '01743***hxm';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<gcse:searchresults-only></gcse:searchresults-only>
If you just need ads, take a look at https://developers.google.com/custom-search-ads/
If you're looking to use Custom Search, but want more control over rendering, use the Custom Search Element Control API and the recently introduced callbacks feature: https://customsearch.googleblog.com/2019/06/introducing-callbacks-for-even-more.html
Note that for policy reasons this does not provide any control over Ads rendering -- Ads must be rendered as provided.
Thanks, these links are helpful, just did not find them before:
explanation with example code:
https://developers.google.com/custom-search-ads/web
code generator for specific settings:
https://developers.google.com/custom-search-ads/web/code-generator
#Andy: I will check it in detail now and try to set it all up. Are you interested in working together with me (of course not for free :-))? That would save a lot of time I think :-) If yes, please get in contact with me (h.gruenbacher#gmail.com)!

How can i rerender Pinterest's Pin It button?

I'm trying to create and manipulate the Pin It button after page load. When i change the button properties with js, it should be rerendered to get the functionality of pinning dynamically loaded images. So, does Pinterest have any method like Facebook's B.XFBML.parse() function?
Thanks...
Just add data-pin-build attribute to the SCRIPT tag:
<script defer
src="//assets.pinterest.com/js/pinit.js"
data-pin-build="parsePinBtns"></script>
That causes pinit.js to expose its internal build function to the global window object as parsePinBtns function.
Then, you can use it to parse links in the implicit element or all of the links on the page:
// parse the whole page
window.parsePinBtns();
// parse links in #pin-it-buttons element only
window.parsePinBtns(document.getElementById('pin-it-buttons'));
Hint: to show zero count just add data-pin-zero="1" to SCRIPT tag.
The best way to do this:
Remove the iframe of the Pin It button you want to manipulate
Append the html for the new button manipulating it as you wish
Realod their script - i.e. using jQuery:
$.ajax({ url: 'http://assets.pinterest.com/js/pinit.js', dataType: 'script', cache:true});
To render a pin-it button after a page has loaded you can use:
<a href="..pin it link.." id="mybutton" class="pin-it-button" count-layout="none">
<img border="0" src="//assets.pinterest.com/images/PinExt.png" width="43" height="21" title="Pin It" />
</a>
<script>
var element = document.getElementById('mybutton');
(function(x){ for (var n in x) if (n.indexOf('PIN_')==0) return x[n]; return null; })(window).f.render.buttonPin(element);
</script>
Assuming of course the assets.pinterest.com/js/pinit.js is already loaded on the page. The render object has some other useful methods like buttonBookmark, buttonFollow, ebmedBoard, embedPin, embedUser.
I built on Derrek's solution (and fixed undeclared variable issue) to make it possible to dynamically load the pinterest button, so it can't possibly slow down load times. Only tangentially related to the original question but I thought I'd share anyway.
at end of document:
<script type="text/javascript">
addPinterestButton = function (url, media, description) {
var js, href, html, pinJs;
pinJs = '//assets.pinterest.com/js/pinit.js';
//url = escape(url);
url = encodeURIComponent(url);
media = encodeURIComponent(media);
description = encodeURIComponent(description);
href = 'http://pinterest.com/pin/create/button/?url=' + url + '&media=' + media + '&description=' + description;
html = '<img border="0" src="http://assets.pinterest.com/images/PinExt.png" title="Pin It" />';
$('#pinterestOption').html(html);
//add pinterest js
js = document.createElement('script');
js.src = pinJs;
js.type = 'text/javascript';
document.body.appendChild(js);
}
</script>
in document ready function:
addPinterestButton('pageURL', 'img', 'description');//replace with actual data
in your document where you want the pinterest button to appear, just add an element with the id pinterestOption, i.e.
<div id="pinterestOption"></div>
hope that helps someone!
Here's what I did.
First I looked at pinit.js, and determined that it replaces specially-marked anchor tags with IFRAMEs. I figured that I could write javascript logic to get the hostname used by the src attribute on the generated iframes.
So, I inserted markup according to the normal recommendations by pinterest, but I put the anchor tag into an invisible div.
<div id='dummy' style='display:none;'>
<a href="http://pinterest.com/pin/create/button/?
url=http%3A%2F%2Fpage%2Furl
&media=http%3A%2F%2Fimage%2Furl"
class="pin-it-button" count-layout="horizontal"></a>
</div>
<script type="text/javascript" src="//assets.pinterest.com/js/pinit.js">
</script>
Then, immediately after that, I inserted a script to slurp up the hostname for the pinterest CDN, from the injected iframe.
//
// pint-reverse.js
//
// logic to reverse-engineer pinterest buttons.
//
// The standard javascript module from pinterest replaces links to
// http://pinterest.com/create/button with links to some odd-looking
// url based at cloudfront.net. It also normalizes the URLs.
//
// Not sure why they went through all the trouble. It does not work for
// a dynamic page where new links get inserted. The pint.js code
// assumes a static page, and is designed to run "once" at page creation
// time.
//
// This module spelunks the changes made by that script and
// attempts to replicate it for dynamically-generated buttons.
//
pinterestOptions = {};
(function(obj){
function spelunkPinterestIframe() {
var iframes = document.getElementsByTagName('iframe'),
k = [], iframe, i, L1 = iframes.length, src, split, L2;
for (i=0; i<L1; i++) {
k.push(iframes[i]);
}
do {
iframe = k.pop();
src = iframe.attributes.getNamedItem('src');
if (src !== null) {
split = src.value.split('/');
L2 = split.length;
obj.host = split[L2 - 2];
obj.script = split[L2 - 1].split('?')[0];
//iframe.parentNode.removeChild(iframe);
}
} while (k.length>0);
}
spelunkPinterestIframe();
}(pinterestOptions));
Then,
function getPinMarkup(photoName, description) {
var loc = document.location,
pathParts = loc.pathname.split('/'),
pageUri = loc.protocol + '//' + loc.hostname + loc.pathname,
href = '/' + pathToImages + photoName,
basePath = (pathParts.length == 3)?'/'+pathParts[1]:'',
mediaUri = loc.protocol+'//'+loc.hostname+basePath+href,
pinMarkup;
description = description || null;
pinMarkup = '<iframe class="pin-it-button" ' + 'scrolling="no" ' +
'src="//' + pinterestOptions.host + '/' + pinterestOptions.script +
'?url=' + encodeURIComponent(pageUri) +
'&media=' + encodeURIComponent(mediaUri);
if (description === null) {
description = 'Insert standard description here';
}
else {
description = 'My site - ' + description;
}
pinMarkup += '&description=' + encodeURIComponent(description);
pinMarkup += '&title=' + encodeURIComponent("Pin this " + tagType);
pinMarkup += '&layout=horizontal&count=1">';
pinMarkup += '</iframe>';
return pinMarkup;
}
And then use it from jQuery like this:
var pinMarkup = getPinMarkup("snap1.jpg", "Something clever here");
$('#pagePin').empty(); // a div...
$('#pagePin').append(pinMarkup);
I rewrote the Pinterest button code to support the parsing of Pinterest tags after loading AJAX content, similar to FB.XFBML.parse() or gapi.plusone.go(). As a bonus, an alternate JavaScript file in the project supports an HTML5-valid syntax.
Check out the PinterestPlus project at GitHub.
The official way to do this is by setting the "data-pin-build" attribute when loading the script:
<script defer="defer" src="//assets.pinterest.com/js/pinit.js" data-pin-build="parsePins"></script>
Then you can render your buttons dynamically like so:
// render buttons inside a scoped DOM element
window.parsePins(buttonDomElement);
// render the whole page
window.parsePins();
There is also another method on this site which lets you render them in JavaScript without the script tag.
Here is what i did.. A slight modification on #Derrick Grigg to make it work on multiple pinterest buttons on the page after an AJAX reload.
refreshPinterestButton = function () {
var url, media, description, pinJs, href, html, newJS, js;
var pin_url;
var pin_buttons = $('div.pin-it a');
pin_buttons.each(function( index ) {
pin_url = index.attr('href');
url = escape(getUrlVars(pin_URL)["url"]);
media = escape(getUrlVars(pin_URL)["media"]);
description = escape(getUrlVars(pin_URL)["description"]);
href = 'http://pinterest.com/pin/create/button/?url=' + url + '&media=' + media + '&description=' + description;
html = '<img border="0" src="http://assets.pinterest.com/images/PinExt.png" title="Pin It" />';
index.parent().html(html);
});
//remove and add pinterest js
pinJs = '//assets.pinterest.com/js/pinit.js';
js = $('script[src*="assets.pinterest.com/js/pinit.js"]');
js.remove();
js = document.createElement('script');
js.src = pinJs;
js.type = 'text/javascript';
document.body.appendChild(js);
}
});
function getUrlVars(pin_URL)
{
var vars = [], hash;
var hashes = pin_URL.slice(pin_URL.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
Try reading this post http://dgrigg.com/blog/2012/04/04/dynamic-pinterest-button/ it uses a little javascript to replace the pinterest iframe with a new button and then reloads the pinit.js file. Below is the javascript to do the trick
refreshPinterestButton = function (url, media, description) {
var js, href, html, pinJs;
url = escape(url);
media = escape(media);
description = escape(description);
href = 'http://pinterest.com/pin/create/button/?url=' + url + '&media=' + media + '&description=' + description;
html = '<img border="0" src="http://assets.pinterest.com/images/PinExt.png" title="Pin It" />';
$('div.pin-it').html(html);
//remove and add pinterest js
pinJs = $('script[src*="assets.pinterest.com/js/pinit.js"]');
pinJs.remove();
js = document.createElement('script');
js.src = pinJs.attr('src');
js.type = 'text/javascript';
document.body.appendChild(js);
}
Their pinit.js file, referenced in their "Pin it" button docs, doesn't expose any globals. It runs once and doesn't leave a trace other than the iframe it creates.
You could inject that file again to "parse" new buttons. Their JS looks at all anchor tags when it is run and replaces ones with class="pin-it-button" with their iframe'd button.
this works fine for me: http://www.mediadevelopment.no/projects/pinit/ It picks up all data on click event
I tried to adapt their code to work the same way (drop in, and forget about it), with the addition that you can make a call to Pinterest.init() to have any "new" buttons on the page (eg. ajax'd in, created dynamically, etc.) turned into the proper button.
Project: https://github.com/onassar/JS-Pinterest
Raw: https://raw.github.com/onassar/JS-Pinterest/master/Pinterest.js
As of June 2020, Pinterest updated the pin js code to v2. That's why data-pin-build might not work on
<script defer="defer" src="//assets.pinterest.com/js/pinit.js" data-pin-build="parsePins"></script>
Now it works on pinit_v2.js
<script async defer src="//assets.pinterest.com/js/pinit_v2.js" data-pin-build="parsePins"></script>

How can I change a JavaScript variable using Greasemonkey?

This is the page that I am trying to modify, I want to bypass the countdown timer, how should I write the script?
Is there a way that I can change the variable document.licenseform.btnSubmit.disabled to yes using Greasemonkey?
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>dsfsdf</title>
</head>
<body>
<form name="licenseform" method="post" action="">
<input name="btnSubmit" type="button" value="我同意">
</form>
<SCRIPT language=javascript type=text/javascript>
<!--
var secs = 9;
var wait = secs * 1000;
document.licenseform.btnSubmit.value = "我同意 [" + secs + "]";
document.licenseform.btnSubmit.disabled = true;
for(i = 1; i <= secs; i++)
{
window.setTimeout("Update(" + i + ")", i * 1000);
//这一句很关键,记得参数写法为("update("+i+")",i*1000)
}
window.setTimeout("Timer()", wait);
function Update(num)
{
if(num != secs)
{
printnr = (wait / 1000) - num;
document.licenseform.btnSubmit.value = "我同意 [" + printnr + "]";
}
}
function Timer()
{
document.licenseform.btnSubmit.disabled = false;
document.licenseform.btnSubmit.value = " 我同意 ";
}
-->
</SCRIPT>
</td>
<!--网页中部中栏代码结束-->
</body>
</html>
A more secure alternative to using unsafeWindow is to inject code into the document. The code that you inject will run in the same context as the page code, so it will have direct access to all of the variables there. But it will not have access to variables or functions in other parts of your user script code.
Another benefit of injecting code is that a user script written that way will work in Chrome as well as in Firefox. Chrome does not support unsafeWindow at all.
My favorite way to inject code is to write a function, then to use this reusable code to get back the source code for the function:
// Inject function so that in will run in the same context as other
// scripts on the page.
function inject(func) {
var source = func.toString();
var script = document.createElement('script');
// Put parenthesis after source so that it will be invoked.
script.innerHTML = "("+ source +")()";
document.body.appendChild(script);
}
To toggle btnSubmit you could write a script like this:
function enableBtnSubmit() {
document.licenseform.btnSubmit.disabled = false;
document.licenseform.btnSubmit.value = " 我同意 ";
// Or just invoke Timer()
}
function inject(func) {
var source = func.toString();
var script = document.createElement('script');
script.innerHTML = "("+ source +")()";
document.body.appendChild(script);
}
inject(enableBtnSubmit);
Remember that when you use the serialized form of a function in this way normal closure scope will not work. The function that you inject will not have access to variables in your script unless they are defined inside that function.
try calling the Timer() function since its what you want to happen anyway:
unsafeWindow.Timer();
while you are at it, change the Update function to do nothing:
unsafeWindow.update = function(){}
This is possible. The short answer is you can use the object unsafeWindow, for instance
unsafeWindow.document.licenseform.btnSubmit.disabled = true;
However it is not recomemended to do so, because it is unsecure. More information about this here:
http://wiki.greasespot.net/UnsafeWindow
Disregard anything said about "insecure", because script->document write operation IS perfectly secure.
unsafeWindow.document.licenseform.btnSubmit.disabled = false;
(Use mkoryak's method to suppress timeout callback)
That given form contains nothing but timeout, so you might want to bypass it completely:
// this example is INSECURE
unsafeWindow.document.licenseform.submit();
See?

Categories

Resources