Accessing jQuery objects in the module pattern - javascript

Really getting in to javascript and looking around at some patterns. One I have come accross is the module pattern. Its seems like a nice way to think of chucks of functionality so I went ahead and tried to implement it with jQuery. I ran in to a snag though. Consider the following code
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>index</title>
<script type="text/javascript" charset="utf-8" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
var TestClass2 = (function(){
var someDiv;
return {
thisTest: function ()
{
someDiv = document.createElement("div");
$(someDiv).append("#index");
$(someDiv).html("hello");
$(someDiv).addClass("test_class");
}
}
})();
TestClass2.thisTest();
});
</script>
</head>
<body id="index" onload="">
<div id="name">
this is content
</div>
</body>
</html>
The above code alerts the html content of the div and then adds a class. These both use jQuery methods. The problem is that the .html() method works fine however i can not add the class. No errors result and the class does not get added. What is happening here? Why is the class not getting added to the div?

Ah, now that you've updated your question I can better answer your question. You should change the append to appendTo considering you're wanting to move the newly created element inside of the already present #index.
$(document).ready(function() {
var TestClass2 = (function() {
var someDiv = $("#name");
return {
thisTest: function() {
someDiv = document.createElement("div");
$(someDiv)
.html("hello")
.addClass("test_class")
.appendTo("#index");
}
}
})();
TestClass2.thisTest();
});
Hope this helps!

I copied and pasted your code and it works for me.
Make sure you're not simply viewing source to see if the class is applied because doing so simply shows you the HTML that was sent from the server - any DOM updates that occur through JavaScript will not be reflected.
To view the live DOM, use a tool like Firebug or WebKit's Inspector (comes built-in to Safari and Chrome).

Your code works great!
http://jsfiddle.net/lmcculley/p3fDX/

Related

Is it possible to use javascript to modify a script element?

Is there a way to use javascript to modify a script element?
Like for example:
HTML:
<script id="something" src="/js/file.js"></script>
Javascript:
var something = document.getElementById("something");
something.src = "/js/anotherfile.js"
Is it possible? Because I have a bit of code that works like that and it sort of doesn't work
To be specific, here's the code:
<!DOCTYPE html>
<html>
<head>
<title>MyohTheGod's Website</title>
<link rel="icon" type="image/x-icon" href="/supercorn.gif" defer>
</link>
<link id="css" href="/css/dark.css" rel="stylesheet" type="text/css">
</link>
<script src="/js/particles.js" defer></script>
<script src="/js/header.js"></script>
<script src="/js/theme.js"></script>
<script>window.alert("Welcome to the Home of MyohTheGod. You can play games, check out our web proxies, and more. Also, please do check out the About page. Press OK to continue...");</script>
</head>
<body>
-snip-
</body>
<script id="foot" src="/js/footer.js"></script>
</html>
<script>
-snip-
</script>
var css = document.getElementById("css");
var foot = document.getElementById("foot");
function toggleDLmode(m) {
-snip-
if (dlmodebool) {
css.href = "/css/dark.css"
foot.src="/js/dark-footer.js"
} else {
css.href = "/css/index.css"
foot.src="/js/footer.js"
}
}
-snip-
It is working, do you inspect it? It does changed, but maybe you're thinking, "hm why this /js/anotherfile.js is not downloaded?". Well because of the script tag is already rendered and already downloaded, so you can't do that. What you can do though add NEW script tag.
Maybe this will help How to dynamically change the script src?. This links would explain more why your code "does not work".
There certainly is. You can use document.scripts which returns an collection that you can iterate through like an array. You can change the code using the innerHTML property very much like a normal element. See here https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
Edited to add: If you've got a html page with multiple script tags, the document.script collection has each script in the order they appear. The code below will log out the source (src tag) or the actual javascript for each script element.
You can also 'write' javascript by setting the innerHTML property.
IMHO it's a bit of a solution that's looking for a problem but at least it gives you access to the number of scripts you have.
[...document.scripts].forEach(script => {
if (script.src != '') {
console.log("Script source:" + script.src);
} else {
console.log(script.innerHTML);
}
});

HTML and JavaScript in separate files - newbie alert

