jquery div hide not working on first load - javascript

I am using remote javascripts to populate two divs on my site.
<div id="flix-inpage"></div>
<div id="ccs-inline-content"></div>
i am using the following code to display only one div if content is available on both divs. I have added this code to the bottom of the page:
$(document).ready(function(){
setTimeout(function() {
if ($("#flix-inpage #inpage_responsive").length > 0) {
$("#ccs-inline-content").hide();
} else {
$("#ccs-inline-content").show();
return false;
}
}, 2000);
});
I have specified a css class:
#ccs-inline-content{
display: none;
}
If Both DIV have same content
The problem I am having is that #ccs-inline-content is not hiding on first load. If I reload the page couple of times then #ccs-inline-content - hide() kicks in otherwise the content is visible.
I have tried different browser but same result.

i test this code , but good working . just i add .text() function in this code
$(document).ready(function(){
setTimeout(function() {
if ($("#flix-inpage").text().length <= 0 ) {
$("#ccs-inline-content").show();
} else {
$("#ccs-inline-content").hide();
}
}, 2000);
});
#ccs-inline-content{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="flix-inpage">12</div>
<div id="ccs-inline-content">ok</div>

If I understand correctly, you want #flix-inpage to be shown and #ccs-inline-content to be hidden unless #flix-inpage is empty. This would do the job:
$(document).ready(function() {
if ($("#flix-inpage").children().length) {
$("#ccs-inline-content").hide();
} else {
$("#ccs-inline-content").show();
}
});
You need to make sure the other scripts you mentioned finish before this runs, So put this somewhere after you execute the other two, at the bottom of the <body> tag.

Related

Avoid flickering when changing existing DOM elements on page load event

