I'm using a script to retrieve content from an external website, and the date is returned with certain elements stripped out so that they don't interfere with the page I'm pulling the data to. However, when I view my page with the error console open, I am receiving 404s on all images. Is there anyway I can strip out all the images from the script so that I'm just getting the text (which is still in its formatted tags)?
$(document).ready(function () {
var container = $('#target');
function doAjax(url) {
if (url.match('^http')) {
$.getJSON("http://query.yahooapis.com/v1/public/yql?"
+ "q=select%20*%20from%20html%20where%20url%3D%22"
+ encodeURIComponent(url)
+ "%22&format=xml'&callback=?",
function (data) {
if (data.results[0]) {
var fullResponse = $(filterData(data.results[0])),
justTable = fullResponse.find("table");
container.append(justTable);
} else {
var errormsg = '<p>Error: could not load the page.</p>';
container.html(errormsg);
}
});
} else {
$('#target').load(url);
}
}
function filterData(data) {
data = data.replace(/<?\/body[^>]*>/g, '');
data = data.replace(/[\r|\n]+/g, '');
data = data.replace(/<--[\S\s]*?-->/g, '');
data = data.replace(/<noscript[^>]*>[\S\s]*?<\/noscript>/g, '');
data = data.replace(/<script[^>]*>[\S\s]*?<\/script>/g, '');
data = data.replace(/<script.*\/>/, '');
return data;
}
doAjax('mywebsite');
});
Option 1:
You can strip the images by adding this line to filterData() function:
data = data.replace(/<img[^>]*>/g, '');
This will replace all strings starting with <img and then containing zero or more characters other than > with an empty string.
Option 2:
You can use jQuery to remove the elements. Insert this before container.append():
justTable.find("img").remove();
This will find all img elements inside the table and remove them.
Alternative:
Some images are not available because their URL is relative. If you have <img src="logo.png"> on http://example.com/page.html then browser is loading the image from example.com/logo.png. If you include the same <img> tag to your page http://own.com/my.html then browser will try to load own.com/logo.png.
You can fix this issue by changing the src attribute of the images to include the domain you retrieved the page from.
Example (not fully tested, may need modifications):
// copy everything for url except the string after last "/" character
// so if url == http://example.com/page.html then path == http://example.com/
var path = url.match("(.+/)[^/]+$")[1];
// modify all local images (value of src attribute not starting with "http://")
justTable.find('img').not('[src^="http://"]').attr('src', function() {
return path + $(this).attr('src');
});
Related
I have created a google chrome extension to replace certain images from third party websites. I have implement all the programming part but one of my requirements states that
On a slower net connection the original images should not be visible
until it’s replaced by the new images
I am not sure wether it is achievable or not. I want to know what sort of event I should attach here. Can experts give their input on this?
This is the work I have done.
// get current websites base url
var current_website = window.location.href;
//run the code on specific pages
if ($.inArray(current_website, config.target_websites) != -1) {
config.image_config.forEach(function (obj) {
var src = obj.src;
var target = obj.target;
/**find all the occurances in the <img> tag */
var key = 'img[src*="' + src + '"]';
var img = $(key);
/**replace it with the target image*/
img.attr('src', target);
/** check the inline CSS*/
$("[style*=background-image]").css('background-image', function (i, oldimg) {
return oldimg.indexOf(src) == -1 ? oldimg : 'url(' + target + ')';
});
/***check all the external styles for the image*/
$('*').each(function () {
if ($(this).css('background-image').indexOf(src) != -1) {
$(this).css('background-image', 'url(' + target + ')');
}
});
});
}
Since you're already using jQuery, if you're not opposed to a small library (7.25 KB), you can use the jQuery plugin imagesloaded.
Basic usage:
// options
$('#container').imagesLoaded( {
// options...
},
function() {
// your code to run after load
}
);
Then you could do a simple $('img').hide() on load, and $('img').show() after all images have loaded on your particular images.
You can see in the demo that it works for images which have been inserted dynamically into the page as well, which would meet your requirement for that the images of your key be hidden until replaced.
http://imagesloaded.desandro.com/
I want to start a greasemonkey plugin to an existing page. The plugin should fetch and display some images automatically, each image from different pages.
I thought of using jQuery.get("link", function(data)) and hide the page and display the images only but on an average to display 4 images I should load 6 webpages into present webpage it is creating a delay in loading.
Is there any other work around to create a function that loads the page html of all image pages in background or in another tab and get the href of <a> tag's in that page, into my page and load only images into my page?
You can try this solution below.
Just put the URLs you want in the "pages" array. When the script runs, it makes Ajax calls in the background. When they are ready, it searches the source returned for images and picks one randomly. If found, it wraps the image in a link to the page where it found it (or if available, the image's url) and inserts the linked image to the top of the body of your own current page.
You can try the code by pasting it into your browser's JavaScript console and it will add the images to the current page.
You also see a demo here: http://jsfiddle.net/3Lcj3918/3/
//pages you want
var pages =
[
'https://en.wikipedia.org/wiki/Special:Random',
'https://en.wikipedia.org/wiki/Special:Random',
'https://en.wikipedia.org/wiki/Special:Random',
'https://en.wikipedia.org/wiki/Special:Random',
'https://en.wikipedia.org/wiki/Special:Random'
]
//a simple function used to make an ajax call and run a callback with the target page source as an argument when successful
function getSubPageSource(url, successCallback)
{
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
//when source returned, run callback with the response text
successCallback(xhr.responseText);
}
};
//requires a proxy url for CORS
var proxyURL = 'https://cors-anywhere.herokuapp.com/';
xhr.open('GET', proxyURL+url, true);
//set headers required by proxy
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
xhr.setRequestHeader("Access-Control-Allow-Origin","https://cors-anywhere.herokuapp.com/");
xhr.send();
}
//a function that extract images from given url and inserts into current page
function injectImagesFrom(url)
{
getSubPageSource(url, function(data)
{
//trim source code to body only
var bodySource = data.substr(data.indexOf('<body ')); //find body tag
bodySource = bodySource.substr(bodySource.indexOf('>') + 1); //finish removing body open tag
bodySource = bodySource.substring(0, bodySource.indexOf('</body')); //remove body close tag
//create an element to insert external source
var workingNode = document.createElement("span");
//insert source
workingNode.innerHTML = bodySource;
//find all images
var allImages = workingNode.getElementsByTagName('img');
//any images?
if (allImages.length > 0)
{
//grab random image
var randomIndex = Math.floor(Math.random() * allImages.length);
var randomImage = allImages.item(randomIndex);
//add border
randomImage.setAttribute('style', 'border: 1px solid red;');
//restrain size
randomImage.setAttribute('width', 200);
randomImage.setAttribute('height', 200);
//check if parent node is a link
var parentNode = randomImage.parentNode;
if (parentNode.tagName == 'A')
{
//yes, use it
var imageURL = parentNode.getAttribute('href');
}
else
{
//no, use image's page's url
var imageURL = url;
}
//add a link pointing to where image was taken from
var aLink = document.createElement("a");
aLink.setAttribute('href', imageURL);
aLink.setAttribute('target', '_blank');
//insert image into link
aLink.appendChild(randomImage);
/* INSERT INTO PAGE */
//insert image in beginning of body
document.body.insertBefore(aLink,document.body.childNodes[0]);
//remove working node children
while (workingNode.firstChild) {
workingNode.removeChild(workingNode.firstChild);
}
//unreference
workingNode = null;
}
});
}
for (var ii = 0, nn = pages.length; ii < nn; ii++)
{
injectImagesFrom(pages[ii]);
}
I need an image to be displayed based on the ending of a URL.
For example, I need "123.jpg" to be displayed when someone visits:
website.com/view/#123
website.com/view/#123.jpg
website.com/view#123
website.com/view#123.jpg
(whichever is recommended or would actually work)
I'm looking for the end result to be: < img src=123.jpg" >
Thanks in advance. I will sincerely appreciate any assistance.
(By way of background or additional information, I need this for Facebook's sharer.php so that people can share one of hundreds of images on a given webpage (for example, website.com/blog and they happen to love the 123rd image on there), they click the link to share that specific image (123.jpg), and then any of their friends who clicks on the link (website.com/view/#123) will arrive at a themed page with just the image in the middle (123.jpg) and nothing else, and then they can click around the rest of the website. The main benefit is that 123.jpg will be the only image that shows up as a thumbnail on the Facebook Feed or "Wall".)
window.onhashchange = function() {
if (location.hash) {
var url = location.hash.substr(1); // strip the # char
if (url.indexOf('.') == -1) {
url += '.jpg';
}
document.getElementById('myImg').src = url; // show the image; value of the variable 'url'
}
};
window.onhashchange(); // call the event on load
Use something like this.
$(document).ready(function(){
var url = document.URL; //get the url
if ( url.indexOf("#") != -1 ) //check if '#' is present in the url
{
var split_array = url.split("#");
var image_url = split_array[split_array.length - 1];
//display the image
}
});
Try this out,
$(document).ready(function() {
getImageSrc();
$(window).on('hashchange', getImageSrc); // will always lookout for changes in # URL
});
function getImageSrc() {
if(window.location.hash) {
var imgSrc = window.location.hash.substr(1);
if(imgSrc.indexOf('.') == -1 ) {
imgSrc = imgSrc + ".jpg";
}
alert(imgSrc);
}
}
How can I get the path of the current script in javascript using jQuery
for example I have site.com/js/script.js and there is a code in this script:
$(document).ready(function() {
alert( ... this code ... );
}
It Should return alert box with the "/js/script.js" message. This function should work like magic __FILE__ constant in php
So, why do I need this?
I want to set background image dynamically:
$("somediv").css("background-image", "url(" + $SCRIPT_PATH + "/images/img.png)");
and images directory is the /js directory, near the script.js file
and js folder's name can be dynamically set, so script and images can be in the /myprogect/javascript-files directory
You can rely on the fact that each <script> element has to be evaluated* before the next one is inserted into the DOM.
This means that the script currently evaluated (as long as it is part of your markup and not dynamically inserted) will be the last one in the NodeList retrieved with getElementsByTagName( 'script' ).
This allows you to read that elements src attribute and from that determine the folder that the script is being served from - like this:
var scriptEls = document.getElementsByTagName( 'script' );
var thisScriptEl = scriptEls[scriptEls.length - 1];
var scriptPath = thisScriptEl.src;
var scriptFolder = scriptPath.substr(0, scriptPath.lastIndexOf( '/' )+1 );
console.log( [scriptPath, scriptFolder] );
I tried this technique with 3 scripts loaded from different folders and get this output
/*
["http://127.0.0.1:8000/dfhdfh/folder1/script1.js", "http://127.0.0.1:8000/dfhdfh/folder1/"]
["http://127.0.0.1:8000/dfhdfh/folder2/script2.js", "http://127.0.0.1:8000/dfhdfh/folder2/"]
["http://127.0.0.1:8000/dfhdfh/folder3/script3.js", "http://127.0.0.1:8000/dfhdfh/folder3/"]
*/
* from John Resigs blog linked to above
This means that when the script finally executes that it'll be the
last script in the DOM - and even the last element in the DOM (the
rest of the DOM is built incrementally as it hits more script tags, or
until the end of the document).
Update
As pimvdb points out - this will work as the script is being evaluated. You will need to store the path somehow if you are going to use it later. You can't query the DOM at a later point. If you use the same snippet for each script the value of scriptFolder will be overwritten for each script. You should give each script a unique variable perhaps?
Wrapping your script in its own scope closes over the value of scriptFolder making it available to the rest of the script without fear of being overwritten
(function() {
var scriptEls = document.getElementsByTagName( 'script' );
var thisScriptEl = scriptEls[scriptEls.length - 1];
var scriptPath = thisScriptEl.src;
var scriptFolder = scriptPath.substr(0, scriptPath.lastIndexOf( '/' )+1 );
$( function(){
$('#my-div').click(function(e){
alert(scriptFolder);
});
});
})();
Add the following code to your JS :
var retrieveURL = function(filename) {
var scripts = document.getElementsByTagName('script');
if (scripts && scripts.length > 0) {
for (var i in scripts) {
if (scripts[i].src && scripts[i].src.match(new RegExp(filename+'\\.js$'))) {
return scripts[i].src.replace(new RegExp('(.*)'+filename+'\\.js$'), '$1');
}
}
}
};
Suppose these are the scripts called in your HTML :
<script src="assets/js/awesome.js"></script>
<script src="assets/js/oldcode/fancy-stuff.js"></script>
<script src="assets/js/jquery/cool-plugin.js"></script>
Then, you can use the function like this
var awesomeURL = retrieveURL('awesome');
// result : 'assets/js/'
var awesomeURL = retrieveURL('fancy-stuff');
// result : 'assets/js/oldcode/'
var awesomeURL = retrieveURL('cool-plugin');
// result : 'assets/js/jquery/'
Note that this only works when there are no two script files in your HTML with the same name. If you have two scripts with the same name that are located in a different folder, the result will be unreliable.
Note
If you dynamically add scripts to your page, you need to make sure your code is executed after the last script has been added to the DOM.
The follow example shows how to do this with one dynamically loaded script. It outputs a JSON array with the src link for scripts that load an external js file and a base64-encoded string of the JS content for inline scripts:
var addScript = function(src, callback) {
var s = document.createElement( 'script' );
s.setAttribute( 'src', src );
document.body.appendChild( s );
s.onload = callback;
}
var retrieveURL = function(filename) {
var scripts = document.getElementsByTagName('script');
if (scripts && scripts.length > 0) {
for (var i in scripts) {
if (scripts[i].src && scripts[i].src.match(new RegExp(filename+'\\.js$'))) {
return scripts[i].src.replace(new RegExp('(.*)'+filename+'\\.js$'), '$1');
}
}
}
};
addScript('https://code.jquery.com/jquery-1.12.4.min.js', function() {
var scripts = document.getElementsByTagName('script');
var sources = [];
for (var i = 0; i < scripts.length; i++) {
if(scripts[i].src == '') {
sources.push(btoa(scripts[i].innerHTML));
} else {
sources.push(scripts[i].src);
}
}
document.body.innerHTML += '<pre>' + JSON.stringify(sources,null,2) + '</pre>';
});
See also this Fiddle.
I don't think jQuery provide such a functionality.
Anyway you can get currentc script path path (both fully http and relative) by reading the answer here: What is my script src URL?
Can't you set a kind of path variable in the js? So, you save the path of the file in the file itself.
For example:
$(function() {
var FilePath = "js/some/path";
setMyDynamicImageUsingPath(FilePath);
});
// ...
function setMyDynamicImageUsingPath(path) {
$("somediv").css("background-image", "url(" + path + "/images/img.png)");
}
I have a function doing the following using javascript:
Create link element and set href=cssFile.
Insert the link element in head tag.
Create a div element.
Set the class name using setAttribute
appendChild the div on body.
Now getting CSS rule value using document.defaultView.getComputedStyle(divElement, null)[cssRule].
Now getComputedStyle is returning the default values, and if I wait on breakpoint using Firebug before getComputedStyle call, then it returns the CSS rule from the CSS injected.
Regards,
Munim
You can create the dynamic css url and fetch the css as plain text using a normal ajax call.
Then use this to load the css:
function loadCss(cssText, callback){
var style = document.createElement('style');
style.type='text/css';
if(callBack != undefined){
style.onload = function(){
callBack();
};
}
style.innerHTML = cssText;
head.appendChild(style);
}
And use it like this:
loadCss(ajaxResponseText, function(){
console.log("yaay css loaded, now i can access css defs");
})
This is actually what I did.
To ensure a specific CSS file is loaded, I added a style in the end of the CSS file. For example:
#ensure-cssload-8473649 {
display: none
}
Now I have a JavaScript function which will fire the callback specified when the above style is loaded on the page:
var onCssLoad = function (options, callback) {
var body = $("body");
var div = document.createElement(constants.TAG_DIV);
for (var key in options) {
if (options.hasOwnProperty(key)) {
if (key.toLowerCase() === "css") {
continue;
}
div[key] = options[key];
}
}
var css = options.css;
if (css) {
body.appendChild(div);
var handle = -1;
handle = window.setInterval(function () {
var match = true;
for (var key in css) {
if (css.hasOwnProperty(key)) {
match = match && utils.getStyle(div, key) === css[key];
}
}
if (match === true) {
window.clearTimeout(handle);
body.removeChild(div);
callback();
}
}, 100);
}
}
And this is how I used the function above:
onCssLoad({
"id": "ensure-cssload-8473649",
css: {
display: "none"
}
}, function () {
// code when you want to execute
// after your CSS file is loaded
});
Here the 1st parameter takes the options where id is to check against the test style and css property to verify against what loaded from the CSS.
I assume you are doing this because you need to dynamically create the URL of the stylesheet.
Couple options come to mind:
1) Create the URL server-side and avoid this problem altogether.
2) Use a setTimeout to check whether or not the style has been loaded and check every 20ms or so until getComputedStyle returns the value you want.
I don't like #2 at all...but it's an option. If you use #2 make sure to clear the timeout even if there is an exception.
Here is a solution that seems to work across all browsers.
function loadCss(fileUrl) {
// check for css file type
if (fileUrl.indexOf(".css")==fileUrl.length-4) {
// Create link element
var fileref=document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", fileUrl);
if (typeof fileref!="undefined") {
// remove the . if this is a relative link
if(fileUrl.indexOf('.')==0) {
fileUrl = fileUrl.substr(1);
}
// generate the full URL to use as the fileId
var pathname = window.location.pathname;
var pathUrl = pathname.substr(0,pathname.lastIndexOf("/"));
var fileId = window.location.protocol + "//" + window.location.host + pathUrl + fileUrl;
// append the newly created link tag to the head of the document
document.getElementsByTagName("head")[0].appendChild(fileref);
// begin checking for completion (100ms intervals up to 2000ms)
this.checkCSSLoaded(fileId,100,0,2000);
} else throw 'INVALID_CSS_ERROR';
} else throw 'INVALID_CSS_ERROR';
}
function checkCSSLoaded(cssHref,milliPerCheck,milliPerCount,milliTimeout) {
// Look through all sheets and try to find the cssHref
var atSheet = -1;
var sheetLength = document.styleSheets.length;
while(++atSheet < sheetLength ) {
if(cssHref == document.styleSheets[atSheet].href) {
// If found dispatch and event or call a procedure
/* Do whatever is next in your code here */
return;
}
}
// check for timeout
if(milliCount > milliTimeout) {
alert('INVALID_CSS_ERROR::'+" ("+cssHref+"+ not found!");
/* Do whatever happens if timeout is reached here */
return;
}
// else keep trying
setTimeout(checkCSSLoaded ,milliPerCheck, cssHref, milliPerCheck, milliCount+millPerCheck, milliTimeout);
}
Essentially we
Create a link tag.
Set its attributes so it knows its a stylesheet link tag
Create a file id in such a way that it will always be the full file URL
Append the link tag to the head of the document head
Perform consecutive tests to see if (stylesheet.href == fileID) comes into existence
If found do something else if timeout do something else keep checking
Using document.styleSheets to check if a css is loaded is wrong, since as soon as a css link is being added to the DOM, it will be available from document.styleSheets, even if it is not loaded yet.
Adding a marker to CSS is hacky too.
The correct solution is to listen to the onload event :
var loadedCss = {};
cssHref = "http://www.foo.com/bar.css";
css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", cssHref);
css.onload = function(){
loadedCss[cssHref] = true;
}
document.getElementsByTagName("head")[0].appendChild(css);
function isCssLoaded(url) {
return loadCss[url];
}