I used jQuery Address several times to support the back button in small asynchronous applications.
When all the AJAX requests do the same thing (that is, requesting a page asynchronously and replace an HTML element with the request) the implementation can be easy.
When the AJAX requests might do different things, let's say open an overlay in one case and change the content of the page entire page in another case, things become messy.
I ended up with some really crappy code for the fact that I had to go through a lot of if statements to analyze the hash value (#/somepage/someotherpage).
I always repeated to myself: there has to be a better way to do this.
Has anybody went through the same problem and can suggest a solution?
If not, check out my idea and tell me what you think.
My idea is to create an object which emulates the window.history object, but only for AJAX history, let's call it "ajaxhistory".
Each time a page is requested asynchronously something like this happens:
ajaxhistory[i] = {
url: 'here the url',
type: 'overlay'
otherusefulinfo: 'whatever'
}
i++
So, for example:
if(moving back or forward){
if(currenturl == ajaxhistory[i-1].url){
// i'm going back
// i'm able to know what type of action i should take thanks to
// ajaxhistory[i-1].type and ajaxhistory[i-1].otherusefulinfo
}
}
I like this idea because it would make my code much easier to read, mantain and change.
Suppose then I want to add new functionality... I can add a new type and I work with that, while normally I should edit a lot of crappy if statements.
What do you think? Would there be problems from a performance point of view?
Check out this work by Ben Alman
http://benalman.com/projects/jquery-bbq-plugin/
He has a plugin to help support back button.
Hope this is useful.
Bob
You can use html5 feature:
window.history.pushState({type: 'overlay'}, title, url), where first param is JS object.
You can access this object like that:
window.onpopstate = function(event) {
alert( event.state.overlay);
}
For more information, check https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
Related
I want to create a variable on my GTM to store a DOM element. I've tried a custom javascript, for example:
function(){
return document.querySelector('.room__price-value').innerText;
}
But nothing, on GTM preview I see always NULL. I think the issue was the single page app.
And I can't involve the programmers.
Any suggestions?
Thanks
Make sure that when in preview, you check the value of your variable on every event on the left.
Make sure when you execute document.querySelector('.room__price-value').innerText; in your console, you actually get the result you're expecting.
Change the code until you get the result in the local console.
Make sure your timing is good, as Eike mentioned in the comment.
What you're doing there seems right. That's pretty much how you do DOM scrape in GTM when front-end devs aren't available. If the suggestions still don't work for you, give us more info on what you're doing, on how your DOM looks like, what your debugging showed and such. As much potentially useful context as you can.
OK this is an odd error, as it's the first ajax page without any complete reloads I'm creating it's an error I never had to face before... and even the Internet doesn't help me - as it doesn't seem to be an usual problem.
Let's get to the Problem step by step:
I have a page where the Ajax request is triggered by a function which simplified looks like this:
$("a[rel='tab']").live('click',function(e) {
pageurl = $(this).attr('href');
$.ajax({url:pageurl+'?rel=tab',success: function(data){
$('#content').html(data);
}});
if(pageurl!=window.location){
window.history.pushState({path:pageurl},'',pageurl);
}
e.preventDefault();
return false;
});
This is parsed by the PHP File and if the property is set the design won't be loaded but instead just the file itself gets loaded - easy hu?
OK, now the problem itself - it was obvious that the page became slower with the time but I didn't really bother at first as I thought it was some mistake in the designs javascripts - but it wasn't.
So I took a look at the firebug and what I've seen explained a lot -> The Requests stack up with every new page! Of course that would lead into an overkill... Well at first I thought it were just the "setInterval"'s and got a workaround running which resets them on each reload.
But that wasn't the only case they also seem to stack up in "scripts" as I don't think that's a plain history as just the reloaded scripts show up more than once!
Any hints in the right would be really helpfull as I am pretty much stuck here!
OK as it seems the issue is just related to the setInterval after all - After trying around for a while I came to the conclusion that this was the main problem, and it was just some kind of a loop in firebug itself.
However maybe someone gets stuck on the same issue so the solution is pretty much this way:
You have to:
1. Create an array where to store your Intervals
2. call your setIntervals this way
3. Reset them on each "new window"
var intervalArr = new Array();
function killIntervals(){
while(intervalArr.length > 0)
clearInterval(intervalArr.pop());
};
These are the array and the function
So these should be added in your AJAX Request function:
killIntervals();
intervalArr.push(setInterval (yourintervalfunction, 5000));
I hope this will come in handy for someone.
I need to build a web application that allow user to input javascript code and the code is then dynamically executed and somehow show the result at the same page. The flow would be something like this:
In the webpage, there area a series of textarea, and under each of these textareas, there is a result div element (or whatever element span, p, doesn't matter). User will input javascript code inside the textareas. He should be able to enter whatever javascript code he want, but at the end he will call a custom function like
my_application_output(some_variables_computed_from_previous_code_execution)
and then something will be displayed on the result div. A simple example will be:
if he input the following text in the textarea:
var a = 0;
a++;
my_application_output(a);
and then execute the code, the result div element below the textarea will have a inner html content of "1"
I don't have much idea how to get started, like what technologies or system architecture should I go for. so would like to ask for some pointers here. I have thought about two options (not sure whether they are good enough)
Use JavaScript eval() function. so I just execute the code from the textarea directly on the client side.
Implement a backend service using an engine like V8. So I do a ajax call to backend with the code content, and then the codes are executed from backend, and result is returned. I then put the result in the result div accordingly.
Personally, I'd like to go for 1) because eval() seems to be a easier solution. However, I'm not sure whether there is any limitation about this function or whether it can achieve what I want to do. Otherwise, if I have to go for the second option. Anyone can propose an architecture for that?
Not only is option 1 easier, it is also the safer choice.
Why? Everyone who has Firebug installed in Firefox (or just has the Chrome Dev tools open) already has what you're asking for, though perhaps in not as noob-friendly a fashion. The code they write is sandboxed to the browser they're using and nothing more.
With option 2, you're going to execute arbitrary untrusted code on the server. Suppose they realize that you're using Node.js (the most likely choice here) and then run a fork-bomb on your server:
require('child_process').exec(':(){:|:&};:', function() { console.log('This will never run') });
Let alone something more nefarious.
Remember that REPL stands for Read-Eval-Print-Loop, and is what dynamic languages since Lisp have used to help programmers understand their languages. Eval is perfectly fine if the only person a newbie can hurt is themselves.
I am using a JavaScript to track the activities of users on my page upon unloading that very page. Consider the following simplified dummie-script to simulate what I am doing on unload:
$(window).unload(function() {
$.get("http://www.google.de/images/srpr/logo3w.png");
});
The image URL in that case serves as a holder for tracking data.
The image is requested in some browsers (e.g. Firefox 3) and isn't loaded in others (e.g. Firefox 6) when closing the browser window.
Probably isn't the way it should be done; anyhow I would like to hold on to it as long as I could make a statement on how reliable the unload-event is.
Any experiences on this?
I have some experience with that and I would recommend a slightly different approach like this:
$(window).unload(function() {
new Image().src = "http://www.google.de/images/srpr/logo3w.png?timestamp="
+ new Date().getTime();
});
The challenge is that if you are making an AJAX-call at unload, you should use synchronous mode. With normal async-mode, it may not succeed at all (for instance in Chrome).
But in this case, a trick using image is just as reliable because the communication is one way only. That works for GET but if you need to POST something then sync-mode is the only option.
I was working with a online game website. There are some event which call a javascript function and the function have some action with callback.
something like this,
<input type="button" onclick="changeSomething"/>
function changeSomething() {
/// some call back, which changes something
}
now anybody who knows this can call this changeSomething from the address bar of the browser, which I do not want.
Very unlikely that somebody will do it, but I want to allow it.
Is there anyway to prevent situation like this ?
Thanks.
P.S. I tried, but still not sure whether I explained it well enought. Please let me know if you are not getting something.
You will never be able to get 100% protected from any technique you try. It's a losing game.
Having said that one way to get closer to your goal is to remove the onclick attribute altogether, and bind your click handler (ie "changeSomething") via javascript:
html:
<input id="foo" type="button" />
js:
addEvent(document.getElementById("foo"), 'click', function() {
/// some call back, which changes something
})
The callback becomes anonymous then (eg there is no "changeSomething" function anymore). These evil users can't call it directly if they don't know its name!
There are still ways around this technique too, but we won't mention those lest we give the evil doers ideas :)
(BTW addEvent is just a sample library function for adding event handlers. I'm sure you have access to one. If not here you go.)
I dont think that there is anything you can do about this. The client can run whatever they want within their own browser. The only thing to do is validate everything on the server side. This is an important concept in all web programming. Client side code can be freely modified and should be treated as an additional check to speed things up rather than a security method.
You have to handle this on whatever back-end you've got accepting the request. Assuming you only give the user the option to doSomething() upon certain conditions, you probably have this information in the database (or whatever).
Don't worry about the JavaScript being called (no way around it), and do the same check you did on the front-end on the back-end. This way you can simply forget about securing your front-end, since you can't anyway... yet you still prevent malicious users from doSomethinging when they aren't supposed to.
Let me know if you need further clarification of what I mean, but I'll need more details about what your app architecture is like.
Any "solution" will be as efficient as disabling right-click in Web page... For the latter problem, I found at least a dozen of workarounds, including viewing the page in Opera!
If you disable this, one will workaround with Firebug, Greasemonkey, or even some proxy modifying HTML on the fly, not to mention using a local copy of the page, etc.
You can check the source of the click by passing an ID:
<input id="good' type="button" onclick="changeSomething(this.id)"/>
function changeSomething(myId) {
if(myId!='good') {
return;
}
//......code
}
Revised to:
<input id="good' type="button" onclick="changeSomething(this)"/>
function changeSomething(myId) {
if(myId.id!='good') {
return;
}
//......code
}