Adding span to numbers using Jquery - javascript

So I have been dabbling around in jQuery a bit this week. Trying to add some cool things to a wordpress theme I am currently working on.
With the help of this wonderful site, I received the following JS to wrap a span around numbers in a certain div. All was well until I started implementing more JS to find out this is actually causing my other JS to break.
//add span to numbers
var elem = document.getElementById('passage');
elem.innerHTML = elem.innerHTML.replace(/\b(\d+)\b/g, '<span>$1</span>');
However, I was informed since I am using jQuery, to take "document.getElementById" out and end up with this:
//add span to numbers
var elem = $( 'passage' );
elem.innerHTML = elem.innerHTML.replace( /\b(\d+)\b/g, '<span>$1</span>' );
I figured this would solve the situation with no luck. Any ideas of why this isn't working? Thanks
My end result is to be able to style numbers like this site does for their Bible verses: http://marshill.com/media/the-seven/lukewarm-in-laodicea-comfort-and-convenience-before-christ#scripture

If you're selecting by the id you need the CSS-alike id selector:
var elem = $('#passage');,
To select by class:
var elems = $('.className');
Using the $('#passage') selector, you end up with a jQuery object, rather than a DOM-node, so $('#passage').innerHTML (or elem.innerHTML) returns an error: Uncaught TypeError: Cannot call method 'replace' of undefined in Chromium 19.
To work around that, you can 'drop' back to a DOM-node with:
elem.innerHTML = $('#passage')[0].innerHTML.replace(/*...*/);
Or instead use jQuery:
elem.html(function(i,oldHTML){
return oldHTML.replace( /\b(\d+)\b/g, '<span>$1</span>' );
});​
JS Fiddle demo.
References:
jQuery selectors.
html().

For the first line, when working with ids, you want to prepend the string with a pound symbol; that is, $('#passage').
For the second line, note that doing $('#passage') returns a jQuery object, so you can't use standard methods on it. You should be using jQuery methods. The equivalent for innerHTML is .html().
So you would want to do the following:
//add span to numbers
var elem = $( '#passage' );
elem.html(elem.html().replace( /\b(\d+)\b/g, '<span>$1</span>' ));
A little ugly, but it gets the job done. David's answer is slightly more eloquent.

Related

jQuery: easier way to use .clone() than described below?

If you execute in the console on this page
var cloned = $(".question").clone(true);
$(".question").addClass("first");
var clonedStr = cloned[0].outerHTML || new XMLSerializer().serializeToString(cloned[0]);
$(".question").after(clonedStr);
you will clone the question (there will be two questions on the page, but the first one will be with the .first class). That's what is needed.
Is there any simpler way to do this with jQuery? I'm confused of the third string in the code above and believe it could be simpler. Any ideas?
Thank you.
If you don't use the HTML as string, then don't get it. Just use the jQuery object:
var cloned = $(".question").clone(true);
$(".question").addClass("first").after(cloned);
Also, you can do it one line:
$(".question").after($(".question").clone(true)).first().addClass("first");
You could use insertAfter to insert the cloned element after changing the class. You don't need to convert the element in the jQuery object to a string, you can use that object within the function itself:
var $question = $('.question');
var $cloned = $question.clone(true).insertAfter($question);
$question.addClass('first');

jquery offset method doesn't always work / exist

Good morning and happy new year everyone!
I've run into a snag on something and need to figure out a solution or an alternative, and I don't know how to approach this. I actually hope it's something easy; meaning one of you all have dealt with this already.
The problem is that I'm doing rollovers that contain information. They're divs that get moved to the absolute location. Now I've tried this with jquery 1.6 - 1.9.1. Of course this has to work in multiple browsers.
What needs to happen is on rollover show a div, and when you rollout of that div, make it hide.
...
// .columnItem is class level and works
$(".columnItem").mouseleave(function() {
$(this).css("display", "none");
});
...
$(".column").mouseenter(function() {
var currentItem = $(this)[0]; // this is where the problem is
// hide all .columnItems
$(".columnItem").css("display", "none");
// i get this error: Object #<HTMLDivElement> has no method 'offset' (viewing in chrome console)
var offsetTop = currentItem.offset().top;
var columnInfoPanel = $("#column" + currentItem.innerText);
});
So the immediate thought of some would be don't use $(this)[0]. Instead, I should use $(this), and you are correct! Where the other problem comes into play is by removing the array index, currentItem.innerText is now undefined.
The only thing I can think of is I'll have to mix both, but it seems like there should be a way to use the selector and get both options.
What have you all done?
Thanks,
Kelly
Replace:
var currentItem = $(this)[0];
With:
var currentItem = $(this).eq(0);
This creates a new jQuery object containing only the first element, so offset will work.
Then you can use either currentItem[0].innerText or currentItem.text(), whichever you prefer.
Skip the [0] at the beginning as you are saying.
But then change the last line to:
var columnInfoPanel = $("#column" + currentItem[0].innerText);
De-referencing the jQuery selector gives you the DOM-object.
If you want to stick to pure jQuery, the .text() / .html() methods will give you the same functionality.

How do I display the value of a jQuery variable for testing?

