Take <span> class and put in <a> attribute jquery - javascript

I have html like this.
<span class="gallery-open-item year-icon-Yes 2010">
<a href="/year/none">
</a>
</span>
I need to check using jQuery if span.gallery-open-item has year-icon-Yes class, and if so take the next (for this example is 2010) class and place it in the href attribute like this:
<a href="/year/2010"/>
All this I need in jQuery or JavaScript.
I have done some experiments but I can't take 2010 to normal javascript variable.
Any ideas?
Sorry for my English.

Here's another approach. Tested, working.
$('.gallery-open-item.year-icon-Yes').each(function(){
that = this;
var classes = $(this).attr('class').split(' ');
$.each(classes, function(i, val) {
if (val.match(/^y-/gi)) {
$('a', that).attr('href', function(){
return this.href.replace('none', val.split('-')[1]);
});
}
});
});
Assumes this markup:
<span class="gallery-open-item year-icon-Yes y-2010">
<a href="/year/none/">
Test
</a>
</span>

How about this:
$('span.gallery-open-item.year-icon-Yes > a').each(function(i, elem) {
$.each($(elem).parent().attr('class').split(' '), function(j, klass) {
// NOTE: use /^y-([\d]*)$/ if years are prefixed with y-
if (year = klass.match(/^([\d]*)$/))
$(elem).attr('href', $(elem).attr('href').replace('none', year[1]));
});
});
This would iterate over every A tag beneath your SPAN tags and fetch the classes from each parent, search these for a number and replace the "next" part.
Update: Added comments for the case you switch to prefixed years.
Update 2: Now tested and working (using Prototype usually *sigh*).

Here's one way of doing it. First, we select the span tags that have both the classes gallery-open-item and year-icon-Yes. Then, for each of them we're going to get an array of classes that the span tag has. I loop over the class names, and check for the first one that is a number. Finally, modify the a tag inside the span to set the desired url.
$(document).ready(function() {
$('span.gallery-open-item.year-icon-Yes').each(function() {
var classNames = $(this).attr('class').split(' ');
for (var i = 0; i < classNames.length; i++)
{
if (!isNaN(classNames[i]))
{
var year = classNames[i];
$(this).find('a').attr('href', '/year/'+year);
break;
}
}
});
});
Edit: Based on the comments that class names should not start with a number, it's pretty easy to make this work for class names of the form y-xxxx:
$(document).ready(function() {
$('span.gallery-open-item.year-icon-Yes').each(function() {
var classNames = $(this).attr('class').split(' ');
for (var i = 0; i < classNames.length; i++) {
var year = classNames[i].substring(2);
if (!isNaN(year)) {
$(this).find('a').attr('href', '/year/' + year);
break;
}
}
});
});

Related

Replace multiple links

I'm trying to replace multiple links but only the first one is replaced,
all the other remain the same.
function rep(){
var text = document.querySelector(".link").querySelector("a").href;
var newText = text.replace(/http:\/\/test(.*)http:\/\/main(.*)com/, 'http://google$2com');
document.querySelector(".link").querySelector("a").href = newText;
}
Any suggestions?
It's multiple a href links inside .link elements which I'm talking about.
Your mistake is in using querySelector, so document.querySelector(".link").querySelector("a") literally translates to: get me the first a inside the first .link;
Use querySelectorAll; and you can combine the two selectors:
Vanilla JS:
[].forEach.call(document.querySelectorAll('.link a'), function(a){
a.href = a.href.replace(/http:\/\/test(.*)http:\/\/main(.*)com/, 'http://google$2com');
});
Or, since you'll select items more often, a little utility:
function $$(selector, ctx){
return Array.from((ctx && typeof ctx === "object" ? ctx: document).querySelectorAll(selector));
}
$$('.link a').forEach(function(a){
a.href = a.href.replace(/http:\/\/test(.*)http:\/\/main(.*)com/, 'http://google$2com');
})
Or in jQuery:
$('.link a').each(function(){
this.href = this.href.replace(/http:\/\/test(.*)http:\/\/main(.*)com/, 'http://google$2com');
});
This doesn't use JQuery, and I've changed your regular expression to something that made more sense for the example. It also works when you run the snippet.
function rep() {
var anchors = document.querySelectorAll(".link a");
for (var j = 0; j < anchors.length; ++j) {
var anchor = anchors[j];
anchor.href = anchor.href.replace(/http:\/\/test(.*)com/, 'http://google$1com');
}
}
rep();
a[href]:after {
content: " (" attr(href)")"
}
<div class="link">
What kind of link is this?
<br/>
And what kind of link is this?
<br/>
</div>
<div class="link">
What kind of link is this?
<br/>
And what kind of link is this?
<br/>
</div>
Edit: Expanded example showing multiple anchor hrefs replaced inside multiple link classed objects.
Edit2: Thomas example is a more advanced example, and is more technically correct in using querySelectorAll(".link a"); it will grab anchors in descendants, not just children. Edited mine to follow suite.
If you intend to only select direct children of link class elements, use ".link>a" instead of ".link a" for the selector.
Try using a foreach loop for every ".link" element. It seems that
every ".link" element have at least 1 anchor inside, maybe just one.
Supposing every .link element has 1 anchor just inside, something like
this should do:
$('.link').each(function(){
// take the A element of the current ".link" element iterated
var anchor = $(this).find('a');
// take the current href attribute of the anchor
var the_anchor_href = anchor.attr('href');
// replace that text and achieve the new href (just copied your part)
var new_href = the_anchor_href.replace(/http:\/\/test(.*)http:\/\/main(.*)com/,'http://google$2com');
// set the new href attribute to the anchor
anchor.attr('href', new_href);
});
I did't test it but it should move you to the way. Consider that we
could resume this in 3 lines.
Cheers
EDIT
I give the last try, looking at your DOM of the updated question and using plain javascript (not tested):
var links = document.getElementsByClassName('link');
var anchors = [];
for (var li in links) {
anchors = li.getElementsByTagName('A');
for(var a in anchors){
a.href = a.href.replace(/http:\/\/test(.*)com/, 'http://google$1com');
}
}
I suggest to read the following post comment for some cooler methods of looping/making stuff foreach item.
How to change the href for a hyperlink using jQuery