OK. I feel dumb! I've been trying to do something very simple and yet finding it very difficult to do or to find. All I want to do is:
have the index.html file display.
I want a separate JavaScript file that contains all of my JavaScript code. Completely separated, so I don't have any JavaScript code in my HTML file. I don't want a click event or anything fancy.
I just want the page to display Hello World! onLoad by getting it from a JavaScript function.
BTW: Seems all tutorials either put the JavaScript code in with the HTML or they want to show you how to do something fancy. I've been all over SO to no avail.
The closest I've gotten is listed below. I give up! A little help would be so appreciated.
index.html:
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="script.js"></script>
</head>
<body>
<script type="text/javascript"></script>
</body>
</html>
script.js:
window.onload = function() {
var result="Hello World!";
return result;
};
if you want to append to body, you can create a text node ( createTextNode() ) and then directly append that to body:
window.onload = function() {
var result = document.createTextNode("Hello World!");
document.querySelector('body').appendChild(result);
};
What you can do is print the text you want to the <body> element when the page loads. Something like this should do the trick:
window.onload = function() {
var result="Hello World!";
document.querySelector('body').innerHTML(result);
};
Or if you had a particular place on your webpage that you wanted to load this text into, you can create an element in your HTML, give it a unique id and reference it in your JavaScript:
<body>
...
<div id="myAwesomeElement"></div>
...
</body>
and in the JavaScript:
window.onload = function() {
var result="Hello World!";
document.querySelector('#myAwesomeElement').innerHTML(result);
};
In your javascript function, you can do something like this:
document.getElementById("divID").innerHTML="Hello World!";
and in your html file create a div or span or something that you want modify(in this case, the inner html content):
<body>
<div id="divID"></div>
</body>
When the function is called, it will find the dom element with the Id of "divID", and the innerHTML will be what you assign the Hello World to. You could modify other properties like css style stuff too.
If you want to grab a hold of a place where to put your file, you need to address it.
Eg.
<body>
<div id="place-for-text"></div>
</body>
And then in your script:
var elem = document.getElementById('place-for-text');
elem.innerHTML = 'Hello world.';
That is about the simplest way to do it in a way you could control some of it.
You could go more fancy and add a DOM element instead:
var elem = document.getElementById('place-for-text');
var text = document.createTextNode('Hello world');
elem.appendChild(text);
Here's a way that hasn't been shown yet.
You can remove the script tag from the head of the file since we want the js file to load up after the rest of the page. Add the script tag with the script.js source to the body.
//index.html
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="script.js"></script>
</body>
</html>
The script.js file looks like this:
//script. js file
!function () { document.querySelector("body").innerHTML = "hello world"; } ();
The exclamation point and the following () causes the function to run automatically upon load. For more info take a look at this question: What does the exclamation mark do before the function?
EDIT
I should also point out that document.write and .innerHTML are not considered best practice. The simplest reasons are that document.write will rewrite the page and .innerHTML causes the DOM to be parsed again(performance takes a hit) - obviously with this example it doesn't really matter since it's a simple hello world page.
An alternative to document.write and .innerHTML
!function () {
var text = document.createTextNode("Hello World");
document.querySelector("body").appendChild(text);
} ();
It's a bit of a pain, but you can write a function for the process and it's no big deal! The good news is that, with the new ecmascript 6(new JavaScript) you can turn this into a quickly written arrow function like the following:
//script.js
! function() {
var addTextNode = (ele, text) => { //create function addTextNode with 2 arguments
document.querySelector(`${ele}`).appendChild(document.createTextNode(`${text}`));
// ^ Tell the function to add a text node to the specified dom element.
}
addTextNode("body", "Hello World");
}();
Here's a JS Fiddle that also shows you how to append to other elements using the same function.
Hope this helps!
There are multiple ways to ways to solve your problem. The first way only changes your javascript. It uses the document.write() function to write the text to the document.
Here is the new javascript:
window.onload = function() {
document.write("Hello World!");
};
The second way also only changes your javascript. It uses the document.createElement() function to create a p tag and then changes the content inside it then appends it to the body.
Here is the new javascript:
window.onload = function() {
var p=document.createElement("p");
p.innerHTML="Hello World!";
document.body.appendChild(p);
};
window.onload = function() {
document.write('Hello World')
};
Returning from window.onload doesn't do anything productive. You need to call methods on the document to manipulate the page.

HTML custom tags not working

