Add a Class to an existing div element - javascript

I want to display an icon for the my account section right next to the cart icon (Woocommerce).
In order to do that I would like to add another class with the name "et-account-info" to an existing div id element. The HTML-code looks like this:
<div id="et-top-navigation">
<nav id="top-menu-nav">…</nav>
…
<div id="et_mobile_nav_menu"></div>
</div>
Eventually it should look something like this. The new class should be displayed right below the first a tag.
<div id="et-top-navigation">
<nav id="top-menu-nav">…</nav>
…
…
<div id="et_mobile_nav_menu"></div>
</div>
I tried using a Javascript function which did not work at all:
<script>
var element = document.getElementById("et-top-navigation");
element.classList.add("et-account-info");
</script>
Any ideas why this is not working? Or is there a smoother way using php?

I assume you are adding the script in the <head></head> tag. Unfortunatly scripts added like this will run before the rest of the document has been loaded/parsed. You need to tell your code to wait for the DOM to be fully loaded and parsed before checking for the element.
function addClassToElement() {
var element = document.getElementById("et-top-navigation");
element.classList.add("et-account-info");
}
// Check if document is already loaded. If so, run the function.
// Otherwise, wait for the DOMContentLoaded event to fire before running it.
if (document.readyState === "complete" || document.readyState === "interactive") {
addClassToElement();
} else {
document.addEventListener("DOMContentLoaded", addClassToElement);
}
However, your code is incomplete according to the outcome you are looking for. This will just add a class to the div element with ID et-top-navigation.
Have a go at adding (hint: appending) the new element you are looking to add.

Related

Moving inline javascript function to external file and convert to jQuery

