make ajax update value on browser without refresh - javascript

i read a value from a XML file using ajax jquery and make it appear on the browser the problem is when i change the value of my xml file i can't figure out how to make it change automatically in the browser
the xml (counter.xml) file:
<?xml version="1.0"?>
<count><number>5</number></count>
the php (slideshow.php):
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<style>
body { font-family: Helvetica, Arial, sans-serif; line-height: 1.3em; -webkit-font-smoothing: antialiased; }
.container {
width: 90%;
margin: 20px auto;
background-color: #FFF;
padding: 20px;
}
pre, code {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
font-size: 12px;
color: #333;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
pre { border: 1px solid #CCC; background-color: #EEE; color: #333; padding: 10px; overflow: scroll; }
code { padding: 2px 4px; background-color: #F7F7F9; border: 1px solid #E1E1E8; color: #D14; }
</style>
</head>
<body>
<div id="result">
<script type="text/javascript">
function ajaxRequest(){
var activexmodes=["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] //activeX versions to check for in IE
if (window.ActiveXObject){ //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
for (var i=0; i<activexmodes.length; i++){
try{
return new ActiveXObject(activexmodes[i])
}
catch(e){
//suppress error
}
}
}
else if (window.XMLHttpRequest) // if Mozilla, Safari etc
return new XMLHttpRequest()
else
return false
}
var mygetrequest=new ajaxRequest()
if (mygetrequest.overrideMimeType)
mygetrequest.overrideMimeType('text/xml')
mygetrequest.onreadystatechange=function(){
if (mygetrequest.readyState==4){
if (mygetrequest.status==200 || window.location.href.indexOf("http")==-1){
var xmldata=mygetrequest.responseXML //retrieve result as an XML object
var rssentries=xmldata.getElementsByTagName('Count')
var output='<ul>'
for (var i=0; i<rssentries.length; i++){
output+='<li>'
output+='<a href="'+rssentries[i].getElementsByTagName('Number')[0].firstChild.nodeValue+'">'
output+=rssentries[i].getElementsByTagName('Number')[0].firstChild.nodeValue+'</a>'
output+='</li>'
}
output+='</ul>'
document.getElementById("result").innerHTML=output
}
else{
alert("An error has occured making the request")
}
}
}
mygetrequest.open("GET", "counter.xml", true);
mygetrequest.send(null);
</script>
<script type="text/javascript">
refreshdiv();
</script>
</div>
</body>
<script src="../libs/jquery/jquery.js"></script>
<script src="../src/jquery.backstretch.js"></script>
<script>
$.backstretch([
<?php
$directory = "images/";
//get all image files with a .jpg extension.
$images = glob($directory . "*.j*");
//print each file name
$output="";
//$nbrImages= 0;
foreach($images as $image)
{
$output.="'".$image."',";
//$nbrImages = $nbrImages + 1;
}
echo substr_replace($output,"",-1);
?>
], {
fade: 750,
duration: 4000
});
</script>
</body>
</html>

try this one
setTimeout(function(){
//your ajax code
},100);

You would need something like this
setInterval(
function(){
//your ajax call
}
,100 //The time in milliseconds that should repeat the ajax call
);
the setInterval function sets a logic that will repeat the given task in the timing you set. So you could check and load the .xml file every x seconds.
You can stop the repeat like this
var interval = setInterval(function(){ //your function }, 100);
clearInterval(interval);
Other then from #pratik nagariya mentioned the
setTimout()
function will only delay your call, but not repeat it.

I just did some quick searches and found that you could use this code:
reloadinterval=window.setInterval(function(){
old=rssentries;
// your ajax reqest code
if(!(rssentries==old)){window.reload();}
}, 3000 //the time interval in milliseconds);

Related

Localstorage - rewrite from JS to Jquery

I'm working on a portfolio project - which should use jquery - part of the task is to set and get text via localstorage - which I can do in Javascript but I breaks when attempting to refactor in jquery.
I found an elegantly simple javascript codepen, which has all the features I want. But when I refactor into jquery it loses funtionality - I can't save the text to local storage (I get null) and I can't copy the text to a different Div.
This is the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Local Test</title>
</head>
<body>
<div class="content-output"></div>
<textarea class="content-input" placeholder="Your text here"></textarea>
<button class="save-button">Save</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="./script.js"></script>
</body>
</html>
This is simple CSS from the JS code pen:
* {
font-size: 16px;
font-family: sans-serif;
}
body {
padding: 1rem;
font-family: sans-serif;
}
.content-output {
float: left;
box-sizing: border-box;
background: #f9f9f9;
padding: 0.5rem;
width: calc(50% - 1rem);
height: 10rem;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
color: #202020;
}
.content-input {
float: left;
box-sizing: border-box;
margin-left: 2rem;
padding: 0.5rem;
width: calc(50% - 1rem);
height: 10rem;
border: 1px solid #505050;
resize: none;
}
.save-button {
/* -webkit-appearance: none; */
border: 0;
background: #0088ff;
padding: 0.5rem 1rem;
border-radius: 3px;
color: #fff;
margin-top: 1rem;
float: right;
cursor: pointer;
}
Here is the JS which works:
var input_textarea = document.querySelector(".content-input");
var output_div = document.querySelector(".content-output");
var save_button = document.querySelector(".save-button");
save_button.addEventListener("click", updateOutput);
output = localStorage.getItem("content");
input = localStorage.getItem("content");
console.log(output);
output_div.textContent = output;
function updateOutput() {
console.log("clicked button");
localStorage.setItem("content", input_textarea.value);
output_div.textContent = input_textarea.value;
}
And here is the jquery which doesn't work:
var input_textarea = $(".content-input");
var output_div = $(".content-output");
var save_button = $(".save-button");
save_button.on("click", updateOutput);
output_div.textContent = localStorage.getItem("content");
input_textarea.value = localStorage.getItem(("content"));
function updateOutput(event) {
event.preventDefault();
localStorage.setItem("content", input_textarea.value);
output_div.textContent = input_textarea.value;
}
I'm running out of ideas and searches - probably a typo but I cant find it . I've tried text() which was the advice 6 years ago. JSON.stringify and parse don't help because it's just a string.
I'm hoping someone has done some refactoring and spots the differences - I've even run this in the console but I can only add the text to localstorage manually: localstorage.setItem('content', 'help')
Thanks in advance
The problem is that you are trying to select a array, get the value of that array, and output to another array. I think jquery does that when you select a class, (because there could be more than one of them). Simple solution to this..
var input_textarea = $(".content-input")[0];
console.log(input_textarea)
var output_div = $(".content-output")[0];
var save_button = $(".save-button");
save_button.on("click", updateOutput);
output_div.textContent = localStorage.getItem("content");
input_textarea.value = localStorage.getItem(("content"));
function updateOutput(event) {
console.log('hello')
event.preventDefault();
localStorage.setItem("content", input_textarea.value);
output_div.textContent = input_textarea.value;
}
Found it: val() to set and text() to get.
var input_textarea = $(".content-input");
var output_div = $(".content-output");
var save_button = $(".save-button");
save_button.on("click", updateOutput);
// input_textarea.value = localStorage.getItem(("content"));
function updateOutput(event) {
event.preventDefault();
localStorage.setItem("content", input_textarea.val());
output_div.text(localStorage.getItem("content"));
}
this post helped: How to save the value of textarea to localstorage then display it in the same textarea

Assign responseXML values to table cells created by a for loop

I have been playing with JavaScript and Arduino Ethernet Shield for a while and I am trying to send data from Arduino to the webpage it serves using AJAX. The data I send is an array of 24 variables. In order to display the data I created a table in JavaScript using the for() loop. The problem is that when I try to assign the variables to the table cells (one variable per cell), only the first cell of the table receives data. The thing is that when I create the table using HTML (all cells created with the <td></td> tags), the variables are assigned to the table cells properly. Thank you for your time!
Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Arduino WebBased Weather Station</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<style>
#charset 'UTF-8';#import url(https://fonts.googleapis.com/css?family=Open+Sans:300,400,700);
body {
background-color: black;
font-family: 'Open Sans', sans-serif;
line-height: 1em;
text-align: center;
Color: #cccccc;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
margin-left:auto;
margin-right:auto;
}
th {
border: 1px solid #336699;
color:#0040ff;
text-align: center;
padding: 8px;
}
td {
border: 1px solid #336699;
color:#0080ff;
text-align: center;
padding: 8px;
}
td.td2 {
border: 1px solid #336699;
color:#0080ff;
text-align: left;
padding: 8px;
}
</style>
<h1>Arduino Web-Based Weather Station</h1><hr>
<h3>WELCOME!</h3>
<p>Project is hosted on github. Please visit my <a href='https://github.com/zissis-pap'>page</a> for more!</p><hr>
</head>
<body onload="BuiltArray(); GetArduinoIO()"><br>
<div id="array1"></div>
<script>
var bool = false;
function BuiltArray() {
var arr1 ="<table style='width:100%'><tr><th colspan='25'>\
AVERAGE CONDITIONS FOR THE LAST 24 HOURS</th></tr><tr><td\ class='td2'>HOURS:</td>"
for (var i = 0; i <= 23; i++) {
arr1 += "<td><font color='#3d0099'>\
<span class='hrs'>...</span></font></td>";
}
arr1 += "</tr></table>";
document.getElementById("array1").innerHTML = arr1;
bool = true;
}
function GetArduinoIO() {
if(bool == true) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
if (this.responseXML != null) {
// XML file received - contains analog values, switch values and LED states
var count;
// get analog inputs
var num_an = this.responseXML.getElementsByTagName('hours').length;
for (count = 0; count < num_an; count++) {
document.getElementsByClassName("hrs")[count].innerHTML =
this.responseXML.getElementsByTagName('hours')[count].childNodes[0].nodeValue;
}
}
}
}
}
// send HTTP GET request with LEDs to switch on/off if any
request.open("GET", "ajax_inputs", true);
request.send();
setTimeout('GetArduinoIO()', 2000);
}
}
</script>
</body>
</html>

How do I prevent reload when a user is going to write something?

My website has a simple messaging system where users write messages and the recipients answer back, which is defined as chatting.
I'm using an HTML to keep the page refreshing until the person receives a new message.
<meta http-equiv="refresh" content="15;URL=chat_5999468.php"/>
It keeps refreshing the page in every 15 seconds, so if a new message intrudes, it pops up. BUT it reloads the page even whilst the recipient is typing.
How do I prevent this reload when a user is typing his message in jQuery?
Edit: Page HTML (Similar to this):
<!DOCTYPE html> <head> <title>Untitled</title> <meta charset="UTF-8"/> <meta http-equiv="refresh" content="15;URL=chat_5999468.php"/> <style> #b { color: #000; } .chat-input input[type="text"] { width: 65%; height: 30px; border: 1px solid #999999; border-top-right-radius: 10px; border-bottom-left-radius: 15px; padding: 10px; color: #0084ff; margin-left: 5px; margin-top: 10px; margin-bottom: 10px; } input:focus,button:focus,input,button { outline: none!important; } .chat-input input[type="submit"] { color: #000; background: url(https://i.stack.imgur.com/NAjD2.jpg) no-repeat; height: 47px; width: 47px; border: none; } .chat77 ul{ list-style: none; margin: 0; padding: 0; } .chat77 ul li{ display:inline-block; clear: both; padding: 8px; border-radius: 30px; margin-bottom: 2px; font-family: Helvetica, Arial, sans-serif; } .message-2 { background: #eee; float: left; } .message-me { float: right; background: #0084ff; color: #fff; } .message-2 + .message-me{ border-bottom-right-radius: 5px; } .message-2 + .message-me{ border-top-right-radius: 5px; border-bottom-right-radius: 5px; } .message-me:last-of-type { border-bottom-right-radius: 30px; } </style> </head> <body> <div class="chat-input"><label><form method="post" action="chat_5999468.php" ><input type="text" name="txt" placeholder="Write here..." /><input type="submit" name="submit_msg" value="" /></form></label></div><center><div id="chat-status">Online Mark Zuckerberg | Refresh</div></center><br /><div class="chat77"><ul><script>var book="Me: 3";if(book=="Me: 3" ){document.write("<li class='message-me'>3</li>");}else{document.write("<li class='message-2'><a href='/profile_12.php?u=Mark+Zuckerberg' id='b' target='_top'>3</a></li>");}</script><script>var book="Mark Zuckerberg: 2";if(book=="Me: 2" ){document.write("<li class='message-me'>2</li>");}else{document.write("<li class='message-2'><a href='/profile_12.php?u=Mark+Zuckerberg' id='b' target='_top'>2</a></li>");}</script><script>var book="Me: Message1";if(book=="Me: Message1" ){document.write("<li class='message-me'>Message1</li>");}else{document.write("<li class='message-2'><a href='/profile_12.php?u=Mark+Zuckerberg' id='b' target='_top'>Message1</a></li>");}</script></ul></div><br /> </body> </html> 
All I can think is jQuery.ajax(). See here for the jQuery API Documentation
This answer is for you if you want a alternative for your meta tag.
You could get the content of the updated site, search for a specific div or something like that and check if there's a new entry.
This is just an example how you could do it!
First of all, create a loop function:
setInterval(function(){
}, 15000); // The loop function will check every 15 seconds
After that, create the ajax() call.
$.ajax({
url: 'YOUR URL HERE',
type: 'GET',
success: function(data) {
var check = $(data).find('#chat');
// Here you get the `div` -> `#chat`
// Now you could check if there is something new
}
});
I dont know how your chat is coded, but I think there's something with timestamps. Just check if there's a div(?) with a newer timestamp than your opened site:
var compareMe = $('#chat').find('.entry span').last().attr('class');
var compareOther = $(data).find('.entry span').last().attr('class');
In my case there's a div with id="chat" and this have div's which have a class="entry which got a span with a class="1504155239" (thats the timestamp for the message).
Here's an example:
var compareMe = $('#chat').find('.entry span').last().attr('class');
console.log(compareMe);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chat">
<div class="entry">
<span class="1504155239">1504155239: </span>
Hello There! First!
</div>
<div class="entry">
<span class="1504155254">1504155254: </span>
Hey! Ah, I'm second?
</div>
</div>
So the only thing that you have to do now is to check if compareMe and compareOther is the same or newer.
// Lets cast them first to int because of reasons.
// Just kidding, it's safer to cast them and then check if they are newer
compareMe = parseInt(compareMe);
compareOther = parseInt(compareOther);
if (compareMe != compareOther && compareMe > compareOther) {
// Now you can reload.
}
At the end it would look like this:
THIS SNIPPET DON'T WORK! It's just here to visualize how it can be done!
setInterval(function(){ // This is the loop function
$.ajax({
url: '<YOUR URL HERE>',
type: 'GET',
success: function(data) {
var check = $(data).find('#chat');
// Here you get the `div` -> `#chat`
var compareMe = $('#chat').find('.entry span').last().attr('class');
var compareOther = $(check).find('.entry span').last().attr('class');
// Now you could check if there is something new
// Lets cast them first to int because of reasons.
// Just kidding, it's safer to cast them and then check if they are newer
compareMe = parseInt(compareMe);
compareOther = parseInt(compareOther);
if (compareMe != compareOther && compareMe > compareOther) {
// Now you can reload.
}
}
});
}, 15000); // The loop function will check every 15 seconds
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chat">
<div class="entry">
<span class="1504155239">1504155239: </span>
Hello There! First!
</div>
<div class="entry">
<span class="1504155254">1504155254: </span>
Hey! Ah, I'm second?
</div>
</div>
EDIT
Since you've copied your HTML in here, I can help you more specifically.
This is an example for your code.
setInterval(function() {
$.ajax({
url: '/',
type: 'GET',
success: function(data) {
var check = $(data).find('.chat77');
var compareMe = $('.chat77').find('li').last().text();
var compareOther = $(check).find('li').last().text();
if (compareMe != compareOther && $('.chat-input').find('input').first().val() == "") {
location.reload();
}
}
});
}, 3000);
I would prefer that you add a timestamp to the messages and check this instead of strings.

Something breaks when Chrome developer tools are open

I made a quote generator and it works fine with the Chrome developer tools open, but then won't generate a new quote when the developer tools are closed. This happens with my project in CodePen. On my computer, it generates a quote three times (works fine the first three clicks of the generate quote button) then stops working. It's not working at all in Safari. Why would this be?
I'm sure my JavaScript could use some refactoring too, any help there would also be great. Thanks!
Link to CodePen Demo
HTML
<html>
<head>
<title>Random Quote Generator</title>
<link rel="stylesheet" type="text/css" href="css/quote.css">
<link href='https://fonts.googleapis.com/css?family=Lato:300italic,300' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="quote-container">
<div class="quote" id="msg"></div>
</div>
<div class="button-container">
Get Quote
</div>
<div id="twtbtn"></div>
<script src="https://code.jquery.com/jquery-3.0.0.min.js" integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script>
<script type="text/javascript" src="js/quote.js"></script>
</body>
</html>
CSS
body {
background: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url('https://images.unsplash.com/photo-1437652010333-fbf2cd02a4f8?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&s=2330269f135faf1c33bf613b85d5f1df');
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
}
* {
font-family: 'Lato', sans-serif;
}
.quote-container {
display: flex;
flex-direction: column;
justify-content: center;
}
.quote {
width: 80%;
text-align: center;
margin: 0 auto;
font-size: 48px;
font-style: italic;
color: white;
}
.button-container {
margin: 30px auto 50px auto;
text-align: center;
}
#button {
border: 1px solid white;
padding: 12px 30px;
background: transparent;
font-size: 18px;
border-radius: 2px;
}
#button:hover {
background-color: white;
}
a {
text-decoration: none;
color: white;
}
a:hover {
color: black;
};
JavaScript
$(document).ready(function(){
//get quote from random quote API
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
//append quote and author to document
$(".quote").append(a[0].content + "<p>— " + a[0].title + "</p>")
//initiate twitter button function
window.twttr = (function (d,s,id) {
var t, js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return; js=d.createElement(s); js.id=id;
js.src="https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs);
return window.twttr || (t = { _e: [], ready: function(f){ t._e.push(f) } });
}(document, "script", "twitter-wjs"));
//insert tweet button
insertTweetBtn();
});
});
$("a").click(function(){
//get quote from random quote API
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
//replace HTML with newly generated quote
$(".quote").html(a[0].content + "<p>— " + a[0].title + "</p>")
//remove contents of tweet button div
$("#twtbtn").empty();
//insert new tweet button to grab newly generated quote
insertTweetBtn();
});
});
function insertTweetBtn() {
var msg = document.getElementById('msg').textContent;
twttr.ready(function (twttr) {
twttr.widgets.createShareButton(
'',
document.getElementById('twtbtn'),
function (el) {
console.log("Button created.")
},
{
text: msg ,
}
);
twttr.events.bind('tweet', function (event) {
console.log(event, event.target);
});
});
}
Ok...so i was going crazy trying to figure it out then I went to the documentation for getJSON for jquery. I am not 100% about JSONP but thats the thing, when you add the &callback into the url..it uses JSONP. So I removed it and it works great in safari. Here is the codepen
FIXED
and here is the quote from jquery:
"If the URL includes the string "callback=?" (or similar, as defined by the server-side API), the request is treated as JSONP instead. See the discussion of the jsonp data type in $.ajax() for more details."
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1", function(a) {stuff}
This unfortunately doesn't explain why safari is the only one it didn't work in...but hey, it fixes it :)