I have the following DOM element change function using vanilla JavaScript where I change the span element that contains some text string of the DOM with a page load event.
With the following code, the DOM elements are changed as expected. However, they still see a minimal fraction of flickering before the DOM element change for the variable desktop and mobile.
Example of the flickering scenario:
I see the tag span "Text I want to change" for a fraction of second.
I see the changed tag span "text1 changed" after the content has fully loaded.
I think this is happening because the DOM changes are applied when the DOM content of the page is fully loaded. I would like to hide the existing tag elements until the changes have been applied and then display them.
The elements structure for desktop and mobile I want to manipulate is like the following:
<span class="first-headline target-span">Text I want to change</span>
See the concept below:
var changesObj = {
"us": {
title: "text1 changed"
},
"eu": {
title: "text2 changed"
}
};
function changes() {
var webshop = changesObj[window.location.pathname.split('/')[1]];
console.log(webshop);
var changesText;
if (!webshop) {
console.log('webshop not found');
}
changesText = webshop.title;
if (document.querySelector('.target-span').innerText.length > 0) {
var desktop = document.querySelector('.target-span');
console.log(desktop);
desktop.innerText = changesText;
console.log(desktop.innerText);
console.log("applied changes for dekstop");
}
if (document.querySelector('.target-span').innerText.lenght > 0) {
var mobile = document.querySelector('.target-span');
mobile.innerText = changesText;
console.log(mobile.innerText);
console.log("applied changes for mobile");
}
}
function invokeChanges() {
document.addEventListener("DOMContentLoaded", function () {
changes();
});
}
invokeChanges();
Is there a way to initially hide the DOM element until the change to the existing element has been applied and then show it?
I was thinking of using something inline CSS rules like the following:
Set .style.visbility='hidden' and when the text content is changed to show it with .style.visbility='visble'.
But I'm not sure how this solution should be appropriately implemented in my code.
There are a few reasons as to why it's flickering, but two preventative steps you can take:
Use defer on your script tag <script defer>, as this lets the browser handle the order your scripts are run instead of DOMContentLoaded. You also get to avoid the changes wrapper function.
As suggested by this question (and your own reasoning) attach inline CSS / a CSS file to the page to set the text as invisible, then mark it as visible
If it doesn't affect the layout of your page too much, you can also opt to dynamically generate the element instead.
However, do note that regardless of any of these, these still require JS to be executed and may still have a delay. If you are able to use it, you may be interested in prerendering your webpage - from your JS code, it looks for the route name if its eu or us, which means your page is pre-renderable.
Quick & Dirty:
Place the script tag just below your span tag:
<span class="first-headline target-span">Text I want to change</span>
<script>
var changesObj = {
"us": {
title: "text1 changed"
},
"eu": {
title: "text2 changed"
}
};
function changes() {
var webshop = changesObj[window.location.pathname.split('/')[1]];
console.log(webshop);
var changesText;
if (!webshop) {
console.log('webshop not found');
}
changesText = webshop.title;
if (document.querySelector('.target-span').innerText.length > 0) {
var desktop = document.querySelector('.target-span');
console.log(desktop);
desktop.innerText = changesText;
console.log(desktop.innerText);
console.log("applied changes for dekstop");
}
if (document.querySelector('.target-span').innerText.lenght > 0) {
var mobile = document.querySelector('.target-span');
mobile.innerText = changesText;
console.log(mobile.innerText);
console.log("applied changes for mobile");
}
}
changes();
</script>
This way you avoid the asynchronous code part.
In any case you need to wait until the DOM has been loaded before you can manipulate it. Using an even listener for DOMContentLoaded would be the way to go. So, three things need to happen:
Wait for the DOM to load
Find the elements and change the text
Make the elements visible. You can either use the property visibility: hidden or display: none. Difference is that with visibility: hidden the element will still take up space. So, the choice depends on the context.
In the first example I add a timeout so that you can see what the page looks like just before the text is changed. I also styled the <p> (display: inline-block) so that you can see the size of the hidden span.
window.location.hash = "us"; // for testing on SO
var changesObj = {
"us": { title: "text1 changed" },
"eu": { title: "text2 changed" }
};
function changes(e) {
//let webshop = changesObj[window.location.pathname.split('/')[1]];
let webshop = changesObj[window.location.hash.substring(1)]; // for testing on SO
if (webshop) {
[...document.querySelectorAll('.target-span')].forEach(span => {
span.textContent = webshop.title;
span.classList.add('show');
});
}
}
document.addEventListener('DOMContentLoaded', e => {
setTimeout(changes, 1000);
});
p {
border: thin solid black;
display: inline-block;
}
.target-span {
visibility: hidden;
}
.target-span.show {
visibility: visible;
}
<p>
<span class="first-headline target-span">Text I want to change</span>
</p>
<p>
<span class="first-headline target-span">Text I want to change</span>
</p>
In the second example I combined all the code into one HTML page. Notice that the style is defined in the header. So, when the DOM is passed the CSS will be passed as well without having to load a external style-sheet (well, there are tricks for that as well, but out of scope for this answer).
<html>
<head>
<style>
p {
border: thin solid black;
}
.target-span {
visibility: hidden;
}
.target-span.show {
visibility: visible;
}
</style>
<script>
window.location.hash = "us"; // for testing on SO
var changesObj = {
"us": {title: "text1 changed"},
"eu": {title: "text2 changed"}
};
function changes(e) {
//let webshop = changesObj[window.location.pathname.split('/')[1]];
let webshop = changesObj[window.location.hash.substring(1)]; // for testing on SO
if (webshop) {
[...document.querySelectorAll('.target-span')].forEach(span => {
span.textContent = webshop.title;
span.classList.add('show');
});
}
}
document.addEventListener('DOMContentLoaded', changes);
</script>
</head>
<body>
<p>
<span class="first-headline target-span">Text I want to change</span>
</p>
<p>
<span class="first-headline target-span">Text I want to change</span>
</p>
</body>
</html>

Toggling around in a simple jQuery Function

