Show HTML elements on demand with JavaScript - javascript

TL;DR : I'm trying to find a way to handle HTML injections into the DOM to avoid having to include irrelevant code in the DOM at all times.
I have a large PHP application that has several forms and modals through out the pages of the application. I'm trying to find a way to lessen the DOM elements by only showing/adding elements as and when they're needed.
What I have so far looks something like this:
<body>
<!-- Page Content -->
<main>
Click to access modal
</main>
<!-- / Page Content -->
<div class="modalContainer">
<div class="modal" id="modal-login">
<!-- modal content -->
</div>
<div class="modal" id="modal-register">
<!-- modal content -->
</div>
<div class="modal" id="modal-forgotpassword">
<!-- modal content -->
</div>
</div>
</body>
In the above, when someone clicks the anchor, you'd see the appropriate modal pop-up. Once you're done with the modal, it hides away until someone needs it again.
My problem with this is that it would mean that every modal needed in the application would always be a part of the DOM regardless of whether it is needed or not.
I wanted to know if there is any way of making this process a little more dynamic? This would involve the user clicking the anchor, and the JS code injecting the Modal into the page, and when done, removing the entire modal code from the page.
I assume this would greatly improve load times and render time.
The problem is that I have been unable to understand the logic behind it, I have been doing something very similar with other parts of the project but I have not been able to apply it to the modals. Here's what I assumed would be the jQuery code for injecting the modal
$('.ismodal').click(function(event) {
event.preventDefault();
let modal = $(this).data('modal'),
elem = '#modal' + modal;
// Check if element already exists
if ($(elem).length) {
$(elem).fadeIn();
} else {
// Get element code
let elementCode = functionToGetElementCode(modal);
// Inject element
$('#modalContainer').append(elementCode);
// Fade In element
$(elem).fadeIn();
}
});
I haven't tried the above code, but I would assume something like the above should work. However, my concern is how I could code the functionToGetElementCode such that it would work, and is not terrible difficult to maintain.
I assume the easiest method would be to have the function in which we could have a switch function that would filter out the needed code. But is there a way to import the template of each modal from a folder? Something similar to the include function in PHP?

Use the <template> tag
In html there is a specific tag designed for this use, it's called <template>. You can use this tag to store your modals and then render them as needed. You're on the right track but I think there is some confusion about how loading works on the web.
JS code injecting the Modal into the page ... I assume this would greatly improve load times and render time.
When you think about load times remember the fastest thing to load is plain text. It can be extremely fast and is very very lightweight. JS, on the other hand, will need to be loaded, run, and not error out
Using AJAX (Not recommended)
If you expect the modal to be infrequently clicked, you could store it in another file and summon it via AJAX. This isn't very advantageous as it will add a network request and processing time to your modal click.

You can use AJAX calls to get the required modal.

Related

Why Twitter Timeline is not getting loaded in based on variable in Vue.js component?

I am trying to load the twitter timeline of multiple accounts based on the route. For example, if someone requests a specific page, twitter timeline for a specific account is loaded on the page.
I tried using one plugin called vue-tweet-embed but it was not working at all, So, I tried the old way. I included twitter's widgets.js in my main HTML file and tried including timeline with static code as given below.
Static Code
<a class="twitter-timeline" href="https://twitter.com/Google?ref_src=twsrc%5Etfw">Tweets by Google</a>
Now, I want to show Twitter timeline of multiple accounts based on the variable. My variable is a property of one object, So, Here is the code I am trying to use. Note that above given static code works even in a Vue component.
Dynamic Code
<a class="twitter-timeline" data-height="500px" v-if="isLoading===false" :href="'https://twitter.com/'+service.twitter_handle+'?ref_src=twsrc%5Etfw'"></a>
But the dynamic one is not working. I checked with inspect element and the markup being generated by the code is perfectly fine. But it is showing nothing. It is not loading a twitter timeline when the code is dynamic.
Here's the generated markup:
<div class="card-body">
<a data-height="500px" href="https://twitter.com/Google?ref_src=twsrc%5Etfw" class="twitter-timeline"></a>
</div>
I don't know what's wrong, Trying to solve this since last 3 hours but nothing seems to work.
Tell the Twitter JavaScript library to reload your widgets by calling twttr.widgets.load() wrapped in $nextTick after changing the twitter_handle property.
$nextTick(function () { twttr.widgets.load(); });
With $nextTick you make sure that Vue rendered the HTML with all changes before executing the code.