I am working on a slider that uses jQuery. Some elements of the slider are working correctly, but there is a problem that I am trying to troubleshoot with some of the code. To test it I would like to be able to display the values of the variables in the statement.
Here is the code block I am working with:
$('.marquee_nav a.marquee_nav_item').click(function(){
$('.marquee_nav a.marquee_nav_item').removeClass('selected');
$(this).addClass('selected');
var navClicked = $(this).index();
var marqueeWidth = $('.marquee_container').width();
var distanceToMove = marqueeWidth * (-1);
var newPhotoPosition = (navClicked * distanceToMove) + 'px';
var newCaption = $('.marquee_panel_caption').get(navClicked);
$(' .marquee_photos').animate({left: newPhotoPosition}, 1000);
});
I added a div called 'test' where I would like to display the values of the variables to make sure they are returning expected results:
<div class="test"><p>The value is: <span></span></p></div>
For example, to test the values, I inserted this into the statement above:
$('.test span').append(marqueeWidth);
However, I don't get any results. What is the correct way to include a test inside that code block to make sure I am getting the expected results?
Thanks.
Just use JavaScript's console functions to log your variables within your browser's console.
var myVar = 123;
console.log(myVar, "Hello, world!");
If you're unsure how to open the console within your browser, see: https://webmasters.stackexchange.com/questions/8525/how-to-open-the-javascript-console-in-different-browsers
append is used to append either an HTML string, a DOM element, an array of DOM elements, or a jQuery element. Since you are just trying to show a number (marqueeWidth), you probably want to set the text of the span instead:
$('.test span').text(marqueeWidth);
Also, is there a particular reason why you don't just use the console? It may be worth reading over a Debugging JavaScript walkthrough.
you can use the following.
$('.test span').html(marqueeWidth);
However doing a console.log(yourvariable); or alert(yourvariable); is better.

More elegant/efficient way to get the 6 consecutive previous DOM elements in a row?

Assuming I have a JQuery object stored in $e obtained through this selector:
var $e = $("input[type='text'][value='" + v + "']");
v represents the $(this).val() which I obtain inside an .each() iteration but it doesn't actually matter, it can be any numeric value.
I want to create a JQuery set of elements containing $e, the DOM element which comes after it, and the 6 DOM elements previous to $e.
The function itself works perfectly fine, I'm using this code for each iteration:
var $e = $("input[type='text'][value='" + v + "']");
$e = $e.add($e.next());
for (i=0;i<6;i++)
$e = $e.add($e.prev());
$e.remove();
I guess it's a little bit hard to explain, so take a look at this JSFiddle.
I've wrapped the code above inside an anonymous function bound to the the Remove line 2 button which will pass a fixed v value to my script.
I'm a starter with JQuery and even after taking a good read at JQuery Selectors page I couldn't find a simpler way to do this. I thought that the .siblings(), or more specifically JQuery('prev ~ siblings') could do it in a simpler way if I could specify the range of the jquery objects array but I couldn't figure out how.
The HTML is generated through a PHP template which I'd rather avoid editing, so I'll accept answers which do not include wrapping the given elements inside a container/wrapper.
Is there any simpler way to select the 6 previous elements of a given JQuery selector without wrapping them inside any container or wrapper?
Try using .prevAll and slice the elements you need. See below,
DEMO
var $prevAll = $e.prevAll();
$e = $e.add($e.next()).add($prevAll.slice(0, 6));
Edit: Added $e.add($e.next()) to add next element.
You could use siblings() and slice():
var $e = $("input:text[value='" + v + "']");
$e.add( $e.siblings().slice(0, 5) ).add( $e.prev() );
I don't know that it's any better, but it's another option:
var $siblings = $e.siblings().andSelf();
var index = $siblings.index($e);
$siblings.slice(index-6,index+2).remove();
http://jsfiddle.net/Lf3xm/5/

Why this type of array wrapping does not work in jQuery?

Consider this:
var i=$('<img src="/path/to/imgI.png"/>');
var j=$('<img src="/path/to/imgJ.png"/>');
$([i,j]).css('cursor','hand');
The cursor is not changed however and I don't know why..
When I do it separately, it works.
Thanks.
The array is of two jQuery objects when what you require is the DOM elements within those jQuery objects. This will work:
var i=$('<img src="/path/to/imgI.png"/>')[0]; // <= Notice [0]
var j=$('<img src="/path/to/imgJ.png"/>')[0];
$([i,j]).css('cursor','pointer');
Alternatively, (using add())
var i=$('<img src="/path/to/imgI.png"/>');
var j=$('<img src="/path/to/imgJ.png"/>');
$(i).add(j).css('cursor','pointer');
EDIT: Also, use cursor:pointer; instead of cursor:hand;
Are you sure your problems isn't browser specific? That particular css property is tricky, it requires the property be set two different ways to work in IE and Firefox.
I'd recommend using a class in the img tag to specify the hand property. Then you can specify both rules and get what you are looking for.
Would make more sense to put selectors in the array:
var i = $('<img src="/path/to/imgI.png"/>').attr('id','i');
var j = $('<img src="/path/to/imgJ.png"/>').attr('id','j');
$( ['#i', '#j'] ).css('cursor','hand');
The correct cursor property is "pointer" not "hand", which is an IE only extension no longer required for anything but IE 5.5 and lower - i.e. very rarely.
You can use jQuery method to turn the jQuery object into a true array and then merge them.
var i=$('<img src="/path/to/imgI.png"/>');
var j=$('<img src="/path/to/imgJ.png"/>');
i = $.makeArray(i);
j = $.makeArray(j);
$( $.merge(i,j) ).css('cursor','pointer');
Btw that also works when you need to add multiple jQuery selection together,
i = $.makeArray( $('div') );
j = $.makeArray( $('a') );
$( $.merge(i,j) ); //this jQuery object holds all divs and a's
You could of course also do that like this:
$('div').add('a');

Categories

Resources