Lets say I got this little span that I can't modify from its structure or give any surrounding elements. It is like it is. But now I want to display another Text in it and I want them to toggle between each other.
Example: First text stays for 1 seconds -> it gets faded out and the other text will be displayed -> repeat to infinity.
Is it possible to archive this with just the toggle() function? I tried around a bit but nothing really works.
$(function() {
$('#test').delay(1000).fadeOut(750, function() {
$(this).text('Some other text!').fadeIn(500);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<span id="test">This Text!</span>
You can do it like this.
Hope this will help you
setInterval(function() {
$("#test").fadeOut(750, function() {
if ($(this).text() == "This Text!") {
$(this).text("Some other text!").fadeIn(500);
} else {
$(this).text("This Text!").fadeIn(500);
}
});
}, 1500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<span id="test">This Text!</span>

jQuery Clickable Dropdown with CSS Animation issue

Please check out this fiddle: https://jsfiddle.net/willbeeler/tfm8ohmw/
HTML:
Do it! Roll me down and up again!
<ul class="roll-btns">
<li>Milk</li>
<li>Eggs and Cheese</li>
<li>Bacon and Eggs</li>
<li>Bread</li>
</ul>
jQUERY
$('.roll-btn').click(function() {
var ctrls = '.control';
if ($(ctrls).hasClass('noshow'))
{
$(ctrls).each(function() {
$(this).removeClass('noshow');
$(this).addClass('fadeInDown');
});
} else {
$(ctrls).each(function() {
$(this).removeClass('fadeInDown');
$(this).addClass('fadeOutDown');
});
}
});
This is a pretty simple thing, but I'm having trouble implementing it. Basically, the class "noshow" is a toggle for the A elements. If it does not exist, then add the CSS animation to the A element. If the CSS animation exists, add another css element to hide the A elements. I've tried delaying the "noshow" class, and other methods to no avail. This entire example works correctly with the first two clicks, but because it doesn't add the noshow class, it won't work after that. Basically, I need to add the noshow class on the second click AFTER the CSS animation gets done playing.
$('.roll-btn').click(function() {
var ctrls = '.control';
if ($(ctrls).hasClass('noshow') || $(ctrls).hasClass('fadeOutDown')) {
$(ctrls).each(function() {
$(this).removeClass('noshow');
$(this).addClass('fadeInDown');
$(this).removeClass('fadeOutDown');
});
} else {
$(ctrls).each(function() {
$(this).removeClass('fadeInDown');
$(this).addClass('fadeOutDown');
});
}
});

Disable/Enable CSS on webpage using Javascript

According to This page I was able to remove all the CSS preloaded and added on the webpage using that. I wanted to implement a button system where "onclick" = enable/disable webpage CSS even the ones pre-loaded by my web-host. I would like to eliminate the style tags to prevent lags for my website users. I prefer using the script that I have linked above unless there is another alternative that works better. Is it possible to enable CSS onclick the same button to disable? If not is it possible, can it be done with this quick? example with the preferred script below:
if (disable) {
style = "disable";
} else {
location.reload();
}
PREFERRED SCRIPT:
function removeStyles(el) {
el.removeAttribute('style');
if(el.childNodes.length > 0) {
for(var child in el.childNodes) {
/* filter element nodes only */
if(el.childNodes[child].nodeType == 1)
removeStyles(el.childNodes[child]);
}
}
}
removeStyles(document.body);
What about a different aproach?
Add initially a class to a body called 'styled' for example
<body class="styled">
use it as a main selector in your css definitions
<style>
.styled a { ... }
.styled h1 { .... }
</style>
then an example jquery script to toggle the class:
<script>
$(function() {
$('#myswitch').click(function() {
$('body').toggleClass('styled');
});
});
</script>
when class is present, the page will be styled, when absent there will be no styling.
Of coures there could be better aproach, but this is the first thing which pops up in my mind
To remove all style on an element, you could do
function removeStyles(el) {
el.style = {};
}
If you want to enable/disable the CSS on the page, then the goal is not to merely remove all the styles on the page, but you will need to save them somewhere also so they can be recalled when the user re-clicks the button. I would recommend having jQuery to help you with this, and it could be done the following way:
var style_nodes = $('link[rel="stylesheet"], style');
style_nodes.remove();
$('*').each(function(num, obj) {
var style_string = $(obj).attr("style");
if (style_string) {
$(obj).data("style-string", style_string);
$(obj).attr("style", "");
}
});
Now you've saved the stylesheets and style DOM nodes inside of style_nodes, and the actual style attribute inside of a jQuery data attribute for that specific DOM node. When you click to add the CSS back to the page, you can do the following:
$('head').append(style_nodes);
$('*').each(function(num, obj) {
if ($(obj).data("style-string"))
$(obj).attr("style", $(obj).data("style-string"));
});
Check out this JS Fiddle I put together to demonstrate it:
https://jsfiddle.net/5krLn3w1/
Uses JQuery, but I'm sure most frameworks should give you similar functionality.
HTML:
<h1>Hello World</h1>
Turn off CSS
Turn on CSS
JS:
$(document).ready(function() {
$('a#turn_off').click(function(evt) {
evt.preventDefault();
var css = $('head').find('style[type="text/css"]').add('link[rel="stylesheet"]');
$('head').data('css', css);
css.remove();
});
$('a#turn_on').click(function(evt) {
evt.preventDefault();
var css = $('head').data('css');
console.info(css);
if (css) {
$('head').append(css);
}
});
});
CSS:
body {
color: #00F;
}
h1 {
font-size: 50px;
}

hide one div when another is showing in jQuery?

I am trying to hide a div when another one is visible.
I have div 1 and div 2.
If div 2 is showing then div 1 should hide and if div 2 is not showing then div 1 should be visible/unhide.
The function would need to be function/document ready upon page load.
I've tried this but I'm not having any luck, can someone please show me how I can do this.
<script>
window.onLoad(function () {
if ($('.div2').is(":visible")) {
$(".div1").fadeOut(fast);
} else if ($('.div2').is(":hidden")) {
$('.div1').fadeIn(fast);
}
});
</script>
Add a class of hidden to each div, then toggle between that class using jQuery. By the way, window.onload is not a function, it expects a string like window.onload = function() {}. Also, put fast in quotations. I don't know if that's required, but that's how jQuery says to do it.
<div class="div1"></div>
<div class="div2 hidden"></div>
.hidden { display: none }
$(document).ready(function() {
if($(".div1").hasClass("hidden")) {
$(".div2").fadeIn("fast");
}
else if($(".div2").hasClass("hidden")) {
$(".div1").fadeIn("fast");
}
});
You should pass a string to the .fadeIn() and .fadeOut() methods.
Instead of .fadeIn(fast) it'll be .fadeIn("fast"). Same for .fadeOut().
And in general since you're already using jQuery it's better to wrap your code like this:
$(function () {
// Code goes here
});
It looks like you're using jquery selectors (a javascript library). If you're going to use jquery make sure the library is loaded properly by including it in the document header (google makes this easy by hosting it for you <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>)
With jQuery loaded you can do it like this
$(document).ready(function(){
if ($('.div1').is(":visible")) {
$('div2').hide();
}
else if ($('.div2').is(":visible")) {
$('div1').hide();
}
});
WORKING EXAMPLE: http://jsfiddle.net/HVDHC/ - just change display:none from div 2 to div 1 and click 'run' to see it alternate.
You can use setTimeout or setInterval to track if these divs exists
$(function() {
var interval = window.setInterval(function() {
if($('#div2').hasClass('showing')) {
$('#div1').fadeOut('fast');
}
if($('#div2').hasClass('hidden')) {
$('#div1').fadeIn('fast');
}
}, 100);
// when some time u don't want to track it
// window.clearInterval(interval)
})
for better performance
var div1 = $('#div1')
, div2 = $('#div2')
var interval ....
// same as pre code

Categories

Resources