Force link to open in same window/tab - javascript

I am using google chrome with this extension - Open Link in Same Tab.
It's very simple and basically does what it says, forces all links to open in the same window/tab. I require this functionality for touch screen kiosk left/right swipe navigation.
The plugin works very well when it comes to links. However it doesn't work when a search is performed in a 'submit' web search form. Presumably because the extension is forcing anything with _blank to open in _top, but it's ignoring forms.
How can I modify the extension in such a way that it also takes into consideration forms, and forces these to also open in the same tab?
I have downloaded the extension and viewed the code, the main js seems to be in the sametab.js file. I have included this below, I'm sure I can modify it somehow to fit my needs.
Any help is appreciated.
"use strict";
// "_blank|_self|_parent|_top|framename"; "framename" should not start with "_"
// - list of iframe names only contains the names of iframes and not the names
// of windows in other tabs that could be targets
// - list of iframe names is not updated if an iframe's name changes
(function() {
var sameTab = {
converted: false,
observer: null,
iframeNameList: [],
index: -1,
mutationObserverFunction: function(mutations, observer) {
sameTab.observer.disconnect();
mutations.forEach(function(mutation) {
var i, node, target;
target = mutation.target;
if (!document.contains(target)) return;
switch (mutation.type) {
case "attributes":
if (mutation.attributeName !== "target" ||
target.tagName !== "A") return;
target.onclick = (target.target === "" ||
target.target[0] === '_') ? "" : sameTab.doNamedTarget;
if (target.target.toLowerCase() !== "_blank" ||
mutation.oldValue === "_top") return;
target.target = "_top";
break;
case "childList":
for (i = 0; i < mutation.addedNodes.length; i++) {
node = mutation.addedNodes[i];
if (node.parentNode !== target || node.nodeType !=
document.ELEMENT_NODE) continue;
sameTab.convertLinks(node);
}
break;
}
});
sameTab.observeDocument();
},
observeDocument: function() {
sameTab.observer.observe(document, {
childList: true,
subtree: true,
characterData: false,
attributes: true,
attributeOldValue: true,
attributeFilter: ["target"]
});
},
convertDocument: function(eventObject) {
sameTab.convertLinks(document);
sameTab.observer = new MutationObserver(sameTab.mutationObserverFunction);
sameTab.observeDocument();
sameTab.converted = true;
},
// When a link with a named target is clicked, change the target to "_top"
// unless the name is in the list of iframe names.
doNamedTarget: function(eventObject) {
// First make sure the iframe's own name is correct.
if (sameTab.index !== -1) {
sameTab.iframeNameList[sameTab.index] === window.name;
}
// Do nothing if the target name is in the list of window names.
if (sameTab.iframeNameList.indexOf(eventObject.target.target) !== -1) return;
eventObject.target.target = "_top";
},
// If the link target is "_blank" change it to "_top". If it is a name
// which does not begin with "_" set the link's click event handler so
// the list of iframe names can be checked for the target when the link is
// clicked.
convertLinks: function(node) {
var i, linkElements;
linkElements = node.querySelectorAll("a[target]");
for (i = 0; i < linkElements.length; i++) {
if (linkElements[i].target === "") continue;
if (linkElements[i].target[0] !== "_") {
linkElements[i].onclick = sameTab.doNamedTarget;
} else if (linkElements[i].target.toLowerCase() === "_blank") {
linkElements[i].target = "_top";
}
}
if (node.tagName !== "A" || node.target === "") return;
if (node.target[0] !== "_") {
node.onclick = sameTab.doNamedTarget;
} else if (node.target.toLowerCase() === "_blank") {
node.target = "_top";
}
}
};
var frame = null;
if (window === top) {
// Top frame
frame = {
iframeList: [],
convertAllLinks: false,
hostname: null,
// Delete an item from the list of iframes.
removeDeletedIframes: function(source) {
var i;
for (i = frame.iframeList.length - 1; i >= 0; i--) {
if (frame.iframeList[i].source && (!source ||
frame.iframeList[i].source !== source)) continue;
frame.iframeList.splice(i, 1);
sameTab.iframeNameList.splice(i, 1);
}
},
sendIframeList: function(source) {
var i, len, origin;
// First remove any deleted iframes from the lists.
frame.removeDeletedIframes(source);
len = frame.iframeList.length;
for (i = 0; i < len; i++) {
origin = (frame.iframeList[i].origin === "null") ?
"*" : frame.iframeList[i].origin;
frame.iframeList[i].source.postMessage({
senderId: "sameTabExtensionTop",
message: "nameList",
iframeNameList: sameTab.iframeNameList,
index: i,
}, origin);
}
},
checkLists: function(items) {
var i;
if (!items.settingsInitialized) {
console.warn("Stored data missing.");
window.removeEventListener("message", frame.windowMessages, false);
frame.iframeList.length = 0;
sameTab.iframeNameList.length = 0;
} else if (!items.convertLinks ||
(items.useWhitelist &&
items.whitelist.indexOf(frame.hostname) == -1) ||
items.blacklist.indexOf(frame.hostname) != -1) {
window.removeEventListener("message", frame.windowMessages, false);
frame.iframeList.length = 0;
sameTab.iframeNameList.length = 0;
} else {
frame.convertAllLinks = true;
frame.sendIframeList();
if (document.readyState === "interactive" ||
document.readyState === "complete") {
sameTab.convertDocument(null);
} else {
document.addEventListener("DOMContentLoaded",
sameTab.convertDocument, false);
}
}
},
getHostname: function() {
switch (location.protocol) {
case "file:":
return "file://" + location.hostname + location.pathname;
break;
case "http:":
case "https:":
return location.hostname;
break;
default:
return null;
break;
}
},
windowMessages: function(eventObject) {
var i, len;
if (!eventObject.data ||
eventObject.data.senderId !== "sameTabExtensionIframe") return;
switch (eventObject.data.message) {
case "windowUnloaded":
frame.sendIframeList(eventObject.source);
break;
case "contentLoaded":
if (!eventObject.source ||
eventObject.source.top !== window) return;
len = frame.iframeList.length;
for (i = 0; i < len; i++) {
if (frame.iframeList[i].source === eventObject.source) break;
}
frame.iframeList[i] = eventObject;
sameTab.iframeNameList[i] = eventObject.data.frameName;
if (!frame.convertAllLinks) return;
frame.sendIframeList(null);
break;
}
}
};
frame.hostname = frame.getHostname();
if (frame.hostname) {
window.addEventListener("message", frame.windowMessages, false);
chrome.storage.local.get(null, frame.checkLists);
}
} else {
// Iframes
frame = {
// Accept messages from the top window only.
windowMessages: function(eventObject) {
if (eventObject.source !== top) return;
if (!eventObject.data ||
eventObject.data.senderId !== "sameTabExtensionTop" ||
eventObject.data.message !== "nameList" ||
!eventObject.data.iframeNameList) return;
sameTab.iframeNameList = eventObject.data.iframeNameList;
sameTab.index = eventObject.data.index;
if (sameTab.converted) return;
sameTab.convertDocument(null);
},
// Tell top window that the window has unloaded
windowUnload: function(eventObject) {
var origin;
try {
origin = top.location.origin;
} catch(err) {
origin = "*";
}
top.postMessage({
senderId: "sameTabExtensionIframe",
message: "windowUnloaded",
}, origin);
},
// Post the window's name to the top window.
contentLoaded: function(eventObject) {
var origin;
try {
origin = top.location.origin;
} catch(err) {
origin = "*";
}
top.postMessage({
senderId: "sameTabExtensionIframe",
message: "contentLoaded",
frameName: window.name
}, origin);
}
};
window.onunload = frame.windowUnload;
window.addEventListener("message", frame.windowMessages, false);
document.addEventListener("DOMContentLoaded", frame.contentLoaded, false);
}
}());