I'm trying to implement the features from this site. But my code isn't alerting anything when I click on the x-foo element. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>
Test
</title>
</head>
<body>
<script type="text/javascript">
var xFoo = document.createElement('x-foo');
var xFoo = new XFoo();
document.body.appendChild(xFoo);
xFoo.onclick=function(){alert("It works!")};
</script>
<x-foo>
Test
</x-foo>
</body>
</html>
Any suggestions? (I'm on Chrome)
It looks like you're trying to create a Custom Element but you haven't registered it yet. To create your own XFoo element would look something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Custom Element</title>
</head>
<body>
<!-- Create a template for the content inside your element -->
<template>
<h1>Hello from XFoo</h1>
</template>
<!-- Register your new element -->
<script>
var tmpl = document.querySelector('template');
var XFooProto = Object.create(HTMLElement.prototype);
XFooProto.createdCallback = function() {
var root = this.createShadowRoot();
root.appendChild(document.importNode(tmpl.content, true));
};
var XFoo = document.registerElement('x-foo', {
prototype: XFooProto
});
</script>
<!-- Use the element you've just registered as a tag -->
<x-foo></x-foo>
<!-- OR, create an instance using JavaScript -->
<script>
var el = document.createElement('x-foo');
document.body.appendChild(el);
</script>
</body>
</html>
Unfortunately this approach depends on native APIs which currently only ship in Chrome 34. As someone else mentioned, a much easier approach to creating your own custom element would be to use Polymer. Polymer is a library that adds support for Web Components (essentially what you're trying to build) to all modern browsers. That includes IE 10+, Safari 6+, Mobile Safari, current Chrome and current Firefox.
I've put together a jsbin which shows how to create your own x-foo element using Polymer.
You should try viewing the following article:
http://www.polymer-project.org/
It's an open source Github project. I actually tried that article, but don't recommend it. Instead, use the link given above. It uses Ajax and JSON.

Hide/Show <div> according to URL in Prototype

I am trying to use the prototype framework to hide a '< div >' based on a particular URL. I don't have access to server side - so I have no choice but to do this using prototype [restriction of platform using prototype].
Wondering if someone could tell me how to do this in prototype framework ?
i.e. I tried to do this but doesn't work
Event.observe(window, 'load',
function() {
var url = document.location.href;
if (url.indexOf('registered') >=
0) {
$$('#side-menu-right').hide(); }
if (url.indexOf('login') >= 0)
{ $$('#side-menu-left').hide();
}
});
Love some help ?
P.S - Never used Prototype [jQuery man right here yo!]
I just made a test case on JS Bin which complains:
Exception thrown: $$("#hello").hide is not a function
Caused by line (23/21): $$('#hello').hide();
(using latest version of Prototype)
When using:
$('hello').style.display = "none";
it works correctly, see example.
EDIT: I adjusted the example on JS Bin to conditionally add a class name to the body before the involved element is reached. Using
.registered-user #hello { display: none; }
The element doesn't show up at all. It's not the most neat solution, as you have to throw some script in the middle of your document, but it works. If someone knows a better solution, please tell.
<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<style>
.registered-user #hello { display: none; }
</style>
</head>
<body>
<script>
if (document.location.href.indexOf('registered')>=0)
$$('body')[0].addClassName('registered-user');
</script>
<p id="hello">Hello World</p>
</body>
</html>
Change
$$('#side-menu-right').hide();
to
$('side-menu-right').hide();
Hope this helps.
Reason
1) As you can see, JQuery uses CSS notation while Prototype is straight Javascript (so no #side-menu-right for div with an ID).
2) Struts and Prototype uses $ and not $$.

Why does this javascript code prevent my browser from ever loading?

I'm learning javascript and jquery and have written a very basic script inside my file. I'm experiencing two problems...
The browser never finishes loading the document, it just sits there with the loading icon animating in the tab. Any ideas?
I can't seem to debug this using firebug. When I set a breakpoint anywhere in the document load function, it never hits. Any ideas?
Here's my code...
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link media="screen" type="text/css" href="default.css" rel="stylesheet">
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function()
{
var strMarkup = "";
var strXMLFile = "";
//Parse XML and generate accordion elements
var arrayAccordianElements = ParseXML(strXMLFile);
});
function ParseXML(strPath)
{
var arrayEvents = new Array();
arrayEvents[0] = "test1";
arrayEvents[1] = "test2";
arrayEvents[2] = "test3";
//Return the accordian elements
return arrayEvents;
}
</script>
</head>
<body>
hello
</body>
</html>
As you experts can see, my webpage should simply display "hello" after processing some javascript that creates an array inside of a function. Do you see any problems? I apologize if they're obvious problems, I'm a noob :)
Thanks in advance for all your help!
Runs fine for me in Safari 4.0.3. Make sure your path to jQuery is correct? If it is incorrect and there's something misconfigured and jQuery fails to load, that will hang indefinitely.
Code-wise I don't see anything that would cause an infinite loop at all. However, knowing firefox etc, there may be a variety of things out of your control. Start with restarting the browser. Profile the script with Firebug (Console > Profile > Reload the page > Press profile again), and see what part takes most time.
One thing, probably unrelated, close your link tag. is sufficient.

Categories