I have been mulling about SEO, ajax and links. I get confused when looking at code from different web-pages and how they seem to handle this issue.
I have always made sure that a static context exists for the function that makes the ajax-call. I have not been placing javascript inline of my markup but I have rather been using ids to invoke the functions with external js-files. A typical example of my own is the following:
Link
And then hookup the id with a click function.
But what I see on some major pages is that they use things like:
Link
Link
Is there some benefits of using javascript inline like above? I don't get it, major sites seems to be using it?
the second way is bad because a crawler that does not use javascript would not be able to use the second method.
the first method would still work if it didn't use javascript.
As long as your links are properly named and contextually appropriate, AND behave correctly without javascript enabled, you should be 100% fine.
Not that some crawlers do use javascript though, so even though the second variation is a poor one, it might still work sometimes.
tl;dr: If it works without javascript you're good.
On HTML part write this way:
Link
On JavaScript part, write this way:
function ajaxCall() {
// AJAX functionalities will go here
return false;
}
Search engines will index the url, as JavaScript code will not be executed during crawlers fetch the page. But when an user browses this page using browsers, the JavaScript code will be executed (assuming the user did not disable JavaScript), and the ajaxCall function will be called.
Note: As the function returns false, user will not navigate to the URL defined in href section. But if it returns true or void, then user will be navigated to the defined location.
Related
I have a small application with two pages: the login page and the main page. My problem is that when I use just one main JavaScript file for both pages (like it's recommanded) I get a lot of ReferenceError because some variables on a page are not defined on the other one...
e.g:
Line of code for the login page
copyrightYear.textContent = new Date().getFullYear();
Main page complains
Uncaught TypeError: Cannot set property 'textContent' of null
How can I fix that? Don't tell me I have to say if(copyrightYear) { do stuff } everytime, it's just a nightmare if I have to do that for every variable
Two answers for you:
The recommendation isn't a dictate
My problem is that when I use just one main JavaScript file for both pages (like it's recommanded)
That's a very general recommendation. It doesn't apply to every situation. There's no point in loading code in a page that won't use that code.
If you have code that you use in both pages, and also page-specific code, it's absolutely fine to have a file that both pages share and also page-specific files:
<script src="main.js"></script>
<script src="page1.js"></script>
If you're really worried about the extra HTTP request (much less of an issue these days than it used to be), use modules and a bundler like Webpack or Rollup that will create a bundle combining the main module with page 1's module for page 1 and another bundle combining the main module with page 2's module for page 2.
But even then, the extra HTTP request may be better for your users, if you expect them to go from page1 to page2 in a reasonable timeframe. The reason is that if you have main.js and page1.js/page2.js and you allow caching of them, when the user goes to page1 they get main.js and page1.js, and then when they go to page2 main.js comes out of their local cache and they only have to load page2.js. In contrast, if you had a single bundle file for each page, they'd have to re-download all of that common code when going from page1 to page2 (or vice versa). But if you expect a visitor to visit either page1 or page2 but not the other one, you save the HTTP request by using page-specific bundles.
There's really no one-size-fits-all solution. :-) There are all sorts of considerations.
Note that HTTP/1.1 made additional HTTP requests more efficient and is nearly universally supported, and HTTP/2 makes them a lot more efficient, effectively eliminating the case for reducing the number of HTTP requests as part of the page startup. All major modern browsers support HTTP/2 as do up-to-date web servers.
Put the code for each page in a function
If you really want to keep a single page, put the code that's specific to each page in functions for those pages, and then have code in the main part of the file call the appropriate function based on location.pathname.
You figured it out, you have to check this for every variable. But generally it's much more convenient to use functions and only call these functions when you need them.
So for example, say you want to set some copyrightYear (even tough this shouldn't be set via JS, you should generate this on Backend side to have it in the source code)
You have something like this:
function updateYear() {
// here you do your magic of selecting the element, setting the year, whatever.
}
// another function, totally unrealted to updateYear()
function toggleMenu() {
// some function where you toggle the menu if you click somewhere
// like: button.addEventListener('click', () => {} );
}
And in your JS file you have one block where you call all these functions:
if (document.querySelectorAll('.elementForYear') {
updateYear(); // here we call it because we are sure this element exists... so everything inside function must work
}
if (document.querySelector('.myMenu') {
toggleMenu(); // if the element myMenu exists, we know we can add these toggle Functionality.
}
You can also add these if inside the function and call the function regardless of if it's needed or not, that's up to you and up to coding guidelines.
Generally I find it makes sense to have one function only rely on one (or max two to three elements if it's some toggling of other elements) ... And then you just check for one element. And if this one element exists you can go ahead and call the function.
We have an IE extension implemented as a Browser Helper Object (BHO). We have a utility function written in C++ that we add to the window object of the page so that other scripts in the page can use it to load local script files dynamically. In order to resolve relative paths to these local script files, however, we need to determine the path of the JavaScript file that calls our function:
myfunc() written in C++ and exposed to the page's JavaScript
file:///path/to/some/javascript.js
(additional stack frames)
From the top frame I want to get the information that the script calling myfunc() is located in file:///path/to/some/javascript.js.
I first expected that we could simply use the IActiveScriptDebug interface to get a stacktrace from our utility function. However, it appears to be impossible to get the IActiveScript interface from an IWebBrowser2 interface or associated document (see Full callstack for multiple frames JS on IE8).
The only thing I can think of is to register our own script debugger implementation and have myfunc() break into the debugger. However, I'm skeptical that this will work without prompting the user about whether they want to break into the debugger.
Before doing more thorough tests of this approach, I wanted to check whether anyone has definitive information about whether this is likely to work and/or can suggest an alternative approach that will enable a function written in C++ to get a stack trace from the scripting engine that invoked it.
Each script you load may have an id and each method of the script calling myfunc() may pass this id to myfunc(). This means that first you have to modify myfunct() and finally alter your scripts and calls.
This answer describes how I solved the actual issue I described in the original question. The question description isn't great since I was making assumptions about how to solve the problem that actually turned out to be unfounded. What I was really trying to do is determine the path of the currently running script. I've changed the title of the question to more accurately reflect this.
This is actually fairly easy to achieve since scripts are executed in an HTML document as they are loaded. So if I am currently executing some JavaScript that is loaded by a script tag, that script tag will always be the last script tag in the document (since the rest of the document hasn't loaded yet). To solve this problem, it is therefore enough just to get the URL of the src attribute of the last script tag and resolve any relative paths based on that.
Of course this doesn't work for script embedded directly in the HTML page, but that is bad practice anyway (IMO) so this doesn't seem like a very important limitation.
So, I'm running these Selenium IDE tests against a site I'm working on. Everything about the tests themselves is running fine, except I would like to do a bit of clean-up once I'm done. In my MVC3 Razor based site, I have a JavaScript file with a function that gets a JsonResult from a Controller of mine. That Controller handles the database clean-up that Selenium IDE otherwise couldn't handle.
However, I'm having a hard time finding any sort of documentation on how to do this. I know I can do JavaScript{ myJavascriptGoesHere } as one of the Values for a line in the test, but I can't seem to find a way to tell it to go find my clean-up function.
Is it even possible for Selenium IDE to do this sort of thing?
If it comes down to it, I can just make a separate View to handle the clean-up, but I'd really like to avoid that if possible.
Thanks!
If you want to execute your own JavaScript function that exists in your test page from Selenium IDE, you need to make sure you access it via the window object. If you look at the reference for storeEval for instance, it says:
Note that, by default, the snippet will run in the context of the
"selenium" object itself, so this will refer to the Selenium object.
Use window to refer to the window of your application, e.g.
window.document.getElementById('foo')
So if you have your own function e.g. myFunc(). You need to refer to it as window.myFunc().
This can be very handy for exercising client-side validation without actually submitting the form, e.g. if you want to test a variety of invalid and valid form field values.
If you use runScript, that should already run in the window's context.
This works for me.
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string title = (string)js.ExecuteScript("myJavascriptGoesHere");
Make sure your javascript works first before using it here!
Actually to access your page javascript space, you need to get the real window of your page : this.browserbot.getUserWindow()
See this statement to get the jQuery entry point in your page (if it has jQuery of course ^^ )
https://stackoverflow.com/a/54887281/2143734
I am developing a site using Asp.net MVC 3 with Razor.
In the _Layout.cshtml (the master page) I want to put a logic based on whether or not the browser enables javascript.
What is the simplest way to make this logic?
For the sake of simplicity, let the master page just output as follows:
#if(....)//need to modify
{ <p>javascript enabled...</p>}
else {<p>javascript disabled...</p>}
If you want to block the access of your application you can use something like this
<noscript>
<meta http-equiv="refresh" content="0;url=../Controller/Error" />
</noscript>
There's no way to find this out on the server, therefore there's no way to find out before the first page is loaded. The best you can do is to put a bit of Javascript into the page that sets a cookie or posts an AJAX response to the server telling it that Javascript is active, so you can do something about it on subsequent page requests. Even apart from the obvious problem of the first page load, it's a bad strategy since the user may switch off Javascript in the meantime while your server still thinks it's active.
Graceful degradation/progressive enhancement are the keywords here. Make your page assume by default that no Javascript is active and act accordingly, i.e. serve plain HTML in either case. Include Javascript that will "upgrade" the site's functionality if Javascript is active. Let the client figure out if Javascript is working or not and give it the means to work in either case.
I'm afraid there's no good solution. Almost all of the solutions out there somehow involve running a script to do the check and it doesn't feel right (at least to me). The best solution I can suggest is use the <noscript /> tag and redirect to a different page that does not depend on javascript.
Here is one trick...
Assume the user has JavaScript blocked (off). We put this code into the index.aspx:
<script>
document.location.href = "index.aspx?js=1";
</script>
If you get the js=1, you know that user has JS enabled.
So you can generate the code in according the user has / hasn't JS.
The other way is to generate contents witho some special class, e.g. <div class="noscript">, and then you run the script (jQuery):
$(".noscript").hide();
I encountered a problem that took me some time to debug where a plug-in that I was using for jQuery (in this case jFeed) was not working. The problem ended up being because we also used Amazon Associates product previews. The product previews code ends up including a number of other JS files through document.write(), including another copy of jQuery. Because the product previews code appeared below the jFeed script, jQuery was redefined without the getFeed function.
Is there a best practice to ensure that certain objects like jQuery only get defined once on a page? I'm thinking of something like #ifndef with C/C++, but I don't know how it would work in this case where I didn't write the code that dynamically pulled in jQuery again.
I think in your situation, it would probably be best to redefine the jQuery variable as something else. The other jQuery code might use a different version so you might want to define a new variable which would indicate which jQuery you're using.
You could so something like this:
<script>
var $jMain = jQuery;
</script>
You would then just use the $jMain instead of jQuery or $. It'll be up to you to you to ensure you have the correct jQuery object when you do this. Here's the documentation.
Unfortunately the environment inside one JS sandbox (like within a window or frame of a browser) was not really designed to support the modern world of pulling in scripts from various places; there's no way you can say "define this object and make it resistant to redefinition". (You can even redefine most of the Javascript built-ins if you try!)
Your best shot is to make sure that your code is eval'd last, which gives you final say over the state of the environment when it runs. That doesn't mean other code can't come along later and clobber your definitions, but that's generally really bad form. You can do this by having your script tag be the last element in the body of the document, for example.
See also this jQuery method, which won't help you directly, but gets you thinking about some solutions to page sharing: http://api.jquery.com/jQuery.noConflict/