Unobtrusive Javascript onclick - unobtrusive-javascript

I was recently reading on Unobtrusive javascript and decided to give it a shot. Whether or not I decide to use this style is to be determined at a later time. This is just for my own curiosity and not for any time restricted project.
Now, I was looking at example code and a lot of the examples seem to be using, what took me forever to discover, jQuery. They use a function like $('class-name').whatever(...);
Well I rather like the look of $('class').function, so I tried to emulate it without using jQuery(as I don't know jQuery and don't care about it atm). I'm unable, however, to make this example work.
Here is my jsFiddle: http://jsfiddle.net/dethnull/K3eAc/3/
<!DOCTYPE html>
<html>
<head>
<title>Unobtrusive Javascript test</title>
<script>
function $(id) {
return document.getElementById(id);
}
$('tester').onclick(function () {
alert('Hello world');
});
</script>
<style>
.styled {
width: 200px;
margin-left: auto;
margin-right: auto;
font-size: 2em;
}
a {
cursor: pointer;
color: blue;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class='styled'>
<ul>
<li><a id='tester'>CLICK ME</a></li>
</ul>
</div>
</body>
</html>
I was expecting an alert box to pop up when you click on the link, but doesn't seem to happen. When checking the console in chrome it gives this message "Uncaught TypeError: Cannot call method 'onClick' of null"
I'm not a javascript expert, so more than likely I'm doing something wrong. Any help is appreciated.

Try this code,
Script
function $(id) {
return document.getElementById(id);
}
$('tester').addEventListener('click', function () {
alert('Hello world');
});
When you console this $('tester') selector, it simply returns <a id='tester'>CLICK ME</a> which is a html element not an object so you cannot use onclick directly. Instead you have to use addEventListener or attachEvent to bind a click event
Demo JS http://jsfiddle.net/K3eAc/4/

You don't need addEventListener or attachEvent: live demo.
The code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Unobtrusive Javascript test</title>
<style>
.styled {
width: 200px;
margin-left: auto;
margin-right: auto;
font-size: 2em;
}
</style>
</head>
<body>
<div class="styled">
<ul>
<li>CLICK ME</li>
</ul>
</div>
<script>
var tester = document.getElementById('tester');
tester.onclick = function() {
alert('Hello world');
}
</script>
</body>
</html>
.
I'm better in practice than in theory, but it would seem to me that with converting the targeted element into a variable, it becomes an object. Tested in IE8/9, Chrome25 and FF30.

Try this
function $(id) {
return document.getElementById(id);
}
var a = $('tester');
a.onclick = (function () {
alert('Hello world');
});
Reference : https://developer.mozilla.org/en-US/docs/DOM/element.onclick

Related

Why is my Flutter web app not loading completely after uploading on Cpanel?

<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="afri_pro">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<title>AfriPro</title>
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" type="text/css" href="splash/style.css">
<script src="https://unpkg.com/canvaskit-wasm#0.33.0/bin/canvaskit.js"></script>
<link rel="preload" href="https://unpkg.com/canvaskit-wasm#0.33.0/bin/canvaskit.wasm" as="fetch" crossOrigin="anonymous">
</head>
<style>
.loading {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border: 15px solid;
border-top: 16px solid blue;
border-right: 16px solid white;
border-bottom: 16px solid blue;
border-left: 16px solid white;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<body style="position: fixed; inset: 0px; overflow: hidden; padding: 0px; margin: 0px; user-select: none; touch-action: none; font: 14px sans-serif; color: red;">
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<!-- <div class="loading">-->
<!-- <div class="loader"></div>-->
<!-- </div>-->
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-messaging.js"></script>
<script>
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
<!-- <script src="firebase-messaging-sw.js"></script>-->
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", function() {
navigator.serviceWorker.register("/firebase-messaging-sw.js");
});
}
</script>
<script type="text/javascript">
let useHtml = "html";
if (useHtml) {
window.flutterWebRenderer = "html";
} else {
window.flutterWebRenderer = "canvaskit";
}
</script>
<script>
var serviceWorkerVersion = '1941516564';
var scriptLoaded = false;
function loadMainDartJs() {
if (scriptLoaded) {
return;
}
scriptLoaded = true;
var scriptTag = document.createElement('script');
scriptTag.src = 'main.dart.js';
scriptTag.type = 'application/javascript';
document.body.append(scriptTag);
}
if ('serviceWorker' in navigator) {
// Service workers are supported. Use them.
window.addEventListener('load', function() {
// Wait for registration to finish before dropping the <script> tag.
// Otherwise, the browser will load the script multiple times,
// potentially different versions.
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
navigator.serviceWorker.register(serviceWorkerUrl)
.then((reg) => {
function waitForActivation(serviceWorker) {
serviceWorker.addEventListener('statechange', () => {
if (serviceWorker.state == 'activated') {
console.log('Installed new service worker.');
loadMainDartJs();
}
});
}
if (!reg.active && (reg.installing || reg.waiting)) {
// No active web worker and we have installed or are installing
// one for the first time. Simply wait for it to activate.
waitForActivation(reg.installing || reg.waiting);
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
// When the app updates the serviceWorkerVersion changes, so we
// need to ask the service worker to update.
console.log('New service worker available.');
reg.update();
waitForActivation(reg.installing);
} else {
// Existing service worker is still good.
console.log('Loading app from service worker.');
loadMainDartJs();
}
});
// If service worker doesn't succeed in a reasonable amount of time,
// fallback to plaint <script> tag.
setTimeout(() => {
if (!scriptLoaded) {
console.warn(
'Failed to load app from service worker. Falling back to plain <script> tag.',
);
loadMainDartJs();
}
}, 4000);
});
} else {
// Service workers not supported. Just drop the <script> tag.
loadMainDartJs();
}
</script>
<picture id="splash">
<source srcset="splash/img/light-1x.png 1x, splash/img/light-2x.png 2x, splash/img/light-3x.png 3x, splash/img/light-4x.png 4x" media="(prefers-color-scheme: light) or (prefers-color-scheme: no-preference)">
<source srcset="splash/img/dark-1x.png 1x, splash/img/dark-2x.png 2x, splash/img/dark-3x.png 3x, splash/img/dark-4x.png 4x" media="(prefers-color-scheme: dark)">
<img class="center" src="splash/img/light-1x.png" />
</picture>
</body>
</html>
i am done building my app on VsCode with Flutter, after I had run without debugging on chrome browser it works perfectly fine.
These are the steps i took.
I try to run the flutter build webcommand it builds.
After building, i copy the build/web files to my Cpanel folder named after the url
It works but doesn't load completely unlike when it ran on my chrome on debug mode.
I'll paste the snippet of my index.html
This is the content of the build folder uploaded
This is what i have tried:
Editing the <base href="/"> to <base href="/subfolder containing the files">
Comparing the old version files to this, i don't really see any significant difference.
What would be the problem guys?
NB: The previous version of the app works fine but when i upload the new version i get this bug.
<base href="">
I have fixed this!
I found out by inspecting the page on my google chrome that the file .env was not found (Error 404), and these is where the most important configs for firing up my web app was.
So i took the below steps
Steps:
I renamed the env file name in my build/web/assets folder from ".env" to "dotenv".
In my "main.dart.js" file, i had to use CMD + F to find the ".env" keyword and then rename it to "dotenv".
After doing this i had to clear my browser cache and reloaded my app, and it was firing again after over 5 days of looking for a solution!!!

