I am trying to optimize JS performance for a first-time user and SEO, with the goal of minimizing First Input Delay. When the home page loads, I initialize common JS functionalities and actions across the site with:
<script defer src="~/assets/js/common.js"></script>
In common.js:
$(function () {
initActions();
}
function initActions() {
$(document).on("click", "a.modal-link", function (e) {
var target = $(this).data("target");
$.ajax({
type: "GET",
url: $(this).data("url"),
dataType: "html",
cache: false,
success: function (response) {
$(target + " .modal-content").html(response);
$(target).modal("show");
}
}).fail(function () {
networkError();
});
});
setTimeout(function () {
$("#successLabel").slideUp("slow");
}, 8000);
$(".utcToLocalDate").each(function () {
$(this).text(moment.utc($(this).data("datetimeutc")).local().format("l"));
});
Is there a best practice to structure JS and declare common functions? I am aware this code is inefficient and I am currently going in circles with iterative improvements.
Related
I'm working on an inherited site which I upgraded from Laravel 5.3 to Laravel 8. It has a lot of jQuery and all the js and css is pre-processed. One button that is supposed to change color when it is clicked doesn't work. This is the jQuery function for that button:
define([], function () {
var VipClass = function () {
// Private vars
var _this = this;
// Private Methods
var _construct = function () {
$(document).on('click', '.button-vip', function (e) {
e.preventDefault();
e.stopPropagation();
var t = $(e.currentTarget),
url = t.data('url'),
status = !t.hasClass('btn-glow');
t.prop('disabled', true);
$.ajax({
url: url,
type: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: {
status: status
},
dataType: 'JSON',
async: true,
cache: false,
complete: function () {
t.prop('disabled', false);
},
success: function (response) {
if (response.success) {
t.toggleClass('btn-clean', !status);
t.toggleClass('btn-glow', status);
}
}
});
});
};
// Init
_construct();
};
return VipClass;
});
That's the prettified version of the code. The button either has orange fill if activated or no fill if not. In either case the jQuery doesn't change it when clicked. If I refresh the page or go out and come back the change has been applied so I know the save to the db is working. The ajax success appears to be doing a double toggle.
This is the html of the button:
<button class="button-vip btn btn-warning btn-icon btn-sm btn-glow" data-url="...">
<span class="icon-star"></span>
</button>
Probably, my biggest problem is that I don't know how to manually change the code when the files are preprocessed. I have not worked much with pre-processed files and it seems cumbersome to have to continually re-compile for a small change. How is this generally handled in dev?
I have an issue, do not know if it possible or not, how to check if my container is already loaded or not, because sometimes it is being loaded faster, sometimes slower and if it does not succeed in time getting an error in javaScript where gridview some functions are not recognizable(because the gridview is not loaded fast enough). Hope it is clear. Thanks for Your time.
Code:
function LoadPartial(partialUrl, container) {
$.ajax({
type: 'POST',
url: partialUrl,
success: function (returnData) {
$(container).html(returnData);
}
});
//.done(function () {
// return;
//});
}
you can use something like this.
$(".container").load(function (){
alert("Loaded :)");
});
Let me know in-case this doesn't work.
You can try using .data()
if ($('#mycontainer').data('loaded')) {
// your code
}
If you mean to find event when data received use "complete" function:
$.ajax({
type: 'POST',
url: partialUrl,
success: function (returnData) {
$(container).html(returnData);
},
complete: function() {
console.log('container filled with data');
}
});
I've played around with creating my own jquery functions, this done via the
$.fn.extend({
myFunc: function () {
}
});
However, after scouring the web and SO for an answer, I would like to ask:
How can I extend $.ajax()
The new implementation of $.ajax can be used by running
$.ajax({
}).done(function (e) {
}).fail(function (e) {
});
What I would like to do is to add a .progress() so that I don't always have to write
$.ajax({
url: path,
xhrFields: {
onprogress: function (e) {
if (e.lengthComputable) {
console.log(e.loaded /e.total * 100 + '%');
}
}
}
});
each time I want to monitor the progress. e.g.
$.ajax({
url: '/somewhereorother',
type: 'post',
dataType: 'json'
}).progress(function (e) {
updateProgressBar(e.percentage + '%');
}).done(function (e) {
}).fail(function (e) {
});
$.ajax is a function attached to $ object.
As such, to extend it you would have to store the reference to it somewhere, and call it when needed, something like:
var ajax = $.ajax;
$.ajax = function()
{
if (!arguments[0].success)
arguments[0].success = function()
{
window.alert('done!');
}
ajax.apply(ajax, arguments);
}
This is a concept (I'm not sure of this scope in apply - would have to actually run it) ;) Also, I'd say it's ugly as hell way of doing things.
If you want your $.ajax function to differ from official function, I'd still separate it. Either via $.my_ajax or by separate namespace (take a look at http://api.jquery.com/jquery.sub/)
I have the follwoing JQuery/AJAX code:
<script>
$('.warning-dialog').click(function () {
alert($(this).data("id"));
});
$(function () {
//twitter bootstrap script
$("button#delete").click(function () {
$.ajax({
type: "GET",
url: "deleteArticleType.php",
data: { 'typeID': $('.warning-dialog').data("id") },
success: function (msg) {
$("#thanks").html(msg)
$("#form-content").modal('hide');
},
error: function () {
alert("failure");
}
});
});
});
</script>
The first function gets the data-id of a button . The second function calls a PHP page and with the method GET should get the value from the first function.
I tried the code above but it didn't work.
My question is why and how can I fix it?
If these are two separate events, disconnected in time and you want to store the value from the first click and then use it in the second click, then you will have to store it somewhere. There are several options, the simplest being a variable.
$(function () {
var lastClickId;
$('.warning-dialog').click(function () {
lastClickId = $(this).data("id");
});
//twitter bootstrap script
// FIXME: you need to add logic here for what to do if lastClickId isn't set yet
// or create a default behavior in that case
$("button#delete").click(function () {
$.ajax({
type: "GET",
url: "deleteArticleType.php",
data: { 'typeID': lastClickId },
success: function (msg) {
$("#thanks").html(msg)
$("#form-content").modal('hide');
},
error: function () {
alert("failure");
}
});
});
});
Since it looks like you are requiring the first click to happen before the second click can have something to operate on, then you should probably either modify the UI to use different types of controls or you will need to add some error handling if the user doesn't click in the right order.
Actually it should have worked using $('.warning-dialog').data("id")
If your page contains only a single class warning-dialog, you approach will be worked. It seems you're referring this class to many elements.
I am trying to simplify all .js functions on the site to improve page load speed and overall performance of my site. Managed to do most of it on my own, but got stack when started to minimize couple of functions that are mostly call backs and onclick functions called from the functions.js in the page head.
SO here is my question, how can I make one function out of the following 2 to make script shorter and without loosing any functionality, or if there any alternative way to make it all simpler than it currently is?
function user_dialog(dialog_content, download_button) {
if (typeof jQuery.ui != 'undefined') {
$("#dialog").attr("title", "Lets share it").html(dialog_content);
$("#dialog").dialog({
modal: false,
width: 400,
buttons: {
Cancel: function() {
$(this).dialog("close");
},
"Download": function () {
$(this).dialog("close");
window.location = download_button;
}
}
});
} else {
window.location = download_button;
}
}
function user_notice(link_source) {
download_link = $(link_source).attr("href");
$.ajax({
type: "POST",
url: "/includes/json.php",
data: "action=reminder&thepath=" + download_link,
dataType: "json",
error: function() {
window.location = download_link;
},
success: function(resp_dialog) {
if (resp_dialog.status == 1) {
user_dialog(resp_dialog.html, download_link);
}
}
});
}
Thanks for your help in advance!!!
add an action variable in your function vars, like us_action and un_action then use an if statement to say if is us_acion, perform this else if un_action do this