How to load html from clicking a div class button without page refresh

I'm sorry for asking a simple question as I'm still learning html/css/js. What I want to do is to be able to click on this button that is a div class made from css and js, to load it's content without refreshing the page, which I believe requires ajax or jquery, but not sure how. Here is my github page danielroberto.github.io and the repo https://github.com/danielroberto/danielroberto.github.io so you can get an idea of what I mean. I basically want to click on any of the navigation buttons and then loads whatever content I want without redirecting to whole new html page. For example, when I want to click on the "photography" button, I want the button effect to happen while my images load on the bottom without redirecting to something like photography.html. Similar to clicking on the "design" button, I want it to transition and load my content.
There is a wealth of resources on the net to get the intro you need to AJAX - the technique of loading parts of a webpage instead of the whole thing.
You correctly suggest that you could use the jQuery JavaScript library to do this - there are lots of alternatives, but that's easy to learn, and is widely used on the net. Tried and tested!
Start here: http://www.w3schools.com/jquery/jquery_ajax_intro.asp
That would only be if you are planning to use some server-side technology to serve up your images.
If you are just going to manually set a list of images to show, and you want the buttons to cycle through these, then you're probably best just to build a carousel of some kind, using a jQuery carousel plugin, and include it all in your HTML markup from the beginning. Loads to choose from or get inspired by here: https://plugins.jquery.com/tag/carousel/.
Also, you should size your images to fit the screen you are serving them to. I recommend you look at using srcset. Your image on the test site was 4600px wide! Check this out: https://css-tricks.com/responsive-images-youre-just-changing-resolutions-use-srcset/
I hope it goes well. The early days can be hard work but you'll soon get the hang of it.
You could store your content in a var in your js. Then when your button is clicked you can call the function which creates a text node or an element and append that to your div.
HTML
<button onClick="function()"></button>
<div id="show-data">
</div>
JS
var newText = 'Stuff here';
function function() {
var div;
div = document.getElementById('show-data');
div.appendChild(document.createTextNode(newText));
}
You can easily edit the html of an element when clicking a button using jQuery
HTML
<div class="my-button">click here</div>
<div class="my-content">init content</div>
JS
contentElement = $('.my-content');
$('.my-button').click(function() {
contentElement.html('new content');
});
https://jsfiddle.net/jaxon58/zp9mvu38/

Best practices to load HTML + Javascript dynamically

I have a page that loads (using a XHR request) a modal box with a form inside.
The form is composed by HTML tags + some Javascript to do validation and to submit it (using another XHR request).
I did that, and it already works, but the resulting DOM is ugly, because the script tag is inside the modal, like in this simplified example:
<html>
<head>...</head>
<body>
<div id="modal">
<form>...</form> <!-- This is my dynamically loaded HTML -->
<script>...</script> <!-- This is the dynamically loaded JS -->
</div>
<script>...</script> <!-- My main scripts -->
</body>
</html>
I have two questions about this:
1) The best practice is to put all JS code right before body closes, but when I do my dynamic loading, I end up with JS inside the modal div. Is there an efficient way to load only HTML to the div and inject the JS at the end of body? Are there any tools for that? Or should I not worry about it?
2) I'm using jQuery, so I try to use $(document).ready() for all JS code, but if I use this for modal JS, it won't run, probably because the event is not triggered a second time. Is there any event I can use to make my dynamically loaded JS to run after laoding is complete? Or should I just put it in the end?
Answer to both questions:
I don't see a reason why you shouldn't insert the JS scripts in the DOM inside the modal. I think it's even better that way compared to a global place where you put all the injected scripts. This way you will still know which modal loads which script.
And it solves your second problem as well. When you first insert your DOM nodes and then the <script> element that will work on them, you don't need to wait for a ready event.
Only other way I can think of is having the modal scripts available globally, loading the modal and then doing something like ModalScript.initialize("#modal").
You could use a framework like Browserify to bundle and dynamically load ("lazy load") resources as needed.
This is a good example/tutorial.

