I am messing around with a deck of cards that I made.I have it set up so that there is a method that spits out cards by suit into a list, so if I want spades I get a <ol> of all of the spades cards. I am now trying to give each <li> element an id depending on what card it is. ace will be <li id="ace"><img src="ace_spades.gif"/></li> king will be <li id="king"><img src="king_spades.gif"/></li> for example.The list is in order from top to bottom akqj1098765432 . I tried doing this:
var card_id=["ace","king","queen","jack","ten","nine","eight","seven","six","five","four", "three","two"];
var counter=0;
while (counter<=12)
{
$(document).ready(function(){
$("li").eq(counter).attr("id", card_id[counter])
});
counter++;
}
but it doesn't work. I have not really done anything with javascript before besides simple jquery stuff. What am I getting wrong here?
Try this:
$(document).ready(function(){
var card_id = ["ace","king","queen","jack","ten","nine","eight","seven","six","five","four", "three","two"];
$.each(card_id, function(i,id){
$("li").eq(i).attr('id',id);
});
});
You should try to only have one $(document).ready() function and it's not necessary to use a while() loop.
I think you don't need to call $(document).ready() function in the while. Try this:
var card_id=["ace","king","queen","jack","ten","nine","eight","seven","six","five","four", "three","two"];
var counter=0;
while (counter<=12){
$("li").eq(counter).attr("id", card_id[counter]);
counter++;
}
You do not need the document ready function. Place your script just before </body> and after the jquery.js script. This is working for me.
Check working example at http://jsfiddle.net/H8MeG/2/
First of ID's in a webpage have to be unique. Some browsers might ignore id's of elements that have already been used. Other browsers might fail completely...
Second off. you shouldn't use .eq() like that.
You definitely shouldn't add 12 new $(document).ready() statements.
Here's a more reliable version and the example on jsfiddle
var card_id=["ace","king","queen","jack","ten","nine","eight","seven","six","five","four", "three","two"];
$("#spades li").each(function(index){
$(this).attr("class", card_id[index]);
$(this).text(card_id[index]);
});
I also added $(this).text(card_id[index]); so you see it actually works. Try to uses classes for multiple elements that share the same characteristic.
why are you messing with ids at all?
you know that the first item is the ace, the second the king, and so on.
ol.getElementsByTagName('li')[12]='deuce'
Related
Lets say I have an empty div:
<div id='myDiv'></div>
Is this:
$('#myDiv').html("<div id='mySecondDiv'></div>");
The same as:
var mySecondDiv=$("<div id='mySecondDiv'></div>");
$('#myDiv').append(mySecondDiv);
Whenever you pass a string of HTML to any of jQuery's methods, this is what happens:
A temporary element is created, let's call it x. x's innerHTML is set to the string of HTML that you've passed. Then jQuery will transfer each of the produced nodes (that is, x's childNodes) over to a newly created document fragment, which it will then cache for next time. It will then return the fragment's childNodes as a fresh DOM collection.
Note that it's actually a lot more complicated than that, as jQuery does a bunch of cross-browser checks and various other optimisations. E.g. if you pass just <div></div> to jQuery(), jQuery will take a shortcut and simply do document.createElement('div').
EDIT: To see the sheer quantity of checks that jQuery performs, have a look here, here and here.
innerHTML is generally the faster approach, although don't let that govern what you do all the time. jQuery's approach isn't quite as simple as element.innerHTML = ... -- as I mentioned, there are a bunch of checks and optimisations occurring.
The correct technique depends heavily on the situation. If you want to create a large number of identical elements, then the last thing you want to do is create a massive loop, creating a new jQuery object on every iteration. E.g. the quickest way to create 100 divs with jQuery:
jQuery(Array(101).join('<div></div>'));
There are also issues of readability and maintenance to take into account.
This:
$('<div id="' + someID + '" class="foobar">' + content + '</div>');
... is a lot harder to maintain than this:
$('<div/>', {
id: someID,
className: 'foobar',
html: content
});
They are not the same. The first one replaces the HTML without creating another jQuery object first. The second creates an additional jQuery wrapper for the second div, then appends it to the first.
One jQuery Wrapper (per example):
$("#myDiv").html('<div id="mySecondDiv"></div>');
$("#myDiv").append('<div id="mySecondDiv"></div>');
Two jQuery Wrappers (per example):
var mySecondDiv=$('<div id="mySecondDiv"></div>');
$('#myDiv').html(mySecondDiv);
var mySecondDiv=$('<div id="mySecondDiv"></div>');
$('#myDiv').append(mySecondDiv);
You have a few different use cases going on. If you want to replace the content, .html is a great call since its the equivalent of innerHTML = "...". However, if you just want to append content, the extra $() wrapper set is unneeded.
Only use two wrappers if you need to manipulate the added div later on. Even in that case, you still might only need to use one:
var mySecondDiv = $("<div id='mySecondDiv'></div>").appendTo("#myDiv");
// other code here
mySecondDiv.hide();
if by .add you mean .append, then the result is the same if #myDiv is empty.
is the performance the same? dont know.
.html(x) ends up doing the same thing as .empty().append(x)
Well, .html() uses .innerHTML which is faster than DOM creation.
.html() will replace everything.
.append() will just append at the end.
You can get the second method to achieve the same effect by:
var mySecondDiv = $('<div></div>');
$(mySecondDiv).find('div').attr('id', 'mySecondDiv');
$('#myDiv').append(mySecondDiv);
Luca mentioned that html() just inserts hte HTML which results in faster performance.
In some occassions though, you would opt for the second option, consider:
// Clumsy string concat, error prone
$('#myDiv').html("<div style='width:'" + myWidth + "'px'>Lorem ipsum</div>");
// Isn't this a lot cleaner? (though longer)
var newDiv = $('<div></div>');
$(newDiv).find('div').css('width', myWidth);
$('#myDiv').append(newDiv);
Other than the given answers, in the case that you have something like this:
<div id="test">
<input type="file" name="file0" onchange="changed()">
</div>
<script type="text/javascript">
var isAllowed = true;
function changed()
{
if (isAllowed)
{
var tmpHTML = $('#test').html();
tmpHTML += "<input type=\"file\" name=\"file1\" onchange=\"changed()\">";
$('#test').html(tmpHTML);
isAllowed = false;
}
}
</script>
meaning that you want to automatically add one more file upload if any files were uploaded, the mentioned code will not work, because after the file is uploaded, the first file-upload element will be recreated and therefore the uploaded file will be wiped from it. You should use .append() instead:
function changed()
{
if (isAllowed)
{
var tmpHTML = "<input type=\"file\" name=\"file1\" onchange=\"changed()\">";
$('#test').append(tmpHTML);
isAllowed = false;
}
}
This has happened to me . Jquery version : 3.3.
If you are looping through a list of objects, and want to add each object as a child of some parent dom element, then .html and .append will behave very different. .html will end up adding only the last object to the parent element, whereas .append will add all the list objects as children of the parent element.
I am programming a WebExtension for Facebook which will invoke CSS based on their privacy settings.
$(document).ready(function(){
$("a[data-tooltip-content*='Public']").closest(".userContentWrapper._5pcr").css({"background-color": "yellow"});
$("a[data-tooltip-content*='Only Me']").closest(".userContentWrapper._5pcr").css({"background-color": "lime"});
$("a[data-tooltip-content*='friends']").closest(".userContentWrapper._5pcr").css({"background-color": "cyan"});
$("a[data-tooltip-content*='Public']").closest("._2tdc").css({"background-color": "yellow"});
$("a[data-tooltip-content*='Only Me']").closest("._2tdc").css({"background-color": "lime"});
$("a[data-tooltip-content*='friends']").closest("._2tdc").css({"background-color": "cyan"});
However, I noticed that a different page layout are has a different class value that I need to invoke with CSS codes.
Is there any way to write a for loop inside a jQuery selector?
$("a[data-tooltip-content*='Public']").closest("**For(a list of class name), loop through all of them)**").css({"background-color": "yellow"});
I have tried using $.each jQuery, but I really don't have much of an idea after reading through the documents.
var obj = {".userContentWrapper._5pcr" , "._2dc"};
$.each(obj, function(index,element)){
$("a[data-tooltip-content]").closest(obj).css({"background-color": "violet"});
$("a[data-tooltip-content*='Public']").closest(obj).css({"background-color": "yellow"});
$("a[data-tooltip-content*='Only Me']").closest(obj).css({"background-color": "lime"});
$("a[data-tooltip-content*='friends']").closest(obj).css({"background-color": "cyan"});
}
Sample result (original image link):
This should be as easy as storing all the class names in an array, and using a loop
var classses = ['.class1','.class2'];
for(var i=0;i<classes.length;i++)
$("a[data-tooltip-content*='Public']").closest(classes[i]).css({"background-color": "yellow"});
However, in general, multiple selectors can be separated with commas so this may also work.
$("a[data-tooltip-content*='Public']").closest('.class1, .class2')
.css({"background-color": "yellow"});
You almost did it yourself
$("a[data-tooltip-content*='Public']").closest(".class1, .class2, .class3").css({"background-color": "yellow"});
I'm pretty new to javascript/jquery and I just built a simple slide menu.
It has 3 menus and each menu has a submenu...everything is working fine, I just want to know if there's a better way to accomplish the same task.
Here's my js code:
function menuOpen(menu){
if(menu=='menu1'){
$("#sub2").slideUp(400);
$("#sub3").slideUp(400);
$("#sub1").slideToggle(400);
}else if(menu=='menu2'){
$("#sub1").slideUp(400);
$("#sub3").slideUp(400);
$("#sub2").slideToggle(400);
}else if(menu=='menu3'){
$("#sub1").slideUp(400);
$("#sub2").slideUp(400);
$("#sub3").slideToggle(300);
}
}
without seeing your HTML:
LIVE DEMO
function menuOpen(menu){
var num = menu.match( /\d+/ ); // Regex expression to retrieve the Number
$('[id^=sub]').slideUp(); // slide UP all ID starting with sub
$('#sub'+num).slideToggle(); // get the desired ID :)
}
Use of jQuery means that we want to easily manipulate DOM elements , which means that without seeing a HTML sample of your DOM nodes and structure you're about to target it's hard to make the above even simpler.
I'm making a web-based quiz.
When I press an answer I want the count at the top to change to the next, however it keeps skipping one digit, jumping to the next (e.i. from I to III, instead of I to III).
What am I doing wrong?
Site: http://www.carlpapworth.com/friday-quiz/#
Html:
<ul id="count">
<li><h4>I</h4></li>
<li><h4>II</h4></li>
<li><h4>III</h4></li>
<li><h4>IV</h4></li>
<li><h4>V</h4></li>
<li><h4>VI</h4></li>
<li><h4>VII</h4></li>
<li><h4>VIII</h4></li>
<li><h4>IX</h4></li>
<li><h4>X</h4></li>
</ul>
JS:
$('#count li:first').addClass('cCurrent');
$('.qAnswers li a').click(qNext);
function qNext(){
$('.cCurrent').next('#count li').addClass('cCurrent');
$('.cCurrent:first').removeClass('cCurrent');
}
The js/custom.js script is mentioned twice in the <head>. You should remove one of them, otherwise the click events are registered twice.
Furthermore, the expression inside .next() looks somewhat odd (you don't need the #count in there and maybe not even li) and the function itself can be simplified to this:
function qNext()
{
$('#count .cCurrent')
.removeClass('cCurrent')
.next('li')
.addClass('cCurrent');
}
It removes the class of the currently highlighted <li>, then moves to the next <li> and applies the cCurrent class there.
Lastly, you shouldn't give your answers a class that gives away that the answer is correct or wrong. Your answers had something like this:
xxx
xxx
If someone would look at the source, it would be very obvious what to click.
I don't see anything wrong in your javascript, but your HTML page includes the same script twice. If the click event is registered twice, it probably causes your issue.
<script type="text/javascript" src='js/custom.js'></script>
<script type="text/javascript" src="js/jquery.easing.1.3.js"></script>
<script src='js/custom.js'></script>
I'm not that familiar with jquery specifics, but I would debug this with adding some trace, inna spirit of:
function qNext(){
// Output data on what is your current question
$('.cCurrent').next('#count li').addClass('cCurrent');
// Output something - so you know for sure that this is the line that does the double move
$('.cCurrent:first').removeClass('cCurrent');
}
And you can also try:
function qNext(){
// Output ...
$myObject = $('.cCurrent');
// Output ...
$myObject2 = $myObject.next('#count li');
// Output ...
$myObject2.addClass('cCurrent');
// Output ...
$('.cCurrent:first').removeClass('cCurrent');
}
the qnext function is working correctly
I assume the Problem is that theres also another click event, which does also slide one Question to the right, added to the answers by the slider (ulslide). Try to comment out this line and see if it works
nextButton: '.qAnswers a',
actually i have two span with ids like this date_eform and time_eform.
Now i have to get these ids.. and check if the span id starts with date_ then i have to perform some logic. and if span id starts with time_ then another action.
<span id='date_eform'></span><span id='time_eform'></span>
Please help me in this.
you need starts with selector
so
$.each('span[id^="date_"]',function(){
//your code here
});
and
$.each('span[id^="time_"]',function(){
//your code here
});
Try this:
$("span[id^='date_']").something...
$("span[id^='time_']").something-else...
This should work:
$("span[id^={word}]")
Where {word} is the word you want the element id to start with.
The following like will help:
http://api.jquery.com/attribute-starts-with-selector/
this should do it:
$('[id^="date_"]')
jQuery syntax for attribute ends with:
$('span[id$="_eform"]')
jQuery syntax for attribute starts with:
$('span[id^="_eform"]')
jQuery syntax for attribute contains:
$('span[id*="_eform"]')
From what I understand, you should need to do something like:
$('span[id$="_eform"]')
Then, with an each method, test if jQuery-object ids are date or time.
var elements = $('span[id$="_eform"]');
elements.each(function() {
if(this.id.substring(0,5)=='date') {
// handle dates
} else if(this.id.substring(0,5)=='time_') {
// handle times
}
});
You can use a variety of ways to achieve this, most of those questions are listed in the other answers.
However, if you only have 2 elements, why aren't you just accessing them directly with the ID? Maybe you want to do something to them once an action has been carried out on them? In which case all the methods listed here can't be used.
If you simply want to bind the two selectors you can just use
$('#date_eform, #time_eform')...
What you're asking for doesn't make too much sense in the context of your question. If you add more details, there may be a better way to do what you're asking for.
I suggest you use id and class for this task; it would make it clearer. Example below:
HTML:
<span id='date' class='eform'></span>
<span id='time' class='eform'></span>
JavaScript (using jQuery):
$(".eform").each(function() {
switch (this.id) {
case "date":
// do something
break;
case "time":
// do something
break;
default:
// "id" is not a case
}
});
Example here: http://fiddle.jshell.net/9hcfx/