Check to see if browser has Pinterest Pin it button

I have written a script to add a Pinterest button to most images on my site. The issue is that when someone has the Chrome Pin it extension enabled in their browser, the "pin it" button shows up twice for the user.
Is there anyway, in JavaScript, to check if the user has this extension enabled in their browser?
(function($) {
$(function() {
$('.container img').each(function() {
if ($(this).parent('a')) {
var $permalink = $(this).parent('a').attr('href');
}
else {
var $permalink = $(location).attr('href');
}
var $permalink = $(location).attr('href'),
$title = $('h1.product_name').text() || $('h2.header');
var $linkhtml = $('<a/>', {
'class':'pin-it-button pinme',
'html': '<img src="//assets.pinterest.com/images/pidgets/pinit_fg_en_rect_gray_20.png" />',
'count-layout': 'horizontal',
'style': 'cursor:pointer; position:absolute; bottom:30px; left:0; border:0 none; opacity: 0.4;',
'href': 'http://pinterest.com/pin/create/button/?url=' + $permalink + '&media=' + $(this).attr('src') + '&description=' + $title
});
if ($(this).parent('a')) {
$(this).addClass('pinme').parent('a').after($linkhtml);
}
else {
$(this).addClass('pinme').after($linkhtml);
}
$('.pinme').hover(
function() {
if ($(this).hasClass('pin-it-button')) {
console.log('hello');
$(this).css('opacity', '1');
}
else {
$(this).parent().siblings('.pin-it-button').css('opacity', '1');
}
}, function() {
if ($(this).hasClass('pin-it-button')) {
$(this).css('opacity', '0.4');
}
else {
$(this).parent().siblings('.pin-it-button').css('opacity', '0.4');
}
}
);
});
});
})(jQuery);
The new Pinterest extension (2017)
injects a <span> hover button directly under <body:
<span style="border-radius: 3px;
text-indent: 20px;
width: auto;
padding: 0px 4px 0px 0px;
text-align: center;
font-style: normal;
font-variant: normal;
font-weight: bold;
font-stretch: normal;
font-size: 11px;
line-height: 20px;
font-family: "Helvetica Neue", Helvetica, sans-serif;
color: rgb(255, 255, 255);
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzBweCIgd2lkdGg9IjMwcHgiIHZpZXdCb3g9Ii0xIC0xIDMxIDMxIj48Zz48cGF0aCBkPSJNMjkuNDQ5LDE0LjY2MiBDMjkuNDQ5LDIyLjcyMiAyMi44NjgsMjkuMjU2IDE0Ljc1LDI5LjI1NiBDNi42MzIsMjkuMjU2IDAuMDUxLDIyLjcyMiAwLjA1MSwxNC42NjIgQzAuMDUxLDYuNjAxIDYuNjMyLDAuMDY3IDE0Ljc1LDAuMDY3IEMyMi44NjgsMC4wNjcgMjkuNDQ5LDYuNjAxIDI5LjQ0OSwxNC42NjIiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxIj48L3BhdGg+PHBhdGggZD0iTTE0LjczMywxLjY4NiBDNy41MTYsMS42ODYgMS42NjUsNy40OTUgMS42NjUsMTQuNjYyIEMxLjY2NSwyMC4xNTkgNS4xMDksMjQuODU0IDkuOTcsMjYuNzQ0IEM5Ljg1NiwyNS43MTggOS43NTMsMjQuMTQzIDEwLjAxNiwyMy4wMjIgQzEwLjI1MywyMi4wMSAxMS41NDgsMTYuNTcyIDExLjU0OCwxNi41NzIgQzExLjU0OCwxNi41NzIgMTEuMTU3LDE1Ljc5NSAxMS4xNTcsMTQuNjQ2IEMxMS4xNTcsMTIuODQyIDEyLjIxMSwxMS40OTUgMTMuNTIyLDExLjQ5NSBDMTQuNjM3LDExLjQ5NSAxNS4xNzUsMTIuMzI2IDE1LjE3NSwxMy4zMjMgQzE1LjE3NSwxNC40MzYgMTQuNDYyLDE2LjEgMTQuMDkzLDE3LjY0MyBDMTMuNzg1LDE4LjkzNSAxNC43NDUsMTkuOTg4IDE2LjAyOCwxOS45ODggQzE4LjM1MSwxOS45ODggMjAuMTM2LDE3LjU1NiAyMC4xMzYsMTQuMDQ2IEMyMC4xMzYsMTAuOTM5IDE3Ljg4OCw4Ljc2NyAxNC42NzgsOC43NjcgQzEwLjk1OSw4Ljc2NyA4Ljc3NywxMS41MzYgOC43NzcsMTQuMzk4IEM4Ljc3NywxNS41MTMgOS4yMSwxNi43MDkgOS43NDksMTcuMzU5IEM5Ljg1NiwxNy40ODggOS44NzIsMTcuNiA5Ljg0LDE3LjczMSBDOS43NDEsMTguMTQxIDkuNTIsMTkuMDIzIDkuNDc3LDE5LjIwMyBDOS40MiwxOS40NCA5LjI4OCwxOS40OTEgOS4wNCwxOS4zNzYgQzcuNDA4LDE4LjYyMiA2LjM4NywxNi4yNTIgNi4zODcsMTQuMzQ5IEM2LjM4NywxMC4yNTYgOS4zODMsNi40OTcgMTUuMDIyLDYuNDk3IEMxOS41NTUsNi40OTcgMjMuMDc4LDkuNzA1IDIzLjA3OCwxMy45OTEgQzIzLjA3OCwxOC40NjMgMjAuMjM5LDIyLjA2MiAxNi4yOTcsMjIuMDYyIEMxNC45NzMsMjIuMDYyIDEzLjcyOCwyMS4zNzkgMTMuMzAyLDIwLjU3MiBDMTMuMzAyLDIwLjU3MiAxMi42NDcsMjMuMDUgMTIuNDg4LDIzLjY1NyBDMTIuMTkzLDI0Ljc4NCAxMS4zOTYsMjYuMTk2IDEwLjg2MywyNy4wNTggQzEyLjA4NiwyNy40MzQgMTMuMzg2LDI3LjYzNyAxNC43MzMsMjcuNjM3IEMyMS45NSwyNy42MzcgMjcuODAxLDIxLjgyOCAyNy44MDEsMTQuNjYyIEMyNy44MDEsNy40OTUgMjEuOTUsMS42ODYgMTQuNzMzLDEuNjg2IiBmaWxsPSIjYmQwODFjIj48L3BhdGg+PC9nPjwvc3ZnPg==") 3px 50% / 14px 14px no-repeat rgb(189, 8, 28);
position: absolute;
opacity: 1;
z-index: 8675309;
display: none;
cursor: pointer;
border: none;
-webkit-font-smoothing: antialiased;
top: 240px;
left: 110px;
">Save</span>
So a simple check would be:
var pin = document.querySelector('body > span[style*="8675309"][style*="rgb(189, 8, 28)"]')
Or you can check for the entire background base64 string which contains the P logo.
Old answer for the old PinIt extension:
Examining a page with Pin It extension installed we can see that it adds its own attribute to <body>:
<body data-pinterest-extension-installed="cr1.39.1">
It's easy to determine the presence of the attribute in js:
if (document.body.dataset.pinterestExtensionInstalled) {
console.log("Pin It extension detected!");
}
Note that the attribute is added after the page has been loaded so you can't check it right in DOMContentLoaded event handler; make a pause with setInterval or use MutationObserver:
Content script with "run_at": "document_end" or "document_idle" (the default mode):
var PinItInstalled = undefined;
new MutationObserver(function(mutations) {
PinItInstalled = document.body.dataset.pinterestExtensionInstalled;
this.disconnect();
}).observe(document.body, {
attributes: true,
attributeFilter: ["data-pinterest-extension-installed"]
});
Content script with "run_at": "document_start":
var PinItInstalled = undefined;
document.addEventListener("DOMContentLoaded", function() {
new MutationObserver(function(mutations) {
PinItInstalled = document.body.dataset.pinterestExtensionInstalled;
this.disconnect();
}).observe(document.body, {
attributes: true,
attributeFilter: ["data-pinterest-extension-installed"]
});
});
P.S. Don't forget to test what happens if the Pin It extension's option to show its button on hover is disabled.
While detecting the presence of the extension or pinit.js on the page may be worthwhile, the easier solution is to simply add the data-pin-no-hover attribute to your images. This will tell the extension to ignore the images.
<img src="whatevz" data-pin-no-hover="true" />
There really isn't any reason to care if it is installed or not if the data-pin attribute is set.
The other option is to not create your own hover buttons, but use pinit.js that creates the hover buttons for you. See the docs.
<script
type="text/javascript"
async defer
data-pin-hover="true"
src="//assets.pinterest.com/js/pinit.js"
></script>

Categories