"html/main.html: not found" error in kdb web application

I'm developing a web application using websocket by taking reference from https://code.kx.com/v2/wp/websockets/.
The application resides at path:
Directory structure:
/Users/repos/chatu/
-->html
--> main.html
--> main.js
-->q
--> main.q
q)\pwd
"/Users/repos/chatu" //- and main.html(index) is at path /Users/repos/chatu/html/main.html
When the pwd is "/Users/repos/chatu" then the webpage is opening properly on browser using url - http://localhost:5001/main.html
But when the pwd is changed to any other directory such as
q)\pwd
"/Users/repos"
Then hitting same url as above throws below error :
html/main.html: not found
What I can understand from the error is that web server is expecting the html/main.html at the current working directory and it is not able to find that.
How/Where can I set absolute path for index.html that from any current working directory the web browser can find the main.html page?(Cannot find/understand any answer which solves same problem).
Code snippet -
main.js
function connect(){
if ("WebSocket" in window) {
ws = new WebSocket("ws://localhost:5001/");
output.value="connecting...";
/* ws.onopen=function(e){output.innerHTML="connected"}; */
ws.onclose=function(e){output.innerHTML="disconnected"};
ws.onerror=function(e){output.value=e.data};
/*
when a message is received,
prepend the message to the display area
along with the input command
*/
} else alert("WebSockets not supported on your browser.");
}
main.html
<!doctype html>
<html>
<head>
<title>Chatu</title>
<style>
/* define some CSS styling on page elements */
div#wrap{
width:100%;
overflow:auto;
}
textarea#txtInput {width: 97.5%; height: 60px; float:left; padding: 10px; margin-top: 10px;}
div#txtOutput{
width: 97.5%; height: 300px; font-family: "Courier New"; padding: 10px;
border: 1px solid gray; margin-top: 2px; overflow:auto;
}
</style>
</head>
<body>
<div id="wrap">
<fieldset id='heads' style="border:1; border-radius:10px">
<legend align="center" style="color:blue">Chatu</legend>
<div id="txtOutput"></div>
<textarea id="txtInput" autofocus></textarea>
</fieldset>
</div>
</body>
<script type="text/javascript" src="main.js"></script>
</html>
main.q
.z.ws:{neg[.z.w].j.j #[.da.mf;x;{`$ "'",x}];};
I believe the way you can set an absolute path for index html as you have described in your kdb web application is assigning this path using .h.HOME.
The variable .h.HOME is a string which contains the location of the webserver root.
If you would like a more detailed explanation on .h.HOME refer to https://code.kx.com/v2/ref/doth/#hhome-webserver-root
.h.HOME is the variable you are interested in
https://code.kx.com/v2/ref/doth/#hhome-webserver-root

jQuery - slideToggle to select and deselect button

I have a jsfiddle here - http://jsfiddle.net/eYV4n/
Really simple navigation and a hidden div block beneath it.
When you click the second link in the nav the div block slides down with slideToggle.
When the div block slides down I would like the button clicked to be selected.
I can do this when it's clicked by changing the background color.
Is it possible to deselect the link (change it's color back) when the div block slides again.
jquery.hover() handler hover-in and hover-out. Is it possible to do the same thing with slideToggle.
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="robots" content="">
<title>Title of the document</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<style type="text/css">
*{
margin:0;
padding:0;
}
body{
background:#eee;
}
#wrap{
background:#fff;
max-width:800px;
margin:0 auto;
height:1000px;
}
ul{
list-style:none;
overflow:auto;
}
ul li{
display:inline;
}
ul li a {
float:left;
display:block;
color:#222;
padding:10px;
margin:0 5px 0 0;
}
#block{
width:100%;
margin:0 auto;
height:200px;
background:red;
display:none;
}
</style>
</head>
<body>
<div id="wrap">
<nav>
<ul>
<li>One</li>
<li>Two ↓</li>
<li>Three</li>
<li>Four</li>
</ul>
</nav>
<div id="block">
</div>
</div><!-- #wrap -->
<script>
$('#btn').click(function(e){
e.preventDefault();
$('#block').slideToggle('2000')
$('#btn').css('background','red');
})
</script>
</body>
</html>
A better solution is to toggle a class that in turn changes the background. You should make it a best practice to never style elements with Javascript, you should use CSS for that. Adding/removing classes is fine though. This will make the code much easier to maintain in the long run, and it's also more semantic since you're using classes and not inline styling.
Try this:
$('#btn').click(function(e){
e.preventDefault();
$('#block').slideToggle('2000')
$('#btn').toggleClass('active');
})
Then in your CSS.
.active { background: red; }
Edit: Jsfiddle here.