I am trying to optimize my "spoiler" bbcode on phpBB3.
Right now, I have a working solution, but the inline javascript is injected by phpBB every time the "spoiler" bbcode tag is used. I want to call a common function instead of adding it inline every time the bbcode is used.
Here is that working inline javascript:
<div class="spoiler">
<div class="spoiler-title">
<span onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.parentNode.getElementsByTagName('a')[0].innerText = 'hide'; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.parentNode.getElementsByTagName('a')[0].innerText = 'show'; }">
<strong>{TEXT1}</strong> (show)
</span>
</div>
<div class="spoiler-text">
<div style="display: none;">
{TEXT2}
</div>
</div>
</div>
For ease of reading, the inline onclick function is repeated here:
if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') {
this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = '';
this.parentNode.getElementsByTagName('a')[0].innerText = 'hide';
} else {
this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none';
this.parentNode.getElementsByTagName('a')[0].innerText = 'show';
}
Clicking the anchor with the class of "spoiler-btn" has a preventDefaults on it, to prevent the click from taking you to the top of the page:
$(document).ready(function(){
$(".spoiler-btn").click(
function(e) {
e.preventDefault();
}
);
});
I was trying to replace the span onclick inline javascript with a function call that passes 'this' to an external javascript file. I couldn't seem to get that working, so I tried using jQuery to capture 'this' to traverse up the DOM to find the "div" contained within the "spoiler-text" div and manipulate the display:none. There can be multiple of these spoiler tags on the page, so I cannot give the div inside of the "spoiler-text" div an id.
Here I changed the onclick of the span to the external function:
onclick="spoilerToggle(this);"
I then have the following in my external file:
var spoilerToggle = function(param) {
if ($(this).parent('div').parent('div').hasClass('spoiler-text').css('style') == 'none') {
($(this).parent('div').parent('div').hasClass('spoiler-text').removeAttr('style'));
($(this).parent('div').$('a').text('hide'));
} else {
($(this).parent('div').parent('div').hasClass('spoiler-text').css('display', 'none'));
($(this).parent('div').$('a').text('show'));
}
}
The console then gives the following error:
bbcode.js:22 Uncaught TypeError: $(...).parent(...).parent(...).hasClass(...).css is not a function
Line 22 is the line with the "if" check.
jQuery is loaded on the site, and I've made sure to call my external javascript file right before the close of the body tag.
I feel like I've gone down the rabbit hole and cannot see the light. I'm sure this is much easier than I am making it out to be.
Any help is greatly appreciated. Thank you!
.hasClass() returns a boolean, so you can't chain other methods after it. That's why you get the error you quote.
I would implement it a different way though:
$(document).on("click", ".spoiler-title", function(e) {
e.preventDefault();
var container = $(this).closest(".spoiler");
container.find(".spoiler-btn").text(function(i, currentText) {
return currentText === "show" ? "hide" : "show"
});
container.find(".spoiler-text div").toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="spoiler">
<div class="spoiler-title">
<span>
<strong>{TEXT1}</strong> (show)
</span>
</div>
<div class="spoiler-text">
<div style="display: none;">
{TEXT2}
</div>
</div>
</div>
The above uses a single, delegated click handler bound to the document to handle clicks on all spoiler elements on the page (you could instead bind it to a lower-level container element, at whatever the lowest level is that contains all the spoilers).
Within the handler, this will refer to the clicked element, so with DOM navigation methods such as .closest() and .find() you can go up to the containing div and then down to the elements you want to manipulate. .closest() is more flexible than trying to chain .parent().parent(), because it will automatically go up until it finds an element matching the specified selector, so if you later change your HTML structure the JS probably won't need to change.
If the .text() call looks confusing, what happens there is jQuery calls the function I passed to .text() as an argument, passing it the current value of the element's text and then whatever value is returned becomes the new text.

Click all links on page containing string?

I'm trying to add a function to a toolbar Chrome extension I've made. What I'd like it to do is once a navigate to a particular page I'd like be able to push a button on the tool bar and have it "click" all of the links on that page containing harvest.game?user=123456 with 123456 being a different number for all of the links. It could be using jquery or javascript. The only catch is that the script will need to be inserted as an element to the head of the page as cross domain scripting is not allowed so no external references to a js file. I can handle the adding of the element but, I'm having no luck figuring out the actual function.
The elements containing the links all look like this:
<div class="friendWrap linkPanel">
<h5>Christine...</h5>
<div class="friend-icon">
<img src="https://graph.facebook.com/100001726475148/picture"></div>
<div class="levelBlock friend-info">
<p>level</p>
<h3 class="level">8</h3></div>
Harvest
<a class="boxLink" href="profile.game?user_id=701240"><span></span></a></div>
Something like this (I know this is a mess and doesn't work)? OR maybe something BETTER using jquery?
var rlr=1;
function harvestall(){var frt,rm,r,rld,tag,rl;
var frt=1000;
r=document.getElementsByClassName("friendWrap linkPanel");
rl=r.length;
rld=rl-rlr;
if(rld>=0){tag=r[rld].getElementsByTagName('a');
if (rl>=1 {rlr++;harvestall();}
else if (rl>=1) {tag[1].onclick();do something??? ;}
}
Something like this should work
$("a[href*='harvest.game?user=']").trigger("click");
// Using jQuery, wait for DOMReady ...
$(function harvestLinks() {
// Only create regexp once ...
var reURL = /harvest.game\?user=/,
// Create a ref variable for harvest links ...
// Use 'links' later without querying the DOM again.
links = $("a").filter(
function() {
// Only click on links matching the harvest URL ...
return this.href && reURL.test(this.href);
}
).click();
});

Javascript display html if div exists

I am trying to display a table (or ul) that will contain a navigation bar on my page, but only displays the tabs that will contain jquery called divs present on the html.
Essentially, it's a single html document that contains all divs, jquery hides all divs but the first, and the nav bar will allow to navigate through each.
Now I am trying to make it easy to use for my client, so that the menu items will only exist if the div for it also exists. I've got most of it done, the only thing is actually knowing if a div exists.
I tried using this:
if(document.getElementById("page1")) {
document.write("<b>Good morning</b>");}
else
{
document.write("<b>Bad morning </b>");
}
When I place the above code within the div page1, it returns true. Is there no way to do it from the top of the page and not within the div?
Thanks!
Update:
As suggested by many, I have used the following:
$j(document).ready(function(){
//Hide the sections we don't need right away
$j("#page2").hide();
$j("#page3").hide();
$j("#page4").hide();
if ($j('#page1').length > 0) {
var page = 'Excellent Morning' ;
}
});
Then when I try to use:
document.write(page);
It displays the following instead:
[object HTMLBodyElement]
Why not use jQuery since you are already?
if ($('#page1').length > 0) {
// do stuff...
}
EDIT: As davin pointed out, your code should be evaluated after the DOM has been rendered. You can do this by placing it in a $(document).ready call:
$(document.ready(function() {
if ($('#page1').length > 0) {
// do stuff...
}
});
EDIT 2: Based on the OP's edits, a better solution would be to add a placeholder element and to set its content (like FishBasketGordo suggested). An example of this:
$(document.ready(function() {
//Hide the sections we don't need right away
$("#page2, #page3, #page4").hide();
if ($('#page1').length) {
$('#myPlaceHolder').html('<b>Good Morning</b>');
}
else
{
$('#myPlaceHolder').html('<b>Bad Morning</b>');
}
});
Somewhere else in the document...
<span id="myPlaceHolder"></span>
If you place it at the top of the page, the page1 div doesn't exist when the code runs. If you are using jQuery, place the code in a $(document).ready event. Then, you can put it where you want it within the markup. Here's an example:
$(document).ready(function() {
if (document.getElementById("page1")) {
document.write("<b>Good morning</b>");
} else {
document.write("<b>Bad morning </b>");
}
});
Although, rather than doing a document.write, I would consider having a placeholder span or div, and setting it's innerHTML property (or use jQuery's html method). I would also use CSS for my style instead of <b> tags, but that's another matter entirely.
You can use
if ($(selector).length > 0) {
// element exists
}
or you can check out this post for a more elegant solution
Is there an "exists" function for jQuery?

change the position of div tag dyanmically with javascript

I have an ASP button in a div to the right side of a page. I want to change the position to the left in the same row dynamically with onchange event of a dropdown.
I did this way:
document.getElementById('divButtonGo').style.Paddingleft="80px"
How do I do this with Javascript?
The example you have provided already is javascript. If you want to change what triggers the code to run, change where you place it.
from an onchange event, into a function in a script tag that is called by something else.
example
<input type="button" onclick="movediv()" />
<script>
function movediv(){
document.getElementById('divButtonGo').style.Paddingleft="80px"
}
</script>
There's several things wrong here. In order of increasing importance:
You're missing the closing slash from your i tag.
I don't see a "divButtonGo" in your html. If it's not there at all, obviously it won't work. If it is, include it in your code snippet.
I'm pretty sure to set the style you're going to need elem.style.paddingLeft, not elem.style.Paddingleft
Your script isn't wrapped inside <script> tags. All Javascript has to be wrapped in these tags, and, in order for that code to operate sucessfully, it's going to have to be placed after the "divButtonGo", or you'll have to wire up an onload event, like window.onload = function() { /* Bombs away! */ };
Your final result should look something like...
<div id="divButtonGo">
My Awesome Content
</div>
<script type="text/javascript">
var el = document.getElementById("divButtonGo");
el.style.paddingLeft = "30px";
</script>
Also, to note, padding wont' exactly change the position of the div, only the position of the content inside. If you want to change the position of the div, use margin-left (in JS, element.style.marginLeft, i believe)
EDIT:
I forgot you wanted it in the onchange event of a dropdown; so you'd do somethign like:
var dropdown = document.getElementById("MyDropDown");
dropdown.onchange = function() {
var el = document.getElementById("divButtonGo");
el.style.paddingLeft = "30px";
};

How to show / hide multiple elements at the same time with javascript

So, I have this between my head tags
<script type="text/javascript">
hidden_links = document.getElementsByName("javascript_needed");
for (i = 0; i < hidden_links.length; i++) {
hidden_links[i].style.display = "visible";
}
</script>
And my divs are all similar to
<div name="javascript_needed" style="display: none;">stuff</div>
the overall goal here, is to have these divs hide when javascript is disabled, and re-enable them when javascript is enabled.... but for whatever reason, my code doesn't work. I ever tried it in the webkit console, and nothing errored =\
The JavaScript is executed before the divs are in the DOM. The standard way to do something after the DOM is ready is to use jQuery's $(document).ready(function () { });, but there are other ways as well.
The oldschool way is to use <body onload="myfunction()">.
Here's a newer way (edit: put display:none into CSS):
HTML:
<p class='javascript_needed'>hello</p>​
CSS:
.javascript_needed {display:none;}
JavaScript:
​$(document).ready(function () {
$('.javascript_needed').show();
});
​
Your JS should be setting the div's display to "block" ("visible" isn't a valid value for display).
Also, from the looks of things your elements aren't in the DOM at the time the code is fired (your code doesn't see them yet). Do any of the following:
Place your code anywhere in the document body below the divs
or, use an unobtrusive strategy to fire your function on window load, a la:
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(nameOfSomeFunctionToRunOnPageLoad);
or, Use a JS framework's "ready" functionality, a la jQuery's:
$(function () {
nameOfSomeFunctionToRunOnPageLoad();
});
"visible" is not a valid value for "display". You're after "inline" or "block".
"visible" and "hidden" are valid values for the "visibility" CSS property.
Difference between display and visible:
An element that is visible still takes up space on the page. The adjacent content is not rearranged when the element is toggled between visible and hidden.
An element that is display=none will not take up any space on the page. Other display values will cause the element to take up space. For example, display=block not only displays the element, but adds line breaks before and after it.
The disadvantage of showing elements on ready is that they will only flicker in after the page has finished loading. This usually looks odd.
Here's what I usually do. In a script in the <head> of the document (which runs before the body begins to render), do this:
document.documentElement.className = "JS";
Then, any CSS selectors that descend from .JS will only match if JavaScript is enabled. Let's say you give your links a class of javascriptNeeded (a class is more appropriate than a name here). Add this to your CSS:
.javascriptNeeded{
display: none;
}
.JS .javascriptNeeded{
display: inline;
}
…and the elements will be there from the start, but only if JavaScript is enabled.

Categories