I have a site that builds the pages dynamically. It's a SharePoint site. The site contains a lot of document libraries. The libraries contain word, excel and PDF documents. When a user clicks on a document, the document opens in the client application for office documents only. PDFs simply open in the same window. when people close the window containing the document, they close the site. I'm trying to use javascript to onload add target="_blank" to the PDF links.
So far I have:
window.onload = function(){
l=document.links.length;
for(i = 0; i<l; i++) {
n = document.links[i].href.indexOf(".pdf");
if (n > 0){
document.links[i].setAttribute('target', '_blank');
}
}
}
This code sort of works as some of the pdf links load in a new window as expected, some load in the parent window and some links load in both a new window and the parent. How do I tell the browser not to load in the parent window and only in the new window?
This is what I want to achieve:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
a.pdf<br /><br />
b.html<br /><br />
c.pdf<br /><br />
<script>
window.onload = function(){
l=document.links.length;
for(i = 0; i<l; i++) {
n = document.links[i].href.indexOf(".pdf");
if (n > 0){
document.links[i].setAttribute('target', '_blank');
}
}
}
</script>
</body>
</html>
The problem I'm running into is that sharepoint document libraries are modifying the link behavior such that the javascript does not make then open in a new window. Below is an example of a link from a document library:
<a onfocus="OnLink(this)" href="https://rcd.sharepoint.com/HR/HR%20Policy%20Manual.pdf" onmousedown="return VerifyHref(this,event,'0','','')" onclick="return DispEx(this,event,'TRUE','FALSE','FALSE','','0','','','','','331','0','0','0x7fffffffffffffff','','')">HR Policy Manual</a>
If you don't have access to all elements for ahead with capturing all clicks on the page. Use addEventListener with enabled capturing for handling event. Test whether it's anchor tag and proceed to new page by own with code below:
document.addEventListener("click", function(e){
if (e.target.localName == 'a') {
var url = e.target.getAttribute('href');
e.stopPropagation();
// You can place extra checks here.
var tab = window.open(url, '_blank');
tab.focus();
}
}, true)
Do
Here is what I would do, I think I would collect the anchors and loop over them to check if the hrefs ends with .pdf and then add a function on all the .pdf links
Don't
Don't check for pdf files with .indexOf('.pdf'). Your check should fail If there's a filename called somedummyfile.pdf.something.png (which is a .png image) or any other formatted file.
Note that, new window might be blocked at user's end if they are using add-blockers.
Here is the Snippet:
function modifyLinks() {
let links = document.getElementsByTagName('a');
let properties = 'height=' + window.innerHeight + ',width=' + window.innerWidth + ',' + 'scrollbars=yes,status=yes';
for (i = 0; i < links.length; i++) {
if (links[i].href.endsWith('.pdf')) {
// links[i].setAttribute('target', '_blank'); // if you want to open them in new tab;
console.log(links[i].href);
links[i].addEventListener('click', function(e) {
e.preventDefault();
window.open(this.href, '_blank', properties);
})
}
}
}
window.addEventListener('load', modifyLinks);
File 1
File 2
File 3
HTML Link
Some Other file
I added the following JavaScript to get links containing "pdf" to open in a new window:
window.onload = function(){
l=document.links.length;
for(i = 0; i<l; i++) {
n = document.links[i].href.indexOf(".pdf");
if (n > 0){
document.links[i].setAttribute('target', '_blank');
}
}
}
I then noticed that document libraries were using a DispEx() javascript function on click of document links which negated the first bit of code. I had to overload the function with my own functionality.
function DispEx(a){
if (a.href.endsWith('.pdf')){
window.open(a);
return false;
}
}
Using both pieces of JavaScript in a content editor web part, I got PDF documents to open in a new window and all other links/documents to load in the same window.
Related
I have one HTA file, one JS file is enqueued to the HTA file and HTML files with contents are loaded into the HTA file.
For example this is my_hta_file.hta
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=9.0" />
</head>
<body></body>
</html>
<script type="text/javascript" src="my_js_file.js"></script>
and this is my_js_file.js
function getFileContent(filePath) {
var fileStream = new ActiveXObject('ADODB.Stream');
fileStream.Type = 2;
fileStream.Charset = 'utf-8';
fileStream.Open();
fileStream.loadFromFile(filePath);
var fileContent = fileStream.ReadText();
fileStream.Close();
return fileContent;
}
// initial loading of home page
document.body.innerHTML = getFileContent('index.html');
var pageLinks = document.querySelectorAll('a');
for(i = 0; i < pageLinks.length; i++) {
var linkHref = pageLinks[i].getAttribute('href');
pageLinks[i].setAttribute('href','#!'+linkHref);
// I add this leading prefix to prevent following by the link when click by it
pageLinks[i].onclick = function() {
var page = this.getAttribute('href').substring(3);
if(page == '') {
var page = 'index';
}
// load HTML of the page by link path when click by the link
document.body.innerHTML = getFileContent(page+'.html');
}
}
and my HTML files with contents are:
index.html
Home
Second
Third
<div>Home page content</div>
second.html
Home
Second
Third
<div>Second page content</div>
third.html
Home
Second
Third
<div>Third page content</div>
When I click by a link, I need to load all the HTML content from the HTML file by the link path including the very links I click by.
If I open my HTA file and click the link "Second", I get the second page links and content successfully.
But after that if I click the link "Third", I get the error
Cannot find file 'file:///D:/third' ...
How to resolve the problem?
UPDATE 1
If I move my script to the bottom of the HTA body and add a div for loading HTML for example
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=9.0" />
</head>
<body>
<div id="body"></div>
<script type="text/javascript" src="my_js_file.js"></script>
</body>
</html>
and in my JS file load HTML into div i.e.
document.getElementById('body').innerHTML = ...
instead of
document.body.innerHTML = ...
the problem still remains
As said in the comments, all the links with attached event listeners are replaced by new elements when innerHTML is changed. These new links don't have the listeners which the old elements had.
The snippet below shows how you can use a function to reinit the listeners. The snippet assumes a content wrapper element is used (as you already seem to use it). I've also simplified the code a bit, and used more modern JS (since IE9 mode is used in the OP).
function getFileContent (filePath) {
// As it currently is
}
// Handles clicks on the links
function newContent (e) { // e contains information of the current event
var path = e.target.href || 'index',
body = document.getElementById('body');
e.preventDefault(); // Prevents the default action of the clicked link
body.innerHTML = getFileContent(path + '.html');
init(); // Initialize the new content
return;
}
// Initializes the page
function init() {
var links = document.querySelectorAll('a'),
i, ei;
for (i = 0, ei = links.length; i < ei; i++) {
links[i].addEventListener('click', newContent);
}
return;
}
// Initialize the first page
init();
I have a help link. If a user clicks on it, it opens a new window with fixed width and height. It's working well except that when I right click the link, there is either no options to 'open in a new tab' (in IE) or I can open in a new tab but is directed to an empty page (chrome). Can any one help to make this like a link and also by default open in a new window (not a tab)?
<html>
<head>
<title>
link
</title>
<script type="text/javascript">
function activateHelpView(helpUri) {
var WindowId = 'SomeWindowId';
var helpWindow = window.open(helpUri, WindowId, 'width=400,height=500,menubar=no,status=no,scrollbars=no,titlebar=no,toolbar=no,resizable=yes');
if (helpWindow) {
(helpWindow).focus();
}
}
</script>
</head>
<body>
<a id='PortOrderPageLearnMoreLink' href='javascript:' title='Learn more' onclick='activateHelpView("http://stackoverflow.com/")'>Learn more</a>
</body>
</html>
Use a real link, not the empty javascript: address. The onclick handler can prevent the link from doing anything "normal", but you'll have something for the right-click to work with.
target=_blank is a strong hint that you want the page opened in a new window, but whether that's honored at all -- and whether in a window or a tab -- is out of the page's control.
<script type="text/javascript">
function activateHelpView(helpUri) {
var WindowId = 'SomeWindowId';
var helpWindow = window.open(helpUri, WindowId, 'width=400,height=500,menubar=no,status=no,scrollbars=no,titlebar=no,toolbar=no,resizable=yes');
if (helpWindow) {
(helpWindow).focus();
}
}
</script>
<a id='PortOrderPageLearnMoreLink' href='http://stackoverflow.com/' title='Learn more' onclick='activateHelpView(this.href); return false;' target='_blank'>Learn more</a>
A more modern way of handling all of this -- particularly if there will be more than one help link -- is to add a class to all of them, and run some JavaScript to add the click handler to each in turn. The HTML stays clean (and with real links, still works if JavaScript is disabled or not loaded).
var helplinks = document.querySelectorAll('.helplink');
for (var i = 0; i < helplinks.length; ++i) {
helplinks[i].addEventListener('click', activateHelpView);
}
function activateHelpView(event) {
event.stopPropagation(); // don't let the click run its course
event.preventDefault();
var helpUri = this.href; // "this" will be the link that was clicked
var WindowId = 'SomeWindowId';
var helpWindow = window.open(helpUri, WindowId, 'width=400,height=500,menubar=no,status=no,scrollbars=no,titlebar=no,toolbar=no,resizable=yes');
if (helpWindow) {
helpWindow.focus();
}
}
<a id='PortOrderPageLearnMoreLink'
href='http://stackoverflow.com/' title='Learn more'
class='helplink' target='_blank'>Learn more</a>
StackOverflow snippets aren't allowed to use some of these functions. A working example can be found here.
Below is an example of what I would like but it has two flaws currently.
I believe that the order is incorrect because I cannot see any url sites beyond google.com. Something must be off in the location of certain items in the code. I have tried it without pop-up blockers and still cannot get the other windows to show.
I believe that this program is supposed to open in different windows/tabs. I would like mine to open the next url in the same window and tab and replace the original.
Google replaced by msn; msn replaced by yahoo
I am grateful for the help. Thank you everyone.
code:
<!DOCTYPE>
<html>
<body>
<script>
var urlList = ['http://www.google.com', 'http://www.msn.com', 'http://www.yahoo.com'];
var wnd;
var curIndex = 0; // a var to hold the current index of the current url
function openWindow(){
wnd = window.open(urlList[curIndex], '', '');
setTimeout(function () {
wnd.close(); //close current window
curIndex++; //increment the index
if(curIndex < urlList.length) openWindow(); //open the next window if the array isn't at the end
}, 2000);
}
openWindow();
</script>
</body>
</html>
You can just reuse your window instance:
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
var urlList = ['http://www.google.com', 'http://www.msn.com', 'http://www.yahoo.com'];
var wnd;
var curIndex = 0; // a var to hold the current index of the current url
function openWindow(){
wnd = wnd || window.open();
wnd.location.href = urlList[curIndex];
setTimeout(function () {
curIndex++; //increment the index
// If all urls have been showed, close our window instance
if(curIndex < urlList.length) openWindow(); else wnd.close();
}, 2000);
}
openWindow();
</script>
</html>
If you open in the same page your javascript will be gone. It won't work. As soon as google.com is opened that will be the end of your javascript. So you should open in either a new tab or consider using iframes.
See here for more info:
http://www.w3schools.com/tags/tag_iframe.asp
Hi I'm total beginner and this is my first question.
I recently setup a site and have some external links to it. All are set to open in same window by default, but wanted to give visitors choice to toggle external links to open in new window.
I found great script from: http://www.dynamicdrive.com/dynamicindex8/newwindow2.htm
edit
Here is the script from dynamicdrive:
//Open offsite links in new window script- http://www.dynamicdrive.com/
//Created: August 28th, 2007'
var ddwindowlinks={
//1)Enter domains to be EXCLUDED from opening in new window:
excludedomains: ["dynamicdrive.com", "google.com"],
//2) Target for links that should open in a new window (ie: "_blank", "secwin" etc):
linktarget: "_blank",
//3) Specify operating mode ("auto" or "manual"):
mode: "manual",
//4) If mode is "manual", customize checkbox HTML to show to users (Preserve id attribute):
toggleHTML: '<form><input type="checkbox" id="targetcheckbox" checked="checked" /><label for="targetcheckbox">Open off-site links in new window?</label></form>',
//5) If mode is "manual", enable user persistence so the state of the checkbox is remembered?
persist: true,
assigntarget:function(){
var rexcludedomains=new RegExp(this.excludedomains.join("|"), "i")
var all_links=document.getElementsByTagName("a")
if (this.mode=="auto" || (this.mode=="manual" && this.togglebox.checked)){
for (var i=0; i<=(all_links.length-1); i++){
if (all_links[i].hostname.search(rexcludedomains)==-1 && all_links[i].href.indexOf("http:")!=-1)
all_links[i].target=ddwindowlinks.linktarget
}
}
else{
for (var i=0; i<=(all_links.length-1); i++)
all_links[i].target=""
}
if (this.mode=="manual" && this.persist)
this.setCookie("dlinktarget", (this.togglebox.checked)? "yes" : "no", 30) //remember user setting for 30 days (set to -1 then reload page to erase cookie)
},
init:function(){
if (document.getElementById && this.mode=="manual"){
document.write(this.toggleHTML)
this.togglebox=document.getElementById("targetcheckbox")
this.togglebox.onclick=function(){ddwindowlinks.assigntarget()}
if (this.persist && this.getCookie("dlinktarget")!="")
this.togglebox.checked=(this.getCookie("dlinktarget")=="yes")? true : false
}
if (window.addEventListener)
window.addEventListener("load", function(){ddwindowlinks.assigntarget()}, false)
else if (window.attachEvent)
window.attachEvent("onload", function(){ddwindowlinks.assigntarget()})
},
getCookie:function(Name){
var re=new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair
if (document.cookie.match(re)) //if cookie found
return document.cookie.match(re)[0].split("=")[1] //return its value
return ""
},
setCookie:function(name, value, days){
var expireDate = new Date()
//set "expstring" to either an explicit date (past or future)
var expstring=expireDate.setDate(expireDate.getDate()+parseInt(days))
document.cookie = name+"="+value+"; expires="+expireDate.toGMTString()+"; path=/"
}
}
ddwindowlinks.init()
end edit
The script works excelent for links that are on text.
Example
<div class="Artistic-Body-P">
<span class="Artistic-Body-C">
test
</span>
</div>
but it's not working for links that are within div rollover.
example:
<div id="div_popup_roll_13" style="position:absolute;left:109px;top:259px;width:76px;height:76px;">
<a href="http://externallink.com" rev="image1.png~#~-14~#~-15~#~text~#~148~#~-119~#~#949393~#~Tahoma~#~30~#~0~#~1~#~transparent~#~165">
<img src="image2.png" border="0" width="76" height="76" id="popup_roll_13" alt="">
</a>
</div>
I have been busting my head for two days how to fix this, but guess that the fact that I'm beginner, doesn't help so I decided to post here.
thnx for help in advance
edit
here is the code from poproll:
(function($){jQuery.fn.poproll=function(settings){var m_bHovering=false;var m_nDivId=0;
var $m_ImageDiv=null;var $m_TextDiv=null;
var eOptions={Img:0,ImgPosX:1,ImgPosY:2,Txt:3,TxtPosX:4,TxtPosY:5,TxtCol:6,TxtFont:7,TxtSize:8,TxtItallic:9,TxtBold:10,TxtBkgrndCol:11,TxtWidth:12};
function ClosePopup(){if($m_ImageDiv!==null){$m_ImageDiv.remove();
$m_ImageDiv=null;if($m_TextDiv!==null){$m_TextDiv.remove();
$m_TextDiv=null}}}function HoverOver(div){m_bHovering=true;var nDivId=$(div).attr('id');
if(nDivId!==m_nDivId){m_nDivId=nDivId;ClosePopup()}if($m_ImageDiv===null){var anchor=$(div).find('a');
var optionArray=$(anchor).attr('rev').split('~#~');
var href=$(anchor).attr('href');
if(href===undefined){$(div).append('<div id="poproll_img" style="position:absolute; left:'+optionArray[eOptions.ImgPosX]+'px; top:'+optionArray[eOptions.ImgPosY]+'px; z-index:100;"><img src="'+optionArray[eOptions.Img]+'" name="popup_roll_2" alt="" style="position:absolute;left:0px;top:0px;"></div>')}else{$(div).append('<div id="poproll_img" style="position:absolute; left:'+optionArray[eOptions.ImgPosX]+'px; top:'+optionArray[eOptions.ImgPosY]+'px; z-index:100;"></div>')}$m_ImageDiv=$('#poproll_img');
if(optionArray[eOptions.Txt].length>0){var fontStyle=optionArray[eOptions.TxtItallic]>0?'italic':'normal';
var fontWeight=optionArray[eOptions.TxtBold]>0?'bold':'normal';$(div).append('<div id="poproll_txt" style="position:absolute; left:'+optionArray[eOptions.TxtPosX]+'px; top:'+optionArray[eOptions.TxtPosY]+'px; width:'+optionArray[eOptions.TxtWidth]+'px; color:'+optionArray[eOptions.TxtCol]+'; font-size:'+optionArray[eOptions.TxtSize]+'; font-family:'+optionArray[eOptions.TxtFont]+'; font-style: '+fontStyle+'; font-weight:'+fontWeight+'; background-color:'+optionArray[eOptions.TxtBkgrndCol]+'; z-index:100;">'+optionArray[eOptions.Txt]+'</div>');$m_TextDiv=$('#poproll_txt')}}}function HoverOut(){m_bHovering=false;window.setTimeout(function(){if(!m_bHovering){ClosePopup()}},100)}this.hover(function(){HoverOver(this)},function(){HoverOut()})}})(jQuery);
It might just be cleaner to write the code yourself. Try the following:
// Grab every <a> tag in the document.
var allTheTags = document.getElementsByTagName('a');
function parseTags(tags) {
var size = tags.length; // cache the size;
for (var i = 0; i < size; i++) {
var tag = tags[i];
var href = tag.getAttribute('href');
// Do we have a target attribute? (and, of course, an href attribute)
if (href && !tag.getAttribute('target')) {
var ourHostName = window.location.hostname;
href = href.split('://');
// Is there a protocol?
if (href.length > 1) {
href = href[1].split('/')[0]; // Get everything before the first /
if (href != window.location.hostname &&
href != 'www' + window.location.hostname) {
// Sometimes, hostname does not have www in it.
tag.setAttribute('target', '_blank');
}
}
}
}
};
// Call our function.
parseTags(allTheTags);
Our variable "allTheTags" is a Nodelist, which will update when the DOM updates, so we can always re-run our parseTags function passing in our allTheTags object each time. This way, we skip querying the DOM if there's an instance where a tags are added dynamically.
EDIT
In the case of accounting for poproll functionality, you'll have to listen for the same roll-over event you pass to your poproll function. So, right after you call poproll on the element you selected, listen for a hover on that same element.
$(someElementYouUseForPoproll).hover(function () {
parseTags(allTheTags);
}, function() { });
This way, after our markup has been injected, this hover event is next in-line to be executed and will now see the tag the poproll generated in the DOM.
I solved my problem, by editing the code for the poprol, changed the href to:
<a href="'+href+'" target="_blank">
I got an ifram that has many links in it and i am trying to copy those link correctly to my main page. My current code copy the links incorectly .For example if the
actual hyper link is like this in iframe:
5
after coping it in to main page the hyper links become like this :
http://ok.mysite24.com/spring/./ok/doit.php
so after clicking to those links from within my main page i go to dead links instead of actual links. is there away to fix this problem by copying iframe content correctly or should i modify my iframe content ?
<script type='text/javascript'>
function getFrameContents(){
var iFrame = document.getElementById('myframe');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
alert(iFrameBody.innerHTML);
document.getElementById('response').innerHTML = iFrameBody.innerHTML
}
</script>
<iframe id ='myframe' src='http://www.mysite.com/ok.php'></iframe>
<div id="response">
<p>getFrameContents! </p>
Before retrieving the innerHTML loop over all links and replace their DOM-href-attribute with their JS-href-property. This will turn the href-attributes into absolute URIs.
//clone the body to keep the original untouched
iFrameBody = iFrameBody.cloneNode(true);
var links = iFrameBody.getElementsByTagName('a');
for (var i = 0; i < iFrameBody.getElementsByTagName('a').length; ++i) {
if (links[i].hasAttribute('href')) {
links[i].setAttribute('href', links[i].href);
}
}
It looks like you want to resolve one relative address to the iframe's source address, which may also be relative. Psuedo code (ish):k
function resolveAddress(source, link) {
if(link.indexOf("../") == 0) {
index--; // go up one directory .//
return resolveAddress(source.substr(0,source.lastIndexOf("/")-1),
link.substr(1, link.length-1));
}
else if(link.indexOf("./") == 0) {
// reduce to current directory ./
return resolveAddress(source.substr(0,source.lastIndexOf("/"),
link.substr(2, link.length-1));
}
return source + link;
}
frame_src = "http://www.mysite.com/ok.php"
link = "./ok/doit.php";
resolveAddress(frame_src, link);
//=> "http://www.mysite.com/ok/doit.php"