Use one file to display to lots of webpages - javascript

I'm building a simple webpage. However there are a few dozen sub pages. The way this guy organises his business means the phone number is constantly changing between those in charge of taking calls any given week. Is there a way I can change a single line of text (say in a css file) and have the phone number posted on all the sub pages change every week according to who is in charge of taking the calls?
Since then I've learned just enough to change the template from a messy html/table code to a more streamlined look to the code using css.

You COULD potentially do it via the ::after pseudo-element if this fits your browser support profile: http://caniuse.com/#feat=css-gencontent
Note that IE8 (the only 'common' browser without support of ::after instead of :after) is EOL early next year (and there will be much rejoicing).
While this is an absolutely terrible way of doing this- you're supposed to use CSS for presentation not information, I'm not gonna tell you don't if this is just a temporary hack to save yourself a headache while you implement something less terrible.
Sample of how-to: http://dabblet.com/gist/b4bd30443cdbd810d8a8
Call <span class="data-onCallPhnNum"></span> for help.
.data-onCallPhnNum::after{
content:"(555)-555-5555";
}
Should note that the primary disadvantage of this is that there is no fallback if the browser cannot render the ::after pseudoelement.
Better yet, you could include a Javascript file like this:
[....]
<script type="text/javascript" src="phonenum.js"></script>
</body>
</html>
and having the js in phonenum.js (and its expected HTML use) be:
(function(){
var phnNum = "(555)-555-5555";
var phnLnks = document.getElementsByClassName("data-onCallPhnNum");
for(var i = phnLnks.length >>> 0; i--;){
phnLnks[i].href = "tel:" + phnNum;
phnLnks[i].innerHTML = phnNum;
}
})();
Call the number listed on our contact page for assistance.
This would accomplish the same thing, only not work on browsers with js turned off, has a natural fallback, has a clickable phone number for mobile viewers, and isn't using CSS for information.
You should still eventually move this into a database and have the number pulled server side, but for a hack to save on headaches before that real solution's ready, either'll do.
EDIT NOTE: Beers go to CBroe for suggesting the tel: protocol and the formalization of the fallback.

There are two other options, neither on is strictly an HTML solution.
Server Side Includes are one option, though they are falling out of favor.
Another option is using a server-side template system, such as PHP.

Related

javascript newbie: what's the right way to apply the same behavior to multiple elements?