Simply add the _top attribute on all forms below (function() {
var submitButtons = document.getElementsByTagName("button");
for (var i = 0; i < submitButtons .length; i++) {
submitButtons[i].setAttribute("target", "_top");
}

You can try setting the querySelectorAll to look for forms as well. I'm pretty sure that forms also support target.

Related

Avoid DevTools menu

I have a code to avoid users opening devtools menu, the code works perfectly for me! But sometimes, when you watch a simple video at my website and put it on fullscreen, the script below returns false positive.
// chrome
var element = new Image;
var devtoolsOpen = false;
element.__defineGetter__("id", function() {
devtoolsOpen = true; // This only executes when devtools is open.
});
setInterval(function() {
devtoolsOpen = false;
//console.log(element);
if (devtoolsOpen && devtoolsOpen == true) {
window.location = "https://mywebsite.com/denied/";
}
}, 1000);
// all
var _interval = 200;
(function() {
'use strict';
var devtools = {
open: false,
orientation: null
};
var threshold = 160;
var emitEvent = function(state, orientation) {
window.dispatchEvent(new CustomEvent('devtoolschange', {
detail: {
open: state,
orientation: orientation
}
}));
};
setInterval(function() {
var widthThreshold = window.outerWidth - window.innerWidth > threshold;
var heightThreshold = window.outerHeight - window.innerHeight > threshold;
var orientation = widthThreshold ? 'vertical' : 'horizontal';
if (!(heightThreshold && widthThreshold) &&
((window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized) || widthThreshold || heightThreshold)) {
if (!devtools.open || devtools.orientation !== orientation) {
emitEvent(true, orientation);
}
devtools.open = true;
devtools.orientation = orientation;
} else {
if (devtools.open) {
emitEvent(false, null);
}
devtools.open = false;
devtools.orientation = null;
}
}, _interval);
if (typeof module !== 'undefined' && module.exports) {
module.exports = devtools;
} else {
window.devtools = devtools;
}
setTimeout(function() {
_interval = 500;
}, 1000);
})();
// check if it's open
//console.log('is DevTools open?', window.devtools.open);
if (window.devtools.open && window.devtools.open == true) {
window.location = "https://mywebsite.com/denied/";
}
// get notified when it's opened/closed or orientation changes
window.addEventListener('devtoolschange', function(e) {
//console.log('is DevTools open?', e.detail.open);
if (e.detail.open && e.detail.open == true) {
window.location = "https://mywebsite.com/denied/";
}
});
// clear
console.API;
if (typeof console._commandLineAPI !== 'undefined') {
console.API = console._commandLineAPI; //chrome
} else if (typeof console._inspectorCommandLineAPI !== 'undefined') {
console.API = console._inspectorCommandLineAPI; //Safari
} else if (typeof console.clear !== 'undefined') {
console.API = console;
}
console.API.clear();
I reviewed the code many times and I wasn't able to find why this is happening. Do you have any idea about how can I solve it?
Thank you.

Paste image from clipboard to html page

I'm learning angular and I'm trying to use copy image from clipboard and paste it in html web page.
I found a solution in Javascript that i want to convert to typeScript. But it doesn't work when I test it. It works fine on jsfiddle : http://jsfiddle.net/KJW4E/1739/
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>
var CLIPBOARD = new CLIPBOARD_CLASS("my_canvas", true);
/**
* image pasting into canvas
*
* #param {string} canvas_id - canvas id
* #param {boolean} autoresize - if canvas will be resized
*/
function CLIPBOARD_CLASS(canvas_id, autoresize) {
var _self = this;
var canvas = document.getElementById(canvas_id);
var ctx = document.getElementById(canvas_id).getContext("2d");
var ctrl_pressed = false;
var command_pressed = false;
var paste_event_support;
var pasteCatcher;
//handlers
document.addEventListener('keydown', function (e) {
_self.on_keyboard_action(e);
}, false); //firefox fix
document.addEventListener('keyup', function (e) {
_self.on_keyboardup_action(e);
}, false); //firefox fix
document.addEventListener('paste', function (e) {
_self.paste_auto(e);
}, false); //official paste handler
//constructor - we ignore security checks here
this.init = function () {
pasteCatcher = document.createElement("div");
pasteCatcher.setAttribute("id", "paste_ff");
pasteCatcher.setAttribute("contenteditable", "");
pasteCatcher.style.cssText = 'opacity:0;position:fixed;top:0px;left:0px;width:10px;margin-left:-20px;';
document.body.appendChild(pasteCatcher);
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (paste_event_support === true || ctrl_pressed == false || mutation.type != 'childList'){
//we already got data in paste_auto()
return true;
}
//if paste handle failed - capture pasted object manually
if(mutation.addedNodes.length == 1) {
if (mutation.addedNodes[0].src != undefined) {
//image
_self.paste_createImage(mutation.addedNodes[0].src);
}
//register cleanup after some time.
setTimeout(function () {
pasteCatcher.innerHTML = '';
}, 20);
}
});
});
var target = document.getElementById('paste_ff');
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
}();
//default paste action
this.paste_auto = function (e) {
paste_event_support = false;
if(pasteCatcher != undefined){
pasteCatcher.innerHTML = '';
}
if (e.clipboardData) {
var items = e.clipboardData.items;
if (items) {
paste_event_support = true;
//access data directly
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
//image
var blob = items[i].getAsFile();
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
this.paste_createImage(source);
}
}
e.preventDefault();
}
else {
//wait for DOMSubtreeModified event
//https://bugzilla.mozilla.org/show_bug.cgi?id=891247
}
}
};
//on keyboard press
this.on_keyboard_action = function (event) {
k = event.keyCode;
//ctrl
if (k == 17 || event.metaKey || event.ctrlKey) {
if (ctrl_pressed == false)
ctrl_pressed = true;
}
//v
if (k == 86) {
if (document.activeElement != undefined && document.activeElement.type == 'text') {
//let user paste into some input
return false;
}
if (ctrl_pressed == true && pasteCatcher != undefined){
pasteCatcher.focus();
}
}
};
//on kaybord release
this.on_keyboardup_action = function (event) {
//ctrl
if (event.ctrlKey == false && ctrl_pressed == true) {
ctrl_pressed = false;
}
//command
else if(event.metaKey == false && command_pressed == true){
command_pressed = false;
ctrl_pressed = false;
}
};
//draw pasted image to canvas
this.paste_createImage = function (source) {
var pastedImage = new Image();
pastedImage.onload = function () {
if(autoresize == true){
//resize
canvas.width = pastedImage.width;
canvas.height = pastedImage.height;
}
else{
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(pastedImage, 0, 0);
};
pastedImage.src = source;
};
}
</script>
</head>
<body>
1. Copy image data into clipboard or press Print Screen <br>
2. Press Ctrl+V (page/iframe must be focused):
<br /><br />
<button onclick="alert('Hello! I am an alert box!!');"></button>
<canvas style="border:1px solid grey;" id="my_canvas" width="300" height="300"></canvas>
</body>
</html>
I am using google chrome Version 70.0.3538.77
Thanks in advance
From the comments above, it sounds like you were trying to execute your bindings in the constructor of your component instead of within ngOnInit. This is a classic gotcha as the constructor spins up well before (in most cases) before the content on screen is finished rendering. ngOnInit is called as the component finalises its instantiation process.
https://angular-6ckpxd.stackblitz.io
The errors you receive are because typescript is strongly typed where javascript is not. You are pasting javascript code in (which is fine in most cases) but will need some casting to any if you want to eradicate most of them.

