Shoud these two JQuery functions produce the same behavior? - javascript

Assuming I have the following two JQuery functions -
The first, which works:
$("#myLink_931").click(function ()
{
$(".931").toggle();
});
and the second, which doesn't work:
$("#myLink_931").click(function ()
{
var class_name = $(this).attr("id").split('_')[1];
$("."+class_name).toggle();
});
I want to replace the first with the second, which is more generalizable, but can't find any obvious syntactical problem with the second which might be preventing it from working.
My guess is there's a problem with the syntax:
"."+class_name
Is this bad syntax?

They work the same.
Working Demo

This is what debuggers are for. Step through the code and make sure class_name is calculated as you expect. The debugger should let you view the result of "."+class_name as well.

I created a sample page and dropped your example code in and it worked as expected. Perhaps there is another issue on the page? Can you post a link to the actual site?
Here is the code I used:
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script src="scripts/script.js" type="text/javascript"></script>
</head>
<body>
<div id="myLink_931">Click Me</div>
<div class="931">HI</div>
</body>
</html>
and the script file:
(function($) {
$(document).ready(function() {
$("#myLink_931").click(function() {
var class_name = $(this).attr("id").split('_')[1];
$("." + class_name).toggle();
});
});
})(jQuery);

Class names and IDs aren't allowed to start with numbers - doesn't explain why one works and the other doesn't though. Give us a bit more info as above.

Is it possible you're not wrapping your 2nd example in the ready syntax [i.e. $(function(){ })] which would mean that the elements haven't been created in the DOM yet?

Related

JQuery .load() does not work

I want to load the content of a webpage in a div. Here's my code:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
When the this item is clicked, the webpage should be loaded inside the content id:
<ul><li><a id="menu_top" href='testing.html'><span>My account</span></a></li></ul>
<div id="content"> </div>
JS:
$("#menu_top").click(function() {
var href = $ (this).attr('href');
alert(href);
$("#content").load(href);
return false;
});
testing.html:
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
SUCCESS!
</body>
</html>
Unfortunately, the above code does not work. I have checked it multiple times but could not find the issue.
#Milind Anantwar is correct - must have the $(document).ready wrap your JS:
$(document).ready(function(){
$("#menu_top").click(function() {
var href = $ (this).attr('href');
alert(href);
$("#content").load(href);
return false;
});
});
I also tested whether or not the UL or OL tags affected it as #psicopoo mentioned, but it didn't seem to in Chrome. *ALSO, make sure that "testing.html" is a valid page to load.
*As noted on http://api.jquery.com/load/: "Due to browser security restrictions, most "Ajax" requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, port, or protocol."
I think you're encountering an issue with the page you're trying to load. I copied your code exactly and it works in Fiddle, see if this works for you, if so, it's probably your page:
testing.html
JS Fiddle:
http://jsfiddle.net/fb4j6y6d/

All Javascript line not executed

I have a simple html page is as-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(e) {
var s = $("#d").get(0).getElementsByTagName("a");
for(var x=0;x<s.length;x++){
document.writeln(s.length);
}
var k=document.createElement("a");
k.innerHTML="hello";
var q=document.getElementById("d");
q.appendChild(k);
});
</script>
</head>
<body>
<div id="d">
<a><img class="zzz"/></a>
<a><img class="zzz"/></a>
</div>
</body>
</html>
Javascript executes only up to for loop (element k is not appended). If for loop is removed then only element k got appended. Isn't code below for loop is supposed to be executed after for loop execution?
Welcome to StackOverflow! A few suggestions to help you as you are learning to develop:
Always use meaningful variable names, it's hard to keep track of what
single letter variables represent
Don't use document.write for
debugging, use the console for that
If you are using a library like
jQuery, try to use it as much as you can when you are beginning to
learn it. Only fall back to basic javascript if you have a compelling
reason to do so
Your function can be rewritten in pure jQuery like so:
$(function() {
var container = $('#d');
console.log(container.find('a').length);
container.append('<a>hello</a>');
});
I haven't run your code, but your error probably has to do with this statement: $("#d").get(0).getElementsByTagName("a");. The eq() method returns a jQuery object, which does not have a getElementsByTagName() method on it.
If you want a plain DOM object without the jQuery wrapper you can address the jQuery object like an array: $('#d')[0].getElementsByTagName("a");, though like I said, it's best to stick with the jQuery library if you are going to use it.
Good luck as you learn!
you can't use writeln (or write) after the document has been loaded(or I better say: you shouldn't, because it will overwrite the complete document, including #d , what will force the error, because this element isn't available anymore after the usage of writeln )
I guess you want something like this:
$(document).ready(function(e) {
$('a').prepend(function(i){return i;});
$('#d').append('hello');
});
Demo: http://jsfiddle.net/stRBU/2/

JavaScript object properties are "sometimes" undefined