I'm taking my first adventure with javascript, and totally without my bearings. I'd like to show a thumbnail that opens a modal with a larger view of the picture (and this is really the only front end fanciness I'll need, so I'm trying to keep it simple). I've copied this code from w3schools, which uses getElementById. It works great for the first image on the page but clicking subsequent images doesn't pop anything up. Reading around on stack overflow it sounds like that's because I'm matching on the id, but each element on the page will/should have a different id (which makes sense).
I saw a post here where the person made the ids unique by appending the element's id. I could do something like that, but I (a) wanted to check if that's kosher and (b) then obviously the id will no longer match, so is there some different attribute I would tack on to match up my HTML with my styles? This must be a common problem- what's the right way to apply the same behavior to multiple elements on a page? For example I can give them
thanks!
UPDATE: based on everyone's feedback below I've modified the code to use getElementByClassName instead of getElementById- see gist here: https://gist.github.com/dianekaplan/1602a7c0a1c1ec6aa103b61d6530ff15
If I'm reading the code correctly, then the important lines for me to change are from line 115 to line 116- (to set the image info based on ClassName, not id)- and replacing 'myImg' with popup' in the style lines 5 and 11, but clicking the first image no longer opens the modal, so I missed something. Anyone see what's wrong that I need for it to work?
You should use a class name (the same in all img) instead of ids and then use getElementsByClassName() to fetch all of them, instead of getElementsById() which gets only one (as ids must be unique).
Then, you should store the full size image's url somehow in order to fetch it regardless of which img was clicked. One way may be using data attributes.
Example:
<img src="thumb1.jpg" data-fullsize="full1.jpg" class="popup">
<img src="thumb2.jpg" data-fullsize="full2.jpg" class="popup">
<img src="thumb3.jpg" data-fullsize="full3.jpg" class="popup">
var elems=document.getElementsByClassName("popup");
for(var i=0;i<elems.length;i++) {
elems[i].onclick=function() {
var fullsize=this.dataset.fullsize;
//open de popup, fullsize has the clicked image url
}
}
Code not tested, for the idea only.
To answer your primary question ID's are "supposed to" [1] be unique so unless you came up with a convention such as a prefix or regex you couldn't easily use them to group elements together.
If you want to group together multiple elements you could use a class, instead, in which case instead of getElementById you'd use getElementsByClassName.
That being said I wouldn't recommend that either; using vanilla JavaScript can be very time-consuming to make a complex application. You will be tempted to merge the UI with all your functionality. This works great for smaller applications but it can become very unruly, particularly if you don't take steps to allow yourself to refactor in the future, in which case you'll be stuck with an application few can easily be trained on and modify.
You are correct to learn the language, though, prior to a framework. JavaScript is especially quirky.
I would suggest if you're looking to create a web application to look into a modern JavaScript framework after learning JavaScript, HTML and CSS. (And focus on having a practice to being able to refactor/upgrade/improve otherwise you'll be stuck in 2016 and it'll be 2020 - you don't have to worry about this immediately, but start learning about how to do that while you're learning the language.)
To find frameworks I would suggest exploring what's out there. Here's an example of one on GitHub. That's probably a hand-coded list. It's also good to explore exhaustive lists, such as just looking at the "most starred" Repositories on GitHub that are written in JavaScript. And of course check elsewhere besides GitHub, too.
I happen to know AngularJS the best and it happens to be one of the most popular but I would recommend for you to explore and find one that has syntax you like. You might find a different one more intuitive. Here's a plunker that shows how to solve that problem in AngularJS.
Notice how all the functionality is separate from the UI and how declarative it is - the main directive has no idea how the images are being rendered - it just says here are some image url's and descriptions:
scope.images = [{
url: 'http://www.w3schools.com/howto/img_fjords.jpg',
description: 'Trolltunga, Norway'
},{
url: 'http://www.w3schools.com/howto/img_fjords.jpg',
description: 'Other Description'
},{
url: 'http://www.w3schools.com/howto/img_fjords.jpg',
description: 'Another Description'
}];
This is what initializes the app: <html ng-app="plunker"> and <main></main> is akin to the "main method" in that it is the component that calls all the other components.
It's much easier to test an app's functionality if you're careful to separate out the presentation concerns from the rest of the app. It will take a while to learn JavaScript and probably any framework, though, so don't expect too much too soon if you're just getting your hands wet in JavaScript - but if you've programmed for a while you already know this :)
(Disclaimer: What I did isn't necessarily the "best practices" as I tried to simplify it a bit so as to not overwhelm OP too much with information, although the added complexity is useful in more advanced scenarios.)
[1] "Supposed to" meaning browsers may do their best to render a page, even it isn't "compliant" HTML. Web Applications suffer from having to have the same code work on different browsers, operating systems and versions of each all implementing the standards (or choosing not to) differently. It's a nightmare if you haven't ran into it, yet.

Effeciency, hidden HTML or JavaScript DOM appending?

I am working on a simple Cordova app with about 4 page types and I am trying to think through which is the better way to handle the inner HTML templates.
Hidden HTML hard coded into the HTML files that is hidden and populated/revealed by my JS.
Using a JS template system and appending and removing from the DOM.
I feel that appending all that to the DOM for a page is inefficient when I could just update the sections that change. But perhaps an append is lightweight enough where I shouldn't worry about it.
There are a number of ways you can do it. In terms of load on the browser. That is hard to say. From your question it is hard to know what is in these pages, what are you displaying, is it live data, static html etc.
When you first plot out an app, if you are from the old class of building multiple page websites, it can be a little concerning as to how well your app/page will run with all those pages crammed in to one, and all that data plus code.
The answer is, amazingly well. If done properly in modern browsers, and for example Ipads the app will run to near native performance.
The options you have are
Map all the pages into one HTML document. Hide each page content using css display:none, flip them into view using css animation, fading or just display:block.
Use a javascript routing library to map urls to blocks of code that deal with each page, this makes mapping out your app much easier, and means that buttons can just link to your pages, like a real website. see http://projects.jga.me/routie/
Building all the page templates into one page can make it hard to code, as the page becomes enormous, consider breaking the inner content of each page into separate files, you can then give each page holder a url and use a small xhr request to load the page on-the fly, once loaded you can cache it into memory or even local-storage, depending on whether you remove it when it is closed or keep it hidden.
In my experience you can put an enormous number or nodes into one page and have very little speed drop, bear in mind if you use something like jquery and do a lot of $(".page > .page1 > .items li") your going to have a slow app.
Tips
Use element ID's everywhere document.getElementById(..) is 100's of times faster in a loop that $(...)
cache elements when you find them, if you need them later store them in a memory cache.
keep for loop inner code to a minimum.
use a decent click touch libary like http://hammerjs.github.io/ and delegate all the events of the body tag or at least on each page.
If you need to touch the server, load data, think dom first, device second server later. A good app is a responsive app, that responds to the user instantly.
I know this has been posted a while ago, but for the sake of the users I am going to add my answer.
I completely agree with MartinWebb but my answer will shed some light on the results of his options. I am currently working on a similar project. Please note that this answer pertains to cordova (previously called phonegap) specifically. My app has about 5 pages with +-20 different components (input's, div's, h1's, p's, etc.). This is what i tried and the result of each:
jQuery was my first option, mainly because it is easy to use and reduces the amount of code required to accomplish a said goal. Result: First time I tried this approach I though I would spice it up with animations and transformations. The result of this was a very unresponsive app. I removed the animation and transformation, however due to the nature of my application I required multiple dynamically added components and jQuery just wasn't up for the task.
Css display:none and visible:hidden was my next option. I used javascript's dom to display certain div's. Result: This works if your not planning on switching many div shortly after one another eg. a simple menu. It quickly became apparent that this wasn't going to work. Also this does not eliminate my need for the dom. Remember document.getElementById('menu').style.display = "none"; is still part of the dom. This as a solution, for me, is poor. There is a reason that var menu= document.createElement('div'); is part of the language. Which brings me to my last option.
Building a page 90% on javascript's dom was my last option. Logically I could not see how 600 lines of code cold trump one .innerHTML or .style.display = "block"; but it did. Result: It was by far the most responsive of all the solutions.
I'm not saying that all webpages should be coded with dom appending, but as I stated previously, for a cordova app of a few pages (<6), with a few components a javascript dom appending approach would be best. It takes longer to code, but you will be rewarded with control and efficiency. I would suggest coding the backbone of your app in html and populating and controlling with javascript's dom.
Best of luck.
The first option, <div>s with display:none; would be more efficient by a small margin, but you can get the best of both worlds by compiling your JavaScript and templates together into a single file using something like browserify or require.js.

From a long HTML to many JPEGs (or any other image)

I have a long web page (vertically)
which can be thought of having 40 pages.
each page is divided by a hr element like this:
and has the same height: 860px.
I would like to transform each 'page' in that html in a jpg.
In an automated way of course.
Can somebody suggest how ?
This isn't an easy problem to solve because for one, different browsers may render the page slightly differently. So how important is it that the table looks exactly like it does on the webpage?
It's more common to convert HTML pages to PDF, for printing purposes or email attachments. There are many libraries to do this (but they're all a bit meh), I've used TCPDF with some success.
You may either
create an image of the whole page, then use some image library to split the hrs
or inject some javascript into your page and use it to hide everything but one single page, then take a screenshot individually.
Try wkhtmltoimage, which uses a headless webkit browser to generate images of HTML pages. Manual
Alternatively, there's browsershot's screenshot factory, which I haven't tried out but will probably do the job. However, it may require a bit of tweaking.
Then there's crazy things like HTML parsers written in JS, but I don't think they're any use in this case. Just to mention that.

