JavaScript - wrap contents within a DIV, if a condition is met - javascript

I have a fairly complicated problem.
The usual markup (no problems here):
<div class="wrapper">
<div class="title"> bla bla... </div>
<div class="content"> ...content... </div>
</div>
The "twisted" markup:
<div class="wrapper">
...content... </div>
</div>
As you can see the opening tag for div.content is missing. Unfortunately I have no control over the output within .wrapper :(
So, my question is: how can I detect if div.title is present, and if not - insert <div class="content"> (not the .title) after div.wrapper ?
I'm aware how to do this with jQuery, but I need a pure javascript solution because with jQuery you get a small "delay" before the layout gets fixed. Any ideas?

There is a fair bit more code without jQuery.
var divs = document.getElementsByTagName('div'),
foundTitleDiv = false;
for (var i = 0, divsLength = divs.length; i < divsLength; i++) {
if (divs[i].className.match(/\btitle\b/)) {
foundTitleDiv = true;
break;
}
}
if (foundTitleDiv) {
var wrapper = document.createElement('div');
wrapper.className = 'content';
var div = divs[i];
wrapper.appendChild(div.cloneNode(true));
div.parentNode.replaceChild(wrapper, div);
}
It works!
Place this at the bottom of your script, or you can wait for the entire window loaded with window.onload = function() { } or research onDOMReady events.
Whilst this answers your question, the fact you have invalid HTML (the extraneous </div>) may make this solution invalid.

Well, JQuery is pure Javascript, but with JQuery there's a lot more Javascript for the browser to parse, that might be why you are experiencing some delay. I don't know exactly how you would go about fixing this with Javascript, because you are outputting invalid HTML. which will be interpretted differently by different browsers. The correct thing to do would be to output proper HTML by the use of server side code such as PHP, or ASP.

Perhaps you can fix it on the server before sending it by searching for and, if it is missing, add it. If you can't fix it on the server, then you can do it with inline javascript, but you will need to add the content as a javascript variable, parse it, then write it out.
Here's an example (FYI, I know the RegEx is wrong, but figured it got the point across ok).
<div class="wrapper">
<div class="title"> bla bla... </div>
<script type="text\javascript">
var content = "<div class="content"> ...content..."
if (!content.match(/<div class="content">/))
content = "<div class="content">" + content;
document.Write(content)
</script>
</div>
</div>

Related

Possible to override classes with specific element?

CSS newbie here wondering if this is possible. If I have something like the code below, is it possible to override just the section that has the class itemtile AND data-id of ABC123? My goal is to hide that entire section from being displayed. I've reviewed some past comments about specifity but when it comes to wanting both values to exist I get a bit lost. I'm mucking with trying to override code for a site that is not mine using a personal plugin.
<div id="itemgrid" class="section">
<div class="itemtile" data-id="ABC123">
<div class="itemcontent"></div>
</div>
<div class="itemtile" data-id="DEF123">
<div class="itemcontent"></div>
</div>
</div>
I did some code examination in the debugger and can make the page do what I want by removing the div element for the data-id's I want to hide just not sure how to do it in CSS. I'm not asking for help on creating the plugin just if and how I can address an element that specifically.
You can accomplish this with JavaScript
let class = document.getElementsByClassName("itemtile");
for(let i = 0; i < class.length; i++){
if(class[i].dataset.id == 'ABC123'){
class[i].style.display = "none";
break;
}
}
Alternatively, if you want to do this using CSS, you can do it like so:
.itemtile[data-id='ABC123'] {
display: none;
}
That should do it!
You can override easily by adding style="" after your div
for example
<div style="" id="itemgrid" class="section">

jQuery in Wordpress - Hide parent div if it contains a specific other div

I'm trying to hide a slick slider section if it has no slides. I've tried tons of different options, like trying to use PHP and CSS, but I feel I'm closest to getting it to work with jQuery.
The HTML output structure is:
<div class="container-flex type-testimonials-container">
<div class="container">
<div class="container type-testimonials slick-initialized slick-slider">
<div class="slick-list draggable">
<div class="slick-track">
<div class="slick-slide">
SINGLE SLIDE CONTENT
</div>
<div class="slick-slide">
SINGLE SLIDE CONTENT
</div>
<div class="slick-slide">
SINGLE SLIDE CONTENT
</div>
</div>
</div>
</div>
</div>
</div>
So, I'm thinking I can use jQuery to hide the containing div (.type-testimonials-container) if the single slide div (.slick-slide) doesn't exists.
I have tried the following:
if(jQuery(".slick-slide").html().length)
{
jQuery(".type-testimonials-container").hide();
}
As well as lots of variations of that... I think it might be because the two divs aren't on the same level and one contains the other, but trying to find a parent/child way of doing is proving difficult... I'm not sure which way to go...
Any help would be massively appreciated!
EDIT*
I've also tried checking the parent and child relationship and trying to wait until the DOM has loaded, like this:
document.addEventListener("DOMContentLoaded", function(event) {
var parentDiv = document.getElementsByClassName("slick-track");
var childDiv = document.getElementsByClassName("slick-slide");
if (parentDiv.contains(childDiv))
{
alert("div DOES exist");
}
else{
alert("div DOES NOT exist");
}
});
But this just shows me the DOES NOT exist alert even though it does exist - Will this search the whole of the DOM for it? or do I need to provide the exact path of the div from body or something?
Why not just query for the length of the HTML collection of .slick-slide? JQ will still return an object if the target element doesn't exist, and the object will have a property length. Something like
if(jQuery(".slick-slide").length === 0) {
jQuery(".type-testimonials-container").hide();
}
I managed to do it this way:
jQuery(document).ready(function() {
if(jQuery('.slick-slide').length){
jQuery('.type-testimonials-container').show();
}
else
{
jQuery('.type-testimonials-container').hide();
}
});

section id not being recognised within jquery scroll function

I have a parallax scrolling website which works via section ID's. I have animations on each of the sections but only want them to activate when the section is in the viewport. I currently have the following, which doesn't seem to be working. I'm fairly new to jquery/javascript so any help would be appreciated!
function paintLine(){
$('#3-Backup-3').lazylinepainter({
"svgData": svgData,
'ease': 'easeInOutQuad',
'strokeCap': 'square'
}).lazylinepainter('paint');
}
var element_position = $('#backup-section-3').offset().top;
$(window).scroll(function() {
var y_scroll_pos = window.pageYOffset;
var scroll_pos_test = element_position;
if(_scroll_pos > scroll_pos_test) {
paintLine();
}
});
<!-- Backup 3 -->
<div data-anchor="backup-section-3" class="section backup-section-3">
<div class="float-left">
<div id="backup-nav">
<p onclick="openSideNavGreen()" class="nav-section-title">Backup</p>
</div>
<div>
<p class="backup-text-title">Methods</p>
<p class="backup-text">No surprises here then: tape as a primary backup method remains at an all-time low of 3%. This is the first year it hasn’t fallen – possibly indicative of how stubborn some legacy systems (often populated with static compliance data) can be. I wouldn’t be surprised to see similar figures next year.<br><br>We did see a drop in the prevalence of combined disk/tape solutions, with a new option, External Hard Drive/USB, seeming the preferred choice instead.</p>
</div>
</div>
<div class="float-right">
<div id="3-Backup-3"></div>
</div>
</div>
$('#backup-section-3').offset().top; refers to an element with an ID of backup-section-3 which you don't seem to have in your HTML markup. Try giving the element that you're referring to an ID of backup-section-3 and see if that resolves your issue.
id needs the start with alpha character. put any alpha char in front of the 3 in your javascript and html and it will work.

How to change static text in a web page using inner html?

I have some text in a website that I want to change using javascript because I can't change it any other way.
In short, the site is laid out like such:
...some other divs before here, body, head, etc...
<div id="header" class="container-fluid clearfix">
<div class = "hero-unit">
<h1 class="title">Support Center</h1>
...some other divs for other parts of the page...
</div>
</div>
...more divs, footer, etc...
I don't need the text to change on click or anything like that I just want it to be set on load to something different than Support Center but I'm not sure if I'm placing the script in the correct place or if the syntax is wrong?
I've tried placing it before and after and it doesn't seem to work. Here is the code:
<script type="text/javascript">
var targetDiv = document.getElementByID("header").getElementsByClassName("hero-unit")[0].getElementsByClassName("title")[0];
targetDiv.innerHTML = "Please use the Knowledge Base to find answers to the most frequently asked questions or you may submit a support ticket which will be sent to your COM email account.";
</script>
Thank you.
Looking at the actual source of your page, your page does not contain a h1 element with a class of title.
Your actual source code
<div id="header" class="container-fluid clearfix">
<div class="hero-unit"></div>
<div class="container-fluid clearfix">
<div class="row-fluid">
<div class="leftcolumn"></div>
<div class="rightcolumn"></div>
</div>
</div>
</div>
This means it does not exist till some point after your page loads. You need to put your code after the code that generates the h1 title element
In jQuery (if you can use it), you'd use something like
$("#title").text("Something else");
it looks like you are not getting the specific class to change the html
try with querySelector like i have done
JS Fiddle
var targetDiv = document.querySelector('#header > .hero-unit > h1.title')
targetDiv.innerHTML = "Please use the Knowledge Base to find answers to the most frequently asked questions or you may submit a support ticket which will be sent to your COM email account.";

Jquery .after() not inserting as expected

EDIT: Solution found How to wrap every 3 child divs with html using jquery?
I'm printing a list with a lot of <div>'s and want to insert a </div><div class="clearfix"> after every 6th <div> with jQuery.
Naturally that would be something like
$('#staffscroll .person:nth-child(5n)').after('</div><div class="clearfix">');
But the output becomes <div class="clearfix"></div> which just doesn't make sense.
Any thoughts?
Ok, maybe should provide some more code..
I'm working with a slideshowscript. The whole take is basicly to put stuff in a <div>.
For example..
<div id="slideshow">
<div class="clearfix"> First slide wrapper
<img>
<img>
<img>
<img>
</div>
<div class="clearfix"> Second slide wrapper
<img>
<img>
<img>
<img>
</div>
<div class="clearfix"> Third slide wrapper
<img>
<img>
</div>
</div>
The problem is that I'm working with a CMS aswell, which havn't got that much control over dynamic output. So my thought was that I just could output all the content, and then provide the slide-wrappers afterwards.
Therefore the </div><div class="clearfix">
Havn't got a clue if it makes any more or less sense now, but I hope you get what I'm trying to do.
The statement you try to insert isn't correct XML. You are thinking about your HTML document as a big string, but this is the wrong way to do if you want to use tools like jQuery.
I suggest you to learn more about DOM and how to use it. Your whole approach is wrong, so your sample of code isn't correctable.
IIRC, jQuery parses the string to a DOM fragment and then inserts it. When your </div><div class="clearfix"> is parsed it's assumed the </div> is an error, and it also closes the <div class="clearfix">. Therefore the effect you observed.
That's because after isn't modifying the HTML -- it's creating new DOM elements and adding them to the document. You should use wrapAll to wrap a group of elements. My guess is that your code will look something like this:
var start = 0,
$list = $('#staffscroll .person').slice(0, 6);
while ($list.length) {
$list.wrapAll('<div class="clearFix"></div>');
start += 6;
$list = $list.end().slice(start, start + 6);
}
jsFiddle working example
As I replace the .wrapAll for .append or a similiar?

Categories