React - check when tab or browser is closed, but not on refresh - javascript

I want to disconnect all my users when the tab is closing or the browser is getting closed, so far so good. But when I refresh the page, all my users get disconnected too, this should not happen on refresh. Is it possible to avoid to execute this event on refresh? I saw some users doing with localStorage, but I still didn't get the point.
componentDidMount() {
this.beforeUnloadListener();
}
beforeUnloadListener = () => {
window.addEventListener("beforeunload", (ev) => {
ev.preventDefault();
// code to logout user
});
};

The way beforeunload works, you can not differentiate weather it's a page refresh or a browser close. beforeunload it is a quite confusing event avoid using this.
Hence for cases where you are dealing with the session you should use session storage. The sessionStorage object stores data for only one session (the data is deleted when the browser tab is closed).

Have done this on react application and its work for me on index.html file write this in script tag.
<script type="text/javascript">
window.addEventListener("beforeunload", (event) => {
window.localStorage.isMySessionActive = "true";
});
window.onunload = function (e) {
const newTabCount = localStorage.getItem("tabsOpen");
if (newTabCount !== null) {
localStorage.setItem("tabsOpen", newTabCount - 1);
}
};
</script>
Then go on main file and write this code.
useEffect(() => {
// define increment counter part
const tabsOpen = localStorage.getItem("tabsOpen");
if (tabsOpen == null) {
localStorage.setItem("tabsOpen", 1);
} else {
localStorage.setItem("tabsOpen", parseInt(tabsOpen) + parseInt(1));
}
// define decrement counter part
window.onunload = function (e) {
const newTabCount = localStorage.getItem("tabsOpen");
if (newTabCount !== null) {
localStorage.setItem("tabsOpen", newTabCount - 1);
}
};
if (performance.navigation.type == performance.navigation.TYPE_RELOAD) {
window.localStorage.isMySessionActive = "false";
} else {
const newTabCount2 = localStorage.getItem("tabsOpen");
let value = localStorage.getItem("isMySessionActive");
if (value == "true") {
if (newTabCount2 - 1 == 0) {
localStorage.clear();
window.localStorage.isMySessionActive = "false";
} else {
window.localStorage.isMySessionActive = "false";
}
}
}
}, []);

Related

How can I limit the user to a single session tab? [duplicate]