How could I "turn off" a stylesheet?

I am creating a website for a University assignment and we have to concentrate on the accessability functions. I have successfully managed to use resize text buttons but am looking for a way to turn off a css file via a button or link.
I have scoured the net and cannot seem to find very much, I found a good website that had the button I am looking for so hit F12 but it would not display the javascript for it.
Ideally I would like to achieve it without the use of javascript but if there is no other way then I am open to any help that I can get.
I am sorry if this is a simple question but I really did look hard for an answer but to no avail, I am only a first year student so have a long way to go!
This should work
for ( i=0; i<document.styleSheets.length; i++) {
void(document.styleSheets.item(i).disabled=true);
}
Here's a good way to do it quickly from javascript:
Precede all of your CSS rules with the tag body.enabled:
body.enabled p {
}
body.enabled #Myselector {
}
...
Declare your markup as such:
...
<body class="enabled">
...
</body>
...
In your JavaScript, when you want to disable CSS, remove the class "enabled" from the <body> and switch it with something else (say, "disabled"). Use whatever methodology you see fit to do this (jQuery would make this easy, but it can be done without)
You're not really disabling CSS using this, you're just making it so that none of it applies. From a user's standpoint, they likely won't know the difference.
You can do it server side when the user clicks on a "special" link, your server side code simply "skips" the stylesheets elements.
Are you trying to mimick every feature already designed in browsers (T+, T-, no CSS)? Were you asked to make an accessible website or specifically to implement accessibility features? I understand this is an assignment but that's quite a waste of time IMHO, a time that would be better spent on implementation of WCAG 2.0 recommendation. (I use the "Accessiweb" methodology a lot).
My first idea was to deconstruct existing CSS like Universal IE6 does for IE6 (you just have to remove the conditional comments and aim to every browser) but #kappa solution seems better as in both cases you must have access to source code.