Anyone know what happened to the AutoFormat feature in CodeMirror?

Trying to auto format some HTML in CodeMirror V4. Found the docs on how to do it but it looks like the call editor.autoFormatRange(range.from, range.to) was removed in V3...
Code for V2 is below.
Anyone know how to do it with V4 today?
From: http://codemirror.net/2/demo/formatting.html
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "htmlmixed"
});
CodeMirror.commands["selectAll"](editor);
function getSelectedRange() {
return { from: editor.getCursor(true), to: editor.getCursor(false) };
}
function autoFormatSelection() {
var range = getSelectedRange();
editor.autoFormatRange(range.from, range.to);
}
function commentSelection(isComment) {
var range = getSelectedRange();
editor.commentRange(isComment, range.from, range.to);
}
</script>
If you put the formatting.js file in the addons folder of codemirror 4 and reference it, the functions will work.
Location: addon/format/formatting.js
include the script file in your html
Call the formatting code (example at http://codemirror.net/2/demo/formatting.html)
formatting.js
(function() {
CodeMirror.extendMode("css", {
commentStart: "/*",
commentEnd: "*/",
newlineAfterToken: function(_type, content) {
return /^[;{}]$/.test(content);
}
});
CodeMirror.extendMode("javascript", {
commentStart: "/*",
commentEnd: "*/",
// FIXME semicolons inside of for
newlineAfterToken: function(_type, content, textAfter, state) {
if (this.jsonMode) {
return /^[\[,{]$/.test(content) || /^}/.test(textAfter);
} else {
if (content == ";" && state.lexical && state.lexical.type == ")") return false;
return /^[;{}]$/.test(content) && !/^;/.test(textAfter);
}
}
});
var inlineElements = /^(a|abbr|acronym|area|base|bdo|big|br|button|caption|cite|code|col|colgroup|dd|del|dfn|em|frame|hr|iframe|img|input|ins|kbd|label|legend|link|map|object|optgroup|option|param|q|samp|script|select|small|span|strong|sub|sup|textarea|tt|var)$/;
CodeMirror.extendMode("xml", {
commentStart: "<!--",
commentEnd: "-->",
newlineAfterToken: function(type, content, textAfter, state) {
var inline = false;
if (this.configuration == "html")
inline = state.context ? inlineElements.test(state.context.tagName) : false;
return !inline && ((type == "tag" && />$/.test(content) && state.context) ||
/^</.test(textAfter));
}
});
// Comment/uncomment the specified range
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode;
cm.operation(function() {
if (isComment) { // Comment range
cm.replaceRange(curMode.commentEnd, to);
cm.replaceRange(curMode.commentStart, from);
if (from.line == to.line && from.ch == to.ch) // An empty comment inserted - put cursor inside
cm.setCursor(from.line, from.ch + curMode.commentStart.length);
} else { // Uncomment range
var selText = cm.getRange(from, to);
var startIndex = selText.indexOf(curMode.commentStart);
var endIndex = selText.lastIndexOf(curMode.commentEnd);
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
// Take string till comment start
selText = selText.substr(0, startIndex)
// From comment start till comment end
+ selText.substring(startIndex + curMode.commentStart.length, endIndex)
// From comment end till string end
+ selText.substr(endIndex + curMode.commentEnd.length);
}
cm.replaceRange(selText, from, to);
}
});
});
// Applies automatic mode-aware indentation to the specified range
CodeMirror.defineExtension("autoIndentRange", function (from, to) {
var cmInstance = this;
this.operation(function () {
for (var i = from.line; i <= to.line; i++) {
cmInstance.indentLine(i, "smart");
}
});
});
// Applies automatic formatting to the specified range
CodeMirror.defineExtension("autoFormatRange", function (from, to) {
var cm = this;
var outer = cm.getMode(), text = cm.getRange(from, to).split("\n");
var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state);
var tabSize = cm.getOption("tabSize");
var out = "", lines = 0, atSol = from.ch == 0;
function newline() {
out += "\n";
atSol = true;
++lines;
}
for (var i = 0; i < text.length; ++i) {
var stream = new CodeMirror.StringStream(text[i], tabSize);
while (!stream.eol()) {
var inner = CodeMirror.innerMode(outer, state);
var style = outer.token(stream, state), cur = stream.current();
stream.start = stream.pos;
if (!atSol || /\S/.test(cur)) {
out += cur;
atSol = false;
}
if (!atSol && inner.mode.newlineAfterToken &&
inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i+1] || "", inner.state))
newline();
}
if (!stream.pos && outer.blankLine) outer.blankLine(state);
if (!atSol && i < text.length - 1) newline();
}
cm.operation(function () {
cm.replaceRange(out, from, to);
for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur)
cm.indentLine(cur, "smart");
cm.setSelection(from, cm.getCursor(false));
});
});
})();
You can use any 3rd party formatting tools, like JS Beautifier (it supports CSS, HTML and JS)
Add custom button
Add onclick handler for it
Use editor.getValue() and editor.setValue(string) from API
jQuery(function($) {
var editor = CodeMirror.fromTextArea($('#code')[0], {
lineNumbers: true,
mode: 'text/javascript',
theme: 'oceanic-next'
});
$('#format').on('click', function() {
editorContent = editor.getValue();
editorContent = js_beautify(editorContent, {indent_with_tabs: true});
editor.setValue(editorContent);
editor.refresh();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.60.0/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.60.0/mode/javascript/javascript.min.js" rel="stylesheet"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.5/beautify.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.60.0/codemirror.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.60.0/theme/oceanic-next.min.css" rel="stylesheet"/>
<button id="format">Format</button>
<textarea id="code">var APP_ID = "APP_ID";
(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',w.intercomSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Intercom=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/' + APP_ID;var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s, x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
</textarea>

Javascript Events using HTML Class Targets - 1 Me - 0

I am trying to create collapsible DIVs that react to links being clicked. I found how to do this using "next" but I wanted to put the links in a separate area. I came up with this which works...
JSFiddle - Works
function navLink(classs) {
this.classs = classs;
}
var homeLink = new navLink(".content-home");
var aboutLink = new navLink(".content-about");
var contactLink = new navLink(".content-contact");
var lastOpen = null;
$('.home').click(function() {
if(lastOpen !== null) {
if(lastOpen === homeLink) {
return; } else {
$(lastOpen.classs).slideToggle('fast');
}
}
$('.content-home').slideToggle('slow');
lastOpen = homeLink;
}
);
$('.about').click(function() {
if(lastOpen !== null) {
if(lastOpen === aboutLink) {
return; } else {
$(lastOpen.classs).slideToggle('fast');
}
}
$('.content-about').slideToggle('slow');
lastOpen = aboutLink;
}
);
$('.contact').click(function() {
if(lastOpen !== null) {
if(lastOpen === contactLink) {
return; } else {
$(lastOpen.classs).slideToggle('fast');
}
}
$('.content-contact').slideToggle('slow');
lastOpen = contactLink;
}
);​
I am now trying to create the same result but with a single function instead of one for each link. This is what I came up with....
function navLink(contentClass, linkClass, linkId) {
this.contentClass = contentClass;
this.linkClass = linkClass;
this.linkId = linkId;
}
var navs = [];
navs[0] = new navLink(".content-home", "nav", "home");
navs[1] = new navLink(".content-about", "nav", "about");
navs[2] = new navLink(".content-contact", "nav", "contact");
var lastOpen = null;
$('.nav').click(function(event) {
//loop through link objects
var i;
for (i = 0; i < (navsLength + 1); i++) {
//find link object that matches link clicked
if (event.target.id === navs[i].linkId) {
//if there is a window opened, close it
if (lastOpen !== null) {
//unless it is the link that was clicked
if (lastOpen === navs[i]) {
return;
} else {
//close it
$(lastOpen.contentClass).slideToggle('fast');
}
}
//open the content that correlates to the link clicked
$(navs[i].contentClass).slideToggle('slow');
navs[i] = lastOpen;
}
}
});​
JSFiddle - Doesn't Work
No errors so I assume that I am just doing this completely wrong. I've been working with Javascript for only about a week now. I've taken what I've learned about arrays and JQuery events and tried to apply them here. I assume I'm way off. Thoughts? Thanks
You just forgot to define navsLength:
var navsLength=navs.length;
Of course you could also replace it with a $().each loop as you're using jQuery.
[Update] Two other errors I corrected:
lastOpen=navs[i];
for(i=0; i < navsLength ; i++)
Demo: http://jsfiddle.net/jMzPJ/4/
Try:
var current, show = function(){
var id = this.id,
doShow = function() {
current = id;
$(".content-" + id).slideToggle('slow');
},
toHide = current && ".content-" + current;
if(current === id){ //Same link.
return;
}
toHide ? $(toHide).slideToggle('fast', doShow): doShow();;
};
$("#nav").on("click", ".nav", show);
http://jsfiddle.net/tarabyte/jMzPJ/5/

Requirejs, Backbonejs browser support function

I need to check whether the browser is supported by my application and I do this the following way:
main.js (main require.js module)
define(['underscore', 'backbone', 'views/mainView', 'views/oldBrowser', 'ui', function(_, Backbone, mainView, oldBrowser){
var _browserHandshaking = function(){
var browserSupportedCookie = $.cookie('browserSupported');
var browserNameCookie = $.cookie('browserName');
var browserVersionCookie = $.cookie('browserVersion');
if(browserSupportedCookie === null){
if(/Chrome[\/\s](\d+\.\d+)/.test(navigator.userAgent)){
$.ui.browserName = 'chrome';
} else if(/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)){
$.ui.browserName = 'opera';
/Version[\/\s](\d+\.\d+)/.test(navigator.userAgent);
} else if(/MSIE (\d+\.\d+);/.test(navigator.userAgent)){
$.ui.browserName = 'ie';
} else if(/Safari[\/\s](\d+\.\d+)/.test(navigator.userAgent)){
$.ui.browserName = 'safari';
/Version[\/\s](\d+\.\d+)/.test(navigator.userAgent);
} else if(/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){
$.ui.browserName = 'firefox';
} else if(/webOS/i.test(navigator.userAgent)){
$.ui.browserName = 'webos';
} else if(/Android/i.test(navigator.userAgent)){
$.ui.browserName = 'android'
} else if(/iPhone/i.test(navigator.userAgent)){
$.ui.browserName = 'iphone';
} else if(/iPod/i.test(navigator.userAgent)){
$.ui.browserName = 'ipod';
} else if(/BlackBerry/i.test(navigator.userAgent)){
$.ui.browserName = 'blackberry';
}
if($.ui.browserName !== false){
// Set browser version.
if(!$.ui.browserVersion){
$.ui.browserVersion = parseFloat(new Number(RegExp.$1));
}
for(var browserName in $.ui.supportedBrowsers){
if($.ui.browserName === browserName){
if($.ui.browserVersion >= $.ui.supportedBrowsers[browserName]){
$.ui.browserSupported = true;
break;
}
}
}
$.cookie('browserVersion', $.ui.browserVersion, { expires: 7 });
$.cookie('browserName', $.ui.browserName, { expires: 7 });
$.cookie('browserSupported', $.ui.browserSupported, { expires: 7 });
}
} else {
$.ui.browserSupported = browserSupportedCookie;
$.ui.browserName = browserNameCookie;
$.ui.browserVersion = browserVersionCookie;
}
};
_browserHandshaking.call(this);
var Router = Backbone.Router.extend({
routes: {
"old-browser": "oldBrowser",
"*actions": "main",
},
oldBrowser: function(){
oldBrowser.render();
},
main: function(){
mainView.render();
}
});
$.ui.router = new Router();
// Start routing.
Backbone.history.start({
pushState: true,
root: $.ui.rootDir
});
});
Is there a function in Backbone.js that triggers at every action, there I could easily implement this:
preRouting: function(){
if(!$.ui.browserSupported){
return false;
}
return true;
}
I just need to check, if the browser is supported, and if it is supported it can call the mainView, else the oldBrowser view should be triggered, I just don't want to do this at each route function call.
Someone has a better solution for this? And does someone know if it is possible to create a check that is basically a prelimiter for a route function call.
Thanks for help :)
Based on comments, you can check for push state with: (from Can use pushState )
var hasPushstate = !!(window.history && history.pushState);
css3 animations with: ( from Detect css transitions using javascript (and without modernizr)? )
function supportsTransitions() {
var b = document.body || document.documentElement;
var s = b.style;
var p = 'transition';
if(typeof s[p] == 'string') {return true; }
// Tests for vendor specific prop
v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms'],
p = p.charAt(0).toUpperCase() + p.substr(1);
for(var i=0; i<v.length; i++) {
if(typeof s[v[i] + p] == 'string') { return true; }
}
return false;
}
var hasCSS3Transitions = supportsTransitions();
There's no need to check the browser name/version if you can simply check to see if the browser has the functionality your application needs.

Categories