I'm just thinking about the whole site registration process.
A user goes to your site, signs up, and then you tell him you've sent him an email and he needs to verify his email address. So he hits Ctrl+T, pops open a new tab, hits his Gmail fav button, doesn't read a word of your lengthy welcome email, but clicks the first link he sees. Gmail opens your site in yet another tab...
He doesn't need nor want two tabs for your site open, he just wants to view that darn page you've disallowed him access to until he registers.
So what do we do? I saw one site (but I forget what it was) that did a really good job, and it actually refreshed the first tab I had open without me having to press anything.
I'm thinking, it might be nice if we can detect if the user already has a tab to your site open, we could either close the new verification-tab automatically, or tell him he can close it can go back to his other tab (which we've now refreshed and logged him in).
Or, maybe when he got your annoying "please check your email" message, he went directly to his email, replacing your site with his email knowing full well that the email will link him back to the site again. In that case, we don't want to close the tab, but maybe could have saved his location from before, and redirect him there again?
Anyway, that's just the use case... the question still stands. Can we detect if a user already has a tab to your site open?
This question is not about how to detect when a user has completed the sign-up process. Ajax polling or comet can solve that issue. I specifically want to know if the user already has a tab open to your site or not.
I'm fairly late to the party here (over a year), but I couldn't help but notice that you'd missed an incredibly easy and elegant solution (and probably what that website you saw used).
Using JavaScript you can change the name of the window you currently have open through:
window.name = "myWindow";
Then when you send out your confirmation email simply do (assuming you're sending a HTML email):
Verify
Which should result in the verificationLink opening up inside the window your website was already loaded into, if it's already been closed it'll open up a new tab with the window name specified.
You can stop the page functionality when user opened another tab or another window or even another browser
$(window).blur(function(){
// code to stop functioning or close the page
});
You can send an AJAX request every X seconds from the original tab that asks the server if it received a request from the email.
You cannot close the second tab automatically, but you could have it ask the server after 3X seconds whether it heard from the first tab.
What I have here is a little bit different use case to you but it detects if the site is being accessed in another tab. In this case I wanted to limit people using some call center pages to only one tab. It works well and is purely client-side.
// helper function to set cookies
function setCookie(cname, cvalue, seconds) {
var d = new Date();
d.setTime(d.getTime() + (seconds * 1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
// helper function to get a cookie
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
// Do not allow multiple call center tabs
if (~window.location.hash.indexOf('#admin/callcenter')) {
$(window).on('beforeunload onbeforeunload', function(){
document.cookie = 'ic_window_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
});
function validateCallCenterTab() {
var win_id_cookie_duration = 10; // in seconds
if (!window.name) {
window.name = Math.random().toString();
}
if (!getCookie('ic_window_id') || window.name === getCookie('ic_window_id')) {
// This means they are using just one tab. Set/clobber the cookie to prolong the tab's validity.
setCookie('ic_window_id', window.name, win_id_cookie_duration);
} else if (getCookie('ic_window_id') !== window.name) {
// this means another browser tab is open, alert them to close the tabs until there is only one remaining
var message = 'You cannot have this website open in multiple tabs. ' +
'Please close them until there is only one remaining. Thanks!';
$('html').html(message);
clearInterval(callCenterInterval);
throw 'Multiple call center tabs error. Program terminating.';
}
}
callCenterInterval = setInterval(validateCallCenterTab, 3000);
}
To flesh out John's answer, here is a working solution that uses plain JS and localStorage and updates the DOM with the count of the currently open tabs. Note that this solution detects the number of open tabs/windows for a given domain within one browser, but does not maintain the count across different browsers.
It uses the storage event to keep the count synchronized across all open tabs/windows without any need for refreshing the page.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
(function() {
var stor = window.localStorage;
window.addEventListener("load", function(e) {
var openTabs = stor.getItem("openTabs");
if (openTabs) {
openTabs++;
stor.setItem("openTabs", openTabs)
} else {
stor.setItem("openTabs", 1)
}
render();
})
window.addEventListener("unload", function(e) {
e.preventDefault();
var openTabs = stor.getItem("openTabs");
if (openTabs) {
openTabs--;
stor.setItem("openTabs", openTabs)
}
e.returnValue = '';
});
window.addEventListener('storage', function(e) {
render();
})
function render() {
var openTabs = stor.getItem("openTabs");
var tabnum = document.getElementById("tabnum");
var dname = document.getElementById("dname");
tabnum.textContent = openTabs;
dname.textContent = window.location.host
}
}());
</script>
</head>
<body>
<div style="width:100%;height:100%;text-align:center;">
<h1 >You Have<h1>
<h1 id="tabnum">0</h1>
<h1>Tab(s) of <span id="dname"></span> Open</h1>
</div>
</body>
</html>
To add to other answers:
You can also use localStorage. Have an entry like 'openedTabs'. When your page is opened, increase this number. When user leaves the page, decrease it.
The user will still have a session at the server. Why not store the user's location prior to registration, and when they confirm their registration, read the location back out of the session and redirect back to that page. No tab magic required. It's certainly not what I'd expect from a signup process.
It is possible to track number of tabs of your site opened by saving data in localstorage of each tab and counting the same, I created a github repository which can track number of tabs of your website a user has opened.
To use it Include tab-counter.js in your page and it will start tracking number of opened tabs.
console.log(tabCount.tabsCount());
Here's a system that uses broadcast channels for cross tab comms. It also assigns a unique ID per tab and manages the discovery of already opened tabs, for new tabs. Finally, using the ID as a stable index, it allows the user to rename their tabs. Tab closing events are handled via polling as well (unload events are unreliable).
This plugs into redux via the callbacks in the constructor. These are onNewTab, onDestroyTab, onRenameTab in this example.
import { setTabs } from './redux/commonSlice';
import { store } from './redux/store';
const promiseTimeout = (ms, promise) => {
let id;
let timeout = new Promise((resolve, reject) => {
id = setTimeout(() => {
reject('Timed out in ' + ms + 'ms.');
}, ms)
})
return Promise.race([
promise,
timeout
]).then((result) => {
clearTimeout(id);
return result;
})
};
// Promise that can be resolved/rejected outside of its constructor. Like a signal an async event has occured.
class DeferredPromise {
constructor() {
this._promise = new Promise((resolve, reject) => {
// assign the resolve and reject functions to `this`
// making them usable on the class instance
this.resolve = resolve;
this.reject = reject;
});
// bind `then` and `catch` to implement the same interface as Promise
this.then = this._promise.then.bind(this._promise);
this.catch = this._promise.catch.bind(this._promise);
this.finally = this._promise.finally.bind(this._promise);
this[Symbol.toStringTag] = 'Promise';
}
}
class TabManager {
tabCreateCallback = undefined;
tabDestroyCallback = undefined;
tabRenameCallback = undefined;
constructor(onNewTab, onDestroyTab, onRenameTab) {
this.tabCreateCallback = onNewTab.bind(this);
this.tabDestroyCallback = onDestroyTab.bind(this);
this.tabRenameCallback = onRenameTab.bind(this);
// creation time gives us a total ordering of open tabs, also acts as a tab ID
this.creationEpoch = Date.now();
this.channel = new BroadcastChannel("TabManager");
this.channel.onmessage = this.onMessage.bind(this);
// our current tab (self) counts too
this.tabs = [];
this.tabNames = {};
// start heartbeats. We check liveness like this as there is _no_ stable browser API for tab close.
// onbeforeunload is not reliable in all situations.
this.heartbeatPromises = {};
this.heartbeatIntervalMs = 1000;
setTimeout(this.doHeartbeat.bind(this), this.heartbeatIntervalMs);
}
doComputeNames() {
for (let i = 0; i < this.tabs.length; i++) {
const tab = this.tabs[i];
const name = this.tabNames[tab];
const defaultName = `Tab ${i + 1}`;
if (!name) {
this.tabNames[tab] = defaultName;
if (this.tabRenameCallback) {
this.tabRenameCallback(tab, name);
}
// if it's a default pattern but wrong inde value, rename it
} else if (name && this.isDefaultName(name) && name !== defaultName) {
this.tabNames[tab] = defaultName;
if (this.tabRenameCallback) {
this.tabRenameCallback(tab, name);
}
}
}
}
doHeartbeat() {
for (let tab of this.tabs) {
if (tab === this.creationEpoch) {
continue;
}
this.channel.postMessage({ type: "heartbeat_request", value: tab });
const heartbeatReply = new DeferredPromise();
heartbeatReply.catch(e => { });
// use only a fraction of poll interval to ensure timeouts occur before poll. Prevents spiral of death.
let heartbeatReplyWithTimeout = promiseTimeout(this.heartbeatIntervalMs / 3, heartbeatReply);
// destroy tab if heartbeat times out
heartbeatReplyWithTimeout.then(success => {
delete this.heartbeatPromises[tab];
}).catch(error => {
delete this.heartbeatPromises[tab];
this.tabs = this.tabs.filter(id => id !== tab);
this.tabs.sort();
this.doComputeNames();
if (this.tabDestroyCallback) {
this.tabDestroyCallback(tab);
}
});
this.heartbeatPromises[tab] = heartbeatReply;
}
// re-schedule to loop again
setTimeout(this.doHeartbeat.bind(this), this.heartbeatIntervalMs);
}
doInitialize() {
this.tabs = [this.creationEpoch];
this.doComputeNames();
if (this.tabCreateCallback) {
this.tabCreateCallback(this.creationEpoch);
}
this.channel.postMessage({ type: "creation", value: this.creationEpoch });
}
onMessage(event) {
if (event.data.type == "creation") {
const newTabId = event.data.value;
// add the new tab
if (!this.tabs.includes(newTabId)) {
this.tabs.push(newTabId);
this.tabs.sort();
this.doComputeNames();
if (this.tabCreateCallback) {
this.tabCreateCallback(newTabId);
}
}
// send all of the tabs we know about to it
this.channel.postMessage({ type: "syncnew", value: this.tabs });
// those tabs we just sent might already have custom names, lets send the older rename requests
// which would have had to have occured. I.E. lets replay forward time and sync the states of ours to theirs.
for (let tab of this.tabs) {
const name = this.tabNames[tab];
if (name && !this.isDefaultName(name)) {
this.notifyTabRename(tab, name);
}
}
} else if (event.data.type == "syncnew") {
let newTabs = [];
// just got a list of new tabs add them if we down't know about them
for (let id of event.data.value) {
if (!this.tabs.includes(id)) {
newTabs.push(id);
}
}
// merge the lists and notify of only newly discovered
if (newTabs.length) {
this.tabs = this.tabs.concat(newTabs);
this.tabs.sort();
this.doComputeNames();
for (let id of newTabs) {
if (this.tabCreateCallback) {
this.tabCreateCallback(id);
}
}
}
} else if (event.data.type == "heartbeat_request") {
// it's for us, say hi back
if (event.data.value === this.creationEpoch) {
this.channel.postMessage({ type: "heartbeat_reply", value: this.creationEpoch });
}
} else if (event.data.type == "heartbeat_reply") {
// got a reply, cool resolve the heartbeat
if (this.heartbeatPromises[event.data.value]) {
// try catch since this is racy, entry may have timed out after this check passed
try {
this.heartbeatPromises[event.data.value].resolve();
} catch {
}
}
} else if (event.data.type == "rename") {
// someone renamed themselves, lets update our record
const { id, name } = event.data.value;
if (this.tabs.includes(id)) {
this.tabNames[id] = name;
// first original (potentially illegal) rename callback first
if (this.tabRenameCallback) {
this.tabRenameCallback(id, name);
}
// force tab numbers back to consistent
this.doComputeNames();
}
}
}
setTabName(id, name) {
if (this.tabs.includes(id)) {
this.tabNames[id] = name;
this.notifyTabRename(id, name);
if (this.tabRenameCallback) {
this.tabRenameCallback(id, name);
}
// force tab numbers back to consistent
this.doComputeNames();
}
}
notifyTabRename(id, name) {
this.channel.postMessage({ type: "rename", value: { id, name } });
}
isDefaultName(name) {
return name.match(/Tab [0-9]+/)
}
getMyTabId() {
return this.creationEpoch;
}
getMyTabIndex() {
return this.tabs.findIndex(tab => tab === this.creationEpoch);
}
isMyTab(id) {
return id === this.creationEpoch;
}
getAllTabs() {
return this.tabs.map((tab, idx) => {
return { id: tab, index: idx, name: this.tabNames[tab] ?? "" };
}, this);
}
}
function onDestroyTab(id) {
store.dispatch(setTabs(this.getAllTabs()));
console.log(`Tab ${id} destroyed`);
}
function onNewTab(id) {
store.dispatch(setTabs(this.getAllTabs()));
console.log(`Tab ${id} created`);
}
function onRenameTab(id, name) {
store.dispatch(setTabs(this.getAllTabs()));
console.log(`Tab ${id} renamed to ${name}`);
}
const TabManager = new TabManager(onNewTab, onDestroyTab, onRenameTab);
export default TabManager;
Initialize it on page load
window.addEventListener("DOMContentLoaded", function (event) {
TabManager.doInitialize();
});
Access any of the methods on the static object at any time. Note that you can get rename events out of order from create / destroy. This could be resolved, but it wasn't important for me.

Selenium Get Element After Following Link

all!
I've followed as many tips and tutorials as I can, but I can't figure out how to obtain an element in Node JS Selenium after moving from the starting page.
In my use case, I go to a login screen, enter the pertinent information, and then run a click() on the login button. I am taken to the home screen.
After this, I cannot select any elements! I just keep getting 'not found' warnings.
I'm sleeping for 6000ms, and I have set the implicit timeouts to 30s.
What am I missing here?
My problematic part would be in the function GoToSettings, which is called after the Login button is clicked.
Thanks
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
const TIMEOUT = 30
var driver = new webdriver.Builder().forBrowser('chrome').build();
const capabilities = driver.getCapabilities().then(()=>{
capabilities['map_'].set('timeouts', { implicit: TIMEOUT, pageLoad: TIMEOUT, script: TIMEOUT });
});
var info = require('./info.json')
driver.get('http://www.okcupid.com/settings?')
driver.sleep(2000);
//We may already be logged in at this point
driver.getTitle().then((title) => {
driver.getCurrentUrl().then((url) => {
LoginOrHome(title, url);
});
});
function LoginOrHome(title, url){
if(title == "Free Online Dating | OkCupid" || url == "https://www.okcupid.com/login?p=/settings") {
//needslogin.exe
console.log("Logging in!");
login();
} else if (title == "Welcome! | OkCupid" || url == "https://www.okcupid.com/settings?") {
//We are already logged in
console.log("Already logged in. Changing location.");
goToSettings();
} else {
console.log(title);
console.log(url);
}
}
function goToSettings() {
driver.sleep(6000);
driver.switchTo().window(driver.getWindowHandle()).then( () => {
driver.getCurrentUrl().then((title) => {
//This prints the URL of the previous page
console.log(title);
});
})
}
function login(){
driver.findElement(By.name("username")).sendKeys(info.email).then(() => {
driver.findElement(By.name("password")).sendKeys(info.password).then(() => {
driver.findElement(By.css("div > input[type=submit]")).click().then(()=> { goToSettings() });
});
});
}

JS: Erroneous popstate event when trying to navigate back past the initial page load

I'm trying to implement JS history using pushState/popState. Navigating back and forward works just fine, but I have trouble navigating before the initial page load using the browser's back button. It needs 1 extra hit on the browser's back button to leave the page. Why is that?
function action(text) {
history.pushState({"text":text}, text);
doAction(text);
}
function doAction(text) {
$('span').text(text);
}
var $button = $('button');
var $p = $('p');
$p.hide();
action("foo");
$button.on('click', function(){
action("bar");
$button.hide();
$p.show();
})
window.addEventListener("popstate", function(e) {
if (e.state !== null) {
$button.show();
$p.text("Next back should navigate away from this page");
} else {
$p.text("Still here? Why is that? Next back will really navigate away");
}
});
https://jsfiddle.net/lilalinux/p8ewyjr9/20/
Edit: Tested with Chrome OS/X
The initial page load shouldn't use history.pushState because it would add another history entry. There is alredy an implicit first history item with state null.
Using history.replaceState for the initial page load, sets a state for that item but doesn't add another one.
var initialPageLoad = true;
function action(text) {
if (initialPageLoad) {
// replace the state of the first (implicit) item
history.replaceState({"text":text}, text);
} else {
// add new history item
history.pushState({"text":text}, text);
}
initialPageLoad = false;
doAction(text);
}
function doAction(text) {
$('span').text(text);
}
var $button = $('button');
var $p = $('p');
$p.hide();
action("foo");
$button.on('click', function(){
action("bar");
$button.hide();
$p.show();
})
window.addEventListener("popstate", function(e) {
if (e.state !== null) {
$button.show();
$p.text("Next back should navigate away from this page");
// } else {
// won't happen anymore, as the first item has state now
// $p.text("Still here? Why is that? Next back will really navigate away");
}
});

Service Worker onClick event - How to open url in window withing sw scope?

I have service worker which handles push notification click event:
self.addEventListener('notificationclick', function (e) {
e.notification.close();
e.waitUntil(
clients.openWindow(e.notification.data.url)
);
});
When notification comes it takes url from data and displays it in new window.
The code works, however, I want different behavior. When User clicks on the link, then it should check if there is any opened window within service worker scope. If yes, then it should focus on the window and navigate to the given url.
I have checked this answer but it is not exactly what I want.
Any idea how it can be done?
P.S. I wrote this code but it still doesn't work. The first two messages are however shown in the log.
self.addEventListener('notificationclick', function (e) {
e.notification.close();
var redirectUrl = e.notification.data.redirect_url.toString();
var scopeUrl = e.notification.data.scope_url.toString();
console.log(redirectUrl);
console.log(scopeUrl);
e.waitUntil(
clients.matchAll({type: 'window'}).then(function(clients) {
for (i = 0; i < clients.length; i++) {
console.log(clients[i].url);
if (clients[i].url.toString().indexOf(scopeUrl) !== -1) {
// Scope url is the part of main url
clients[i].navigate(givenUrl);
clients[i].focus();
break;
}
}
})
);
});
Ok, here is the piece of code which works as expected. Notice that I am passing scope_url together with redirect_url into the web notification. After that I am checking if scope_url is part of sw location. Only after that I navigate to redirect_url.
self.addEventListener('notificationclick', function (e) {
e.notification.close();
var redirectUrl = e.notification.data.redirect_url;
var scopeUrl = e.notification.data.scope_url;
e.waitUntil(
clients.matchAll({includeUncontrolled: true, type: 'window'}).then(function(clients) {
for (i = 0; i < clients.length; i++) {
if (clients[i].url.indexOf(scopeUrl) !== -1) {
// Scope url is the part of main url
clients[i].navigate(redirectUrl);
clients[i].focus();
break;
}
}
})
);
});
If I understand you correctly, most of the code you linked to works here.
First retrieve all the clients
If there are more than one, choose one of them
Navigate that to somewhere and focus
Else open a new window
Right?
event.waitUntil(
clients.matchAll({type: 'window'})
.then(clients => {
// clients is an array with all the clients
if (clients.length > 0) {
// if you have multiple clients, decide
// choose one of the clients here
const someClient = clients[..someindex..]
return someClient.navigate(navigationUrl)
.then(client => client.focus());
} else {
// if you don't have any clients
return clients.openWindow(navigationUrl);
}
})
);

javascript html5 history, variable initialization and popState

main question
Is there a javascript way to identify if we are accessing a page for the first time or it is a cause of a back?
My problem
I'm implementing html5 navigation in my ajax driven webpage.
On the main script, I initialize a variable with some values.
<script>
var awnsers=[];
process(awnsers);
<script>
Process(awnsers) will update the view according to the given awnsers, using ajax.
In the funciton that calls ajax, and replaces the view, I store the history
history.pushState(state, "", "");
I defined the popstate also, where I restore the view according to the back. Moreover, I modify the global variable awnsers for the old value.
function popState(event) {
if (event.state) {
state = event.state;
awnsers=state.awnsers;
updateView(state.view);
}
}
Navigation (back and forth) goes corectly except when I go to an external page, and press back (arrving to my page again).
As we are accessing the page, first, the main script is called,the valiable awnsers is updated, and the ajax starts. Meanwile, the pop state event is called, and updates the view. After that the main ajax ends, and updates the view according to empty values.
So I need the code:
<script>
var awnsers=[];
process(awnsers);
<script>
only be called when the user enters the page but NOT when it is a back. Any way to do this?
THanks!
Possible solution
After the first awnser I have thought of a possible solution. Tested and works, whoever, I don't know if there is any cleaner solution. I add the changes that I've done.
First I add:
$(function() {
justLoaded=true;
});
then I modify the popState function, so that is in charge to initialize the variables
function popState(event) {
if (event.state) {
state = event.state;
awnsers=state.awnsers;
updateView(state.view);
} else if(justLoaded){
awnsers=[];
process(awnsers);
}
justLoaded=false;
}
Thats all.
what about using a global variable?
var hasLoaded = false;
// this function can be called by dom ready or window load
function onPageLoad() {
hasLoaded = true;
}
// this function is called when you user presses browser back button and they are still on your page
function onBack() {
if (hasLoaded) {
// came by back button and page was loaded
}
else {
// page wasn't loaded. this is first visit of the page
}
}
Use cookie to store the current state.
yeah! This is what I have:
var popped = (($.browser.msie && parseInt($.browser.version, 10) < 9) ? 'state' in window.history : window.history.hasOwnProperty('state')), initialURL = location.href;
$(window).on('popstate', function (event) {
var initialPop = !popped && location.href === initialURL, state;
popped = true;
if (initialPop) { return; }
state = event.originalEvent.state;
if (state && state.reset) {
if (history.state === state) {
$.ajax({url: state.loc,
success: function (response) {
$(".fragment").fadeOut(100, function () {
$(".fragment").html($(".fragment", response).html()).fadeIn(100);
);
document.title = response.match(/<title>(.*)<\/title>/)[1];
}
});
} else { history.go(0); }
else {window.location = window.location.href; }
});
And:
$.ajax({url:link,
success: function (response) {
var replace = args.replace.split(",");
$.each(replace, function (i) {
replace[i] += ($(replace[i]).find("#video-content").length > 0) ? " #video-content" : "";
var selector = ".fragment "+replace[i];
$(selector).fadeOut(100, function () {
$(selector).html($(selector,response).html()).fadeIn(100, function () {
if (base.children("span[data-video]")[0]) {
if ($.browser.msie && parseInt($.browser.version, 10) === 7) {
$("#theVideo").html("");
_.videoPlayer();
} else {
_.player.cueVideoById(base.children("span[data-video]").attr("data-video"));
}
}
});
});
});
document.title = response.match(/<title>(.*)<\/title>/)[1];
window.history.ready = true;
if (history && history.pushState) { history.pushState({reset:true, loc:link}, null, link); }
}
});

Categories

Resources