Designing a website for both javascript script support and not support

Okay i know that it's important for your website to work fine with javascript disabled.
In my opinion one way to start thinking about how to design such websites is to detect javascript at the homepage and if it's not enabled redirect to another version of website that does not javascript code and works with pure html (like gmail)
Another method that i have in mind is that for example think of a X (close button) on a dialog box on a webpage. What if pressing the X without any javascript interference lead to sending a request to the server and in the server side we hide that dialog next time we are rendering the page, And also we bind a javascript function to onclick of the link and in case of the javascript enabled it will hide the dialog instantly.
What do you think of this? How would you design a website to support both?
One way to deal with this is to :
First, create the site, without any javascript
Then, when every works, add javascript enhancements where suitable
This way, if JS is disabled, the "first" version of the site still works.
You can do exactly the same with CSS, naturally -- there is even one "CSS Naked Day" each day, showing what websites look like without CSS ^^
One example ?
You have a standard HTML form, that POSTs data to your server when submitted, and the re-creation of the page by the server displays a message like "thanks for subscriving"
You then add some JS + Ajax stuff : instead of reloading the whole page while submitting the form, you do an Ajax request, that only send the data ; and, in return, it displays "thanks for subscribing" without reloading the page
In this case, if javascript is disabled, the first "standard" way of doing things still works.
This is (part of) what is called Progressive enhancement
The usual method is what's called progressive enhancement.
Basically you take a simple HTML website, with regular forms.
The next enhancement is CSS - you make it look good.
Then you can enhance it further with Javascript - you can add or remove elements, add effects and so on.
The basic HTML is always there for old browsers (or those with script blockers, for example).
For example a form to post a comment might look like this:
<form action="post-comment.php" method="post" id="myForm">
<input type="text" name="comment">
</form>
Then you can enhance it with javascript to make it AJAXy
$('#myForm').submit(...);
Ideally the AJAX callback should use the same code as post-comment.php - either by calling the same file or via include, then you don't have to duplicate code.
In terms, it is not important to make your site work with JavaScript disabled. People who disable JavaScript are people who want to hack bugs into your site, they don't deserve to navigate it correctly. Don't waste your efforts with them. Everybody know the Web is unsurfable without JavaScript.
The only thing you have to be careful is about your forms: Don't ever trust filters in JavaScript, Always filter it again on server-side, ALWAYS!
Use Progressive Enhancement, study jquery to understand it. It takes some time till you get your head around it. For example your idea:
to detect javascript at the homepage
and if it's not enabled redirect to
another version of website that does
not javascript code and works with
pure html
how would you detect if javascript is disabled? not with javascript, obivously...
you're thinking the wrong way round: the most basic version has to be the default version, and then, if you detect more advanced capabilities, you can use them.
Try to avoid separate versions for different bowsers/capabilities for as long as you can. It's so much work to keep all versions in sync and up-do-date.
Some good ressources to get you started:
Understanding Progressive Enhancement
Progressive Enhancement with JavaScript
Test-Driven Progressive Enhancement
The best way is to design a page that works adequately without JS. Then add a <script> block at the bottom of the <body> section with code like this:
window.onload = function() {
// Do DOM manipulations to add JS functionality here. For instance...
document.getElementById('someInputField').onchange = function() {
// Do stuff here that you can't do in HTML, like on-the-fly validation
}
}
Study the jQuery examples. They show lots of things like this. This is called "unobtrusive JavaScript". Google for that to find more examples.
EDIT: The jQuery version of the above is:
$(document).ready(function() {
// Do DOM manipulations to add JS functionality here. For instance...
$('#someInputField').change(function() {
// Do stuff here that you can't do in HTML, like on-the-fly validation
});
});
I added this just to show the lower verbosity of jQuery vs. standard DOM manipulation. There is a minor difference between window.onload and document.ready, discussed in the jQuery docs and tutorials.
What you're aiming for is progressive enhancement. I'd go about this by first designing the site without the JavaScript and, once it works, start adding your JavaScript events via a library such as jQuery so that the behaviour of the site is completely separate from the presentation. This way you can provide a higher level of functionality and polish for those who have JavaScript enabled in their browsers and those who don't.

Categories

Resources