I am very confused.
I created the following script which is located at http://tapmeister.com/test/dom.html. For some unknown reason, tinymce.editors.ta1 and tinymce.editors[0] show up as undefined, and attempting to use a method under them results in an error. But when I inspect tinymce or tinymce.editors using FireBug, I see them in the DOM.
So, I create a jsfiddle http://jsfiddle.net/JWyWM/ to show the people on stackoverflow. But when I test it out, tinymce.editors.ta1 and tinymce.editors[0] are no longer undefined, and the methods work without error.
What is going on??? Maybe something to do with public/protected/private properties? How do I access methods such as tinymce.editors.ta1.hide()? Thank you!!!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Testing</title>
<script src="http://tinymce.cachefly.net/4.0/tinymce.min.js"></script>
<script type="text/javascript">
tinymce.init({selector: "textarea#ta1"});
tinymce.init({selector: "textarea#ta2"});
console.log(tinymce);
console.log(tinymce.editors);
console.log(tinymce.editors.ta1);
console.log(tinymce.editors[0]);
//tinymce.editors.ta1.hide();
//alert('pause');
//tinymce.editors.ta1.show();
</script>
</head>
<body>
<form>
<textarea id="ta1"></textarea>
<textarea id="ta2"></textarea>
</form>
</body>
</html>
TinyMCE doesn't do all of the setup work immediately when you call init. It provides a callback, setup, to tell you when the work is done.
So if you provide a setup callback, you can interact with the editor instance then.
Here's an example (I've also moved your scripts to the end, which is best practice regardless):
Live Example | Live Source
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Testing</title>
</head>
<body>
<form>
<textarea id="ta1"></textarea>
<textarea id="ta2"></textarea>
</form>
<script src="http://tinymce.cachefly.net/4.0/tinymce.min.js"></script>
<script type="text/javascript">
tinymce.init({
selector: "#ta1, #ta2",
setup: function(e) {
console.log("Editor " + e.id + " is ready");
}
});
</script>
</body>
</html>
Now, if you want to actually access the editor instance, bizarrely TinyMCE doesn't add it to tinymce.editors until after calling the setup function. But if you throw in a brief yield, you're all set. Here's the above with a changed setup function:
Live Copy | Live Source
setup: function(e) {
// Bizarrely, TinyMCE calls `setup` *before* adding
// the relevant editor to `tinymce.editors`,
// so we have to yield briefly
console.log("Editor " + e.id + " is ready");
if (e.id === "ta2") {
console.log("It's ta2, I'll hide it in a moment.");
setTimeout(function() {
tinymce.editors[e.id].hide();
}, 0);
}
}
So why did it work on jsFiddle? Well, jsFiddle has a truly brain dead surprising default setting, which is to put all of your script in a window#load callback function. window#load happens very late in the load process, after all external resources have been loaded. (You can see that in the jsFiddle UI, it's the second drop-down list on the left.) So apparently TinyMCE was completely ready at that point, where it isn't earlier in the cycle.
Side note: 99.9% of the time, there is absolutely no point in supplying a tag name with an id selector, e.g. textarea#ta1. id values are unique, so you don't have to qualify them unless you explicitly want to avoid matching an element that may sometimes have one tag name, or other times have another, which is a pretty unusual use case.
There's a large chance that your script is running before tinyMCE has actually loaded. It might be the case that it loads faster from your test site so that is why it works.
Use as a quick check.

Why document.ready waits?

I know that Document.ready - DONt wait for images to download.
So why it does here ?
http://jsbin.com/ehuke4/27/edit#source
(after each test - change the v=xxx in the img SRC)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
alert('0');
});
</script>
</head>
<body >
<img src='http://musically.com/blog/wp-content/uploads/2011/04/Google-Logo.jpg?v=42333' />
</body>
</html>
I think, the problem comes out from JSBin.com
Because, when you try this example on JSFiddle.net, it works properly
http://jsfiddle.net/vqte9/
It has to do with the fact that you're using "alert()", I think, though I'm not 100% sure why. If you change your code like this:
<body>
<div id='x'></div>
<img ...>
</body>
<script>
$(function() { $('#x').text("hello there"); });
</script>
you'll see that the text is filled in before the image loads.
edit — I don't know why this would make a difference, but I notice quite different behavior when I set up the ready handler with:
$(function() { whatever; });
and:
$(document).ready(function() { whatever; });
Now that's not supposed to be the case; the two forms are supposed to do exactly the same thing, as far as I know. However, they don't seem to. Here is a jsbin example that sets up the ready handler with the first form, and here is one that uses the second one. They behave very differently for me. I'll have to check the jQuery source to figure out how that can be true.
Here is the jQuery documentation explaining the equivalence of $(handler) and $(document).ready(handler).

jQuery Plugin Authoring: Cannot get basic example to work?

I'm trying to write a few plugins for jQuery, so as a starting point I went for the basic example shown in the documentation (here). This is the code I have, in a js file called jquery.test.js:
(function($) {
$.fn.myPlugin = function(settings) {
var config = {'foo': 'bar'};
if (settings) $.extend(config, settings);
this.each(function() {
// element-specific code here
alert('found P tag');
});
return this;
});
})(jQuery);
And here's the HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
<head>
<title>Plugin Test</title>
<script type="text/javascript" src="/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/jquery.test.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('p').myPlugin();
});
</script>
</head>
<body>
<p>asdgasdgasg</p>
</body>
</html>
I'd expect this to pop up an alert for every paragraph tag in the page. However, when I load the page, nothing happens. Firebug gives me two errors:
missing ; before statement
http://playground.darthvader.com/jquery.test.js
Line 16
$("p").myPlugin is not a function
http://playground.darthvader.com/ol.html
Line 11
I'm puzzled. Can anyone see what I've done wrong here?
EDIT: It turned out there was a typo in the jQuery docs (well caught Ghommey), from which I was copying and pasting the code. I contacted the admins at the docs site, and it's now fixed.
return this;
});
seems to be wrong - try only:
return this;
};

Categories

Resources