Loading mulitple LinkedIn share buttons dynamically and asynchronously

I have a page showing thumbnails of posts. The posts are fetched via AJAX and a filter allows for different posts to be fetched. When a thumbnail is clicked, a carousel opens centered on the clicked post. Each post in the carousel has a LinkedIn share button.
Linked share buttons don't work properly if loaded into an invisible element and then loaded later. So we must load them at the time of opening the carousel. I do this using the following code:
$.getScript('http://platform.linkedin.com/in.js', function() {
$('.li-box-1').append('<script type="IN/Share" data-counter="right"></script>');
});
Now, if I close the carousel and select a filter, thereby fetching a different set of posts, and then click on one of them, the carousel displays without the LinkedIn share button, and we get this warning in the console:
duplicate in.js loaded, any parameters will be ignored
This is because we've already loaded LinkedIn's in.js. Does anyone know how to get around this?
This is the code that calls in the required linked in .js library.
We check to see if the library has been loaded previously by checking if the variable IN is undefined. And based on that we load the library for the first time, or ignore it.
This code you will put somewhere in your <header> tag, after the <body> tag, or right before the </body>, dont know your situation.
<script>
if (typeof (IN) !== 'undefined') {
// IN.parse(); // old but still supports
IN.init(); // reinitiating linkedin button
} else {
$.getScript("http://platform.linkedin.com/in.js");
}
</script>
or alternatively you could do this:
<script>
delete IN;
$.getScript("http://platform.linkedin.com/in.js")
</script>
And now this code you will place with your specific carousel, or carousel items.
<script type="IN/Share"
data-url=" **code to generate your url** "
data-counter="right">
</script>
If you look at the script you're running, you'll see that the results of the .getScript isn't being loaded into the script tag or anything like that, but rather you're essentially performing two seperate actions: loading the script and then creating the tag with type="IN/Share". The initial action, loading the script, only needs to be run once, as you've discovered, so you just need to run that .append line to create whatever dynamic buttons you want and then call IN.parse() to link the script to the newly created elements.
Seems like you're doing some really amazing coding gymnastics just to be able to share a link on LinkedIn. Why not try something simpler?
https://www.linkedin.com/sharing/share-offsite/?url={url}
Then you can hyperlink anything you want, control it with whatever CSS and JS you want, etc..
Source: Microsoft LinkedIn Share URL Documentation.
For example, this works for me:
https://www.linkedin.com/sharing/share-offsite/?url=http://www.wikipedia.org/
Works fine:

Access content of jQuery Mobile (sub)page using JavaScript

I've been trying many of the "standard" JavaScript DOM functions to access elements in an HTML document (getElementById, getElementsByName etc.), but I can't get it working with jQuery Mobile - when a subpage is loaded, the values returned from getElementById("elementOfInterest").innerHTML still contains the value from the master page.
I'm trying to implement this in an iPhone app, to extract and display the respective subpages' titles in a navigation bar (the page is displayed in an UIWebView), but I think (and hope) that the problem and solution is more or less "platform independent".
Anyone with thoughts of how to achieve this using JavaScript (or possibly some jQuery function)? I couldn't find anything in the jQuery Mobile Docs, though.
As per default behavior of jQuery Mobile configuration, it will automatically handle link clicks and form submissions through Ajax, when possible. So when you open a new page (sub page), new page will be appended to master page's DOM. During this time you loose JavaScript written on new page.
As per my thinking you can disable Ajax form and link.
To do so, write a link as follow:
Create
You can also do it for all the links by overriding default configuration:
<script src="/js/jquerymobile/jquery-1.5.min.js"></script>
<script type="text/javascript">
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled= false;
});
</script>
<link rel="stylesheet" href="/css/jquerymobile/jquery.mobile-1.0a3.min.css" />
<script src="/js/jquerymobile/jquery.mobile-1.0a3.min.js"></script>
In both the way, pain is, you will loose framework's generated back button!
Read more at:
http://jquerymobile.com/demos/1.0a3/#page.html&subpageidentifier
Edit:
To add back button in new page, you may put it manually like:
<div data-role="header">
Back
<h1>
List items
</h1>
</div>

Categories