CSS: How can I hide a class which has no other class or ID?

So how can I had a td which has only 1 class?
For example:
<td class="ss_label ss_class">Hello</td>
<td class="ss_label">World!</td>
I this case I want to display:none the second one.
This works: $('[class="ss_label"]').hide(); but I don't want to use Javascript or any library such as jQuery. Just pure CSS.
In the real life example, the td I want to hide is the sixth and seventh.
You can use that attribute selector from jQuery in CSS as well:
td[class="ss_label"] { display: none }
This will match a <td> element whose class attribute is exactly "ss_label" with no other additions to it. Works in all major browsers except IE6 (if you consider it a major browser).
You can do:
.ss_label { display: none }
.ss_label.ss_class { display: table-cell }
for this specific case.
As far as I know, there is no general solution.
<style type="text/css">
.ss_label {
display:none;
}
.ss_label.ss_class {
display:block;
}
</style>
The last rule overrides the first one
Maybe you can use the attribute selector (works in safari)
<html>
<head>
<style>
div.hide { color: green }
div[class=hide] { display: none }
</style>
</head>
<body>
<div class="hide">Hide me</div>
<div class="no hide">Don't hide me</div>
</body>
</html>

How to use Jquery tools Overlay programmatically?

I wan to show an overlay programmatically. I tried to modify the code in this example Opening overlays programmatically. Instead of loading the overlay only once upon document load as shown in this example, I want to show the overlay everytome a user clicks the button. The problem is thatthe overlay is loaded only for the first click. It does not open for the subsequent clicks on the same button
Here is my code.
<html>
<head>
<title>jQuery Tools standalone demo</title>
<script src="http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://static.flowplayer.org/tools/css/standalone.css"/>
<style>
#facebox {
display:none;
width:400px;
border:10px solid #666;
border:10px solid rgba(82, 82, 82, 0.698);
-moz-border-radius:8px;
-webkit-border-radius:8px;
}
#facebox div {
padding:10px;
border:1px solid #3B5998;
background-color:#fff;
font-family:"lucida grande",tahoma,verdana,arial,sans-serif
}
#facebox h2 {
margin:-11px;
margin-bottom:0px;
color:#fff;
background-color:#6D84B4;
padding:5px 10px;
border:1px solid #3B5998;
font-size:20px;
}
</style>
<script>
var overlayDiv=function(){
$("#facebox").overlay({
api: true,
top: 260,
mask: {
color: '#fff',
loadSpeed: 200,
opacity: 0.5
},
closeOnClick: false,
load: true
})
};
$(document).ready(function() {
$("#triggerBtn").click(function(){
console.log(" I have been CLICKED");
overlayDiv();
});
});
</script>
<body>
<button id="triggerBtn"> Trigger Overlay</button>
<div id="facebox">
<div>
<h2>Facebox</h2>
<p>
This dialog is opened programmatically when the page loads. There is no need for a trigger element.
</p>
<form>
<input type="file" />
</form>
<p style="color:#666">
To close, click the Close button or hit the ESC key.
</p>
<p>
<button class="close"> Close </button>
</p>
</div>
</div>
</body>
This should do the trick for you.
$("#triggerBtn").click(function(){
console.log(" I have been CLICKED");
$('#facebox').data('overlay').load();
});
More information here - Jquery Tools Overlay Scripting API
This is working for me... I found this method on the jQuery Tools forum and seems to be the best I can find for now.
<script>
function popup() {
if ($("#facebox").hasClass("init")) {
$("#facebox").overlay().load();
}
else {
$("#facebox").addClass("init");
$("#facebox").overlay({
// custom top position
top: 260,
mask: { color: '#838383',
loadSpeed: 200,
opacity: 0.5
},
closeOnClick: true,
load: true
});
}
}
</script>
Simplify:
var overlay;
function overlayDiv()
{
if (typeof overlay === 'undefined')
overlay = $('#facebox').data('overlay').load();
else
overlay.load();
}
You should use:
$(".overlay").remove();