Trying to remove element based on type of attribute

I am trying to remove an element based on type of attribute. It isn't working for some reason.
The element in question is this:
<p style="width:250px;font-size:11px;text-align:left;margin-left:1.2ex;margin-top:0px;margin-bottom:0px;line-height:1.15em;">– in Europe<span style="font-size:8px;"><span style="white-space:nowrap;"> </span></span>(<span style="font-size:9px;">green & dark grey</span>)<br>
– in the European Union<span style="font-size:8px;"><span style="white-space:nowrap;"> </span></span>(<span style="font-size:9px;">green</span>)</p>
I am trying to remove it this way - item is a container element.
$(item).find("p").filter("[style]").remove();
There are no other <p> tags with the attribute style, however this doesn't appear to remove it.
Other code, like this, works fine:
$(item).find(".reference").remove();
How do I remove all p tags with the style attribute from the item element?
This is how item is created:
$.get(link, function(response) {
var elements = $.parseHTML(response);
var wiki = $(elements).find('#mw-content-text').find("p");
//var ps = [];
var arrayLength = wiki.length;
for (var i = 0; i < arrayLength; i++) {
if (wiki[i].innerHTML === "") {
break;
}
var item = wiki[i];
The link variable is a link to wikipedia.
Maybe try this:
$.each(item.children('p'), function(index) {
if ($(this).attr('style')) {
$(this).remove();
}
});
item refers to p element itself. you don't have to find p in item:
$(item).filter("[style]").remove();
after re-looking over your question ,
$(item).find("p").filter("[style]").remove();
is perfectly valid , instead of trying to come up with alternative ways to write it , find out what is wrong with item, because it is not what you think it is if above code is not working

Access dynamic generated div id

I have some div ids that are generated dynamicly via php
<div id='a<?php echo $gid?>>
How can I access them in JavaScript? All these divs start with "A" followed by a number.
Is there some kind of search function
getElementById(a*)?
Thanks for any help
No generic JavaScript function for this (at least not something cross browser), but you can use the .getElementsByTagName and iterate the result:
var arrDivs = document.getElementsByTagName("div");
for (var i = 0; i < arrDivs.length; i++) {
var oDiv = arrDivs[i];
if (oDiv.id && oDiv.id.substr(0, 1) == "a") {
//found a matching div!
}
}
This is the most low level you can get so you won't have to worry about old browsers, new browsers or future browsers.
To wrap this into a neater function, you can have:
function GetElementsStartingWith(tagName, subString) {
var elements = document.getElementsByTagName(tagName);
var result = [];
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.id && element.id.substr(0, subString.length) == subString) {
result.push(element);
}
}
return result;
}
The usage example would be:
window.onload = function() {
var arrDivs = GetElementsStartingWith("div", "a");
for (var i = 0; i < arrDivs.length; i++) {
arrDivs[i].style.backgroundColor = "red";
}
};
Live test case.
In case you choose to use jQuery at some point (not worth for this thing alone) all the above code turns to single line:
$(document).ready(function() {
$('div[id^="a"]').css("background-color", "blue");
});
Updated fiddle, with jQuery.
No, you need a fixed id value for getElementById to work. However, there are other ways to search the DOM for elements (e.g. by CSS classes).
You can use querySelectorAll to get all divs that have an ID starting with a. Then check each one to see if it contains a number.
var aDivs = document.querySelectorAll('div[id^="a"]');
for(var index = 0, len = aDivs.length; index < len; index++){
var aDiv = aDivs[index];
if(aDiv.id.match(/a\d+/)){
// aDiv is a matching div
}
}​
DEMO: http://jsfiddle.net/NTICompass/VaTMe/2/
Well, I question myself why you would need to select/get an element, that has a random ID. I would assume, you want to do something with every div that has a random ID (like arranging or resizing them).
In that case -> give your elements a class like "myGeneratedDivs" with the random ID (if you need it for something).
And then select all with javascript
var filteredResults=document.querySelectorAll(".myGeneratedDivs").filter(function(elem){
....
return true;
});
or use jQuery/Zepto/YourWeaponOfChoice
var filteredResults=$(".myGeneratedDivs").filter(function(index){
var elem=this;
....
return true;
});
If you plan to use jQuery, you can use following jQuery selectors
div[id^="a"]
or
$('div[id^="id"]').each(function(){
// your stuff here
});
You will have to target the parent div and when someone click on child div inside a parent div then you can catch the child div.
<div id="target">
<div id="tag1" >tag1</div>
<div id="tag1" >tag2</div>
<div id="tag1" >tag3</div>
</div>
$("#target").on("click", "div", function() {
var showid = $(this).attr('id');
alert(showid)
});
getElementById() will return the exact element specified. There are many javascript frameworks including jQuery that allow much more powerful selection capabilities. eg:
Select an element by id: $("#theId")
Select a group of elements by class: $(".class")
Select subelements: $("ul a.action")
For your specific problem you could easily construct the appropriate selector.

Select by next instance of class with jQuery

I'm looking to convert a function that selects by id to select the next instance of a given class.
Here is the code.
function swap3(oldDivId, newDivId) {
var oldDiv = document.getElementById(oldDivId);
var newDiv = document.getElementById(newDivId);
oldDiv.style.display = "none";
newDiv.style.display = "block";
}
Suppose you have this HTML:
<div id="test"></div>
<img>
<br>
<div></div>
<input>
<div class="abc">Found it</div>
<div class="cdf"></div>
Updated at 2021
The original answer is quite old now. Since the original question have the jQuery tag, the answer keeps valid and usable. But for those coming here with the hope to see an updated JavaScript code with no dependency on jQuery, take a look on how querySelector is a awesome nowadays:
const next = document.querySelector('#test ~ .abc')
next.textContent = 'Yeah, you found it!'
So the secret is to use the general sibling combinator that matches all iterations of the second element, but with querySelector that returns only the first match.
Original answer
So you select the first div by id:
var some = $("#test");
Then you want to find the next div with the class abc:
var next = some.nextAll("div.abc");
Suppose you want a variable as the className:
var x = "abc";
var next = some.nextAll("div." + x);
If I understand your question:
function nextItem(className) {
return $('#ID').closest('.' + className);
}
using closest: http://api.jquery.com/closest/
Select by ID in jQuery:
$('#class_name')
Select by class in jQuery:
$('.class_name')
Get the next item in jQuery:
$('.class_name').next('.class_name')
Using this, you can do something like
// Something to remember the current element
var currentElement = false;
function getNext(className)
{
// First time, there will be no current element
if (!currentElement)
{
currentElement = $('.' + className);
return currentElement;
}
// Other times...
currentElement = $(currentElement).next('.' + className);
return currentElement;

Javascript - Link Name Changing with restrictions

I'm trying to change the name of a link, however, I have some restrictions. The link is placed in code that looks like this:
<li class='time'>
Review Time
<img alt="Styled" src="blah" />
</li>
Basically, I have a class name to work with. I'm not allowed to edit anything in these lines, and I only have a header/footer to write Javascript / CSS in. I'm trying to get Review Time to show up as Time Review, for example.
I know that I can hide it by using .time{ display: hide} in CSS, but I can't figure out a way to replace the text. The text is also a link, as shown. I've tried a variety of replace functions and such in JS, but I'm either doing it wrong, or it doesn't work.
Any help would be appreciated.
You could get the child elements of the li that has the class name you are looking for, and then change the innerHTML of the anchor tags that you find.
For example:
var elements = document.getElementsByClassName("time")[0].getElementsByTagName("a");
for(var i = 0, j = elements.length; i<j; i++){
elements[i].innerHTML = "Time Review";
}
Of course, this assumes that there is one element named "time" on the page. You would also need to be careful about checking for nulls.
Split the words on space, reverse the order, put back together.
var j = $('li.time > a');
var t = j.text();
var a = t.split(' ');
var r = a.reverse();
j.text(r.join(' '));
This could have some nasty consequences in a multilingual situation.
Old school JavaScript:
function replaceLinkText(className, newContents) {
var items = document.getElementsByTagName('LI');
for (var i=0; i<items.length; i++) {
if (items[i].className == className) {
var a = items[i].getElementsByTagName('A');
if (a[0]) a[0].innerHTML = newContents;
}
}
}
replaceLinkText("time", "Review Time");
Note that modern browsers support getElementsByClassName(), which could simplify things a bit.
You can traverse the DOM and modify the Text with the following JavaScript:
var li = document.getElementsByClassName('time');
for (var i = 0; i < li.length; i++) {
li[i].getElementsByTagName('a')[0].innerText = 'new text';
}
Demo: http://jsfiddle.net/KFA58/

Categories