- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
最近,我一直在对模块化JS进行大量试验,但我仍然想知道是否以“正确的方式”编写它。
例如,如果我有一个页面,其中包含输入和提交按钮,这些页面应在提交后显示数据(例如表格和图形),所以我在IFFE下编写代码,因此没有人可以访问它,但是使用这样的对象变量:
var webApp = { ... }
qwData
中进行管理:
(function() {
const qwData = {
// Initialize functions
init: function() {
this.cacheDom();
this.bindEvents();
},
// Cache vars
cacheDom: function() {
this.dataDisplayed = false;
this.countUsers = <?php echo $_SESSION['all_users_count_real']; ?>;
this.customerMachines = <?php echo $_SESSION['customer_statistics']['total_machines']; ?>;
this.$form = $('#frm');
this.$alistToolbar = this.$form.find('.alist-toolbar');
this.start_date = this.$form[0][9].value;
this.end_date = this.$form[0][10].value;
this.dateCount = this.countDays(this.start_date, this.end_date);
this.show = document.querySelector('#btn-show');
this.downloadBtn = document.querySelector('#download_summary_button');
this.$dataContainer = $('#qw-data-container');
this.$qwTable = $('#qwtable');
this.$qwTbody = this.$qwTable.find('tbody');
this.$qwTd = this.$qwTbody.find('td');
this.qwChart = echarts.init(document.getElementById('main-chart'));
this.progressBar = document.querySelector('.progress-bar');
Object.defineProperty(this, "progress", {
get: () => {
return this.progressPrecent || 0;
},
set: (value) => {
if( value != this.progressPrecent ) {
this.progressPrecent = value;
// this.setQwChartProgress(value);
this.setProgressBarValue(value);
this.setProgressButton(value);
}
},
configurable: true
});
this.qwChartProgress = this.progress;
},
// Bind click events (or any events..)
bindEvents: function() {
var that = this;
// On click "Show" BTN
this.show.onclick = this.sendData.bind(this);
// On Change inputs
this.$form.change(function(){
that.updateDatesInputs(this);
});
// downloadQw
this.downloadBtn.onclick = this.downloadQw.bind(this);
},
downloadQw: function(e){
e.preventDefault();
var customer = "<?php echo $_SESSION['company_name']; ?>";
var filename = customer + "qws_"+ this.start_date + "-" + this.end_date + ".zip";
$.ajax({
url: "/aaa/api/download_csv.php",
method: "GET",
dataType : "json",
data: {
customer: customer,
filename: filename
},
success:function(result){
if(result.status){
window.location.href="/aaa/api/download_csv.php?customer="+customer+"&filename="+filename+"&download=1";
}
},
error:function(){
}
})
},
setQwChartProgress: function(value){
if (value != 0) {
// Show Chart Loading
this.qwChart.showLoading({
color: (value == 99) ? '#00b0f0' : '#fff',
text: value + '%'
});
}
},
setProgressButton: function(value){
if ( value >= 100 || value == 0 ){
this.show.value = 'Show';
}
else {
this.show.value = value +'%';
// this.show.disabled = true;
this.disableShow();
}
},
resetShowButton: function(){
this.show.value = 'Show';
this.disableShow();
},
disableShow: function(){
// this.show.style.color = "grey";
// this.show.disabled = true;
this.show.classList.add("isDisabled");
},
enableShow: function(){
// this.show.style.color = "#66aa66";
// this.show.disabled = false;
this.show.classList.remove("isDisabled");
},
updateDatesInputs: function(){
this.start_date = this.$form[0][9].value;
this.end_date = this.$form[0][11].value;
this.dateCount = this.countDays(this.start_date,this.end_date);
// this.show.disabled = false;
this.enableShow();
this.removeError();
},
removeError: function(){
if (this.errors) {
this.errors.remove();
delete this.errors;
}
},
countDays: function(date1, date2){
// First we split the values to arrays date1[0] is the year, [1] the month and [2] the day
var date1 = date1.split('-');
var date2 = date2.split('-');
// Now we convert the array to a Date object, which has several helpful methods
date1 = new Date(date1[0], date1[1], date1[2]);
date2 = new Date(date2[0], date2[1], date2[2]);
// We use the getTime() method and get the unixtime (in milliseconds, but we want seconds, therefore we divide it through 1000)
var date1_unixtime = parseInt(date1.getTime() / 1000);
var date2_unixtime = parseInt(date2.getTime() / 1000);
// This is the calculated difference in seconds
var timeDifference = date2_unixtime - date1_unixtime;
// in Hours
var timeDifferenceInHours = timeDifference / 60 / 60;
// and finaly, in days :)
var timeDifferenceInDays = timeDifferenceInHours / 24;
if (timeDifferenceInDays > 0){
return timeDifferenceInDays;
} else {
// alert('Error: The date are invalid.');
}
},
// Get data, prevent submit defaults and submit.
sendData: function(e) {
e.preventDefault();
if (this.show.classList.contains('isDisabled')) {
this.showErrorDiv("Please select a new date range before submitting.");
} else {
let that = this;
let estimatedTotalTime = ( (this.countUsers*this.customerMachines)/777 ) * 0.098;
let estimatedTime = estimatedTotalTime/99;
let estimatedTimeMs = estimatedTime*1000;
let timer = setInterval( function(){that.incrementProgress(timer);}, estimatedTime);
console.log('Total Time: ' + estimatedTotalTime + 's');
console.log('Estimated Time for 1%: ' + estimatedTime + 's');
$.ajax({
type: 'POST',
url: "/manageit/ajax.php?module=qw_module",
dataType: 'json',
data: {
start_ts: that.start_date,
stop_ts: that.end_date,
submitted: true,
company_name: "<?php echo $_SESSION['company_name']; ?>"
},
beforeSend: function() {
// Show Chart Loading
that.qwChart.showLoading({
color: '#00b0f0',
// text: that.qwChartProgress
text: ''
});
// If data div isn't displayed
if (!that.dataDisplayed) {
// Show divs loading
that.showMainDiv();
} else {
that.$qwTbody.slideUp('fast');
that.$qwTbody.html('');
}
},
complete: function(){},
success: function(result){
// Reset show btn
that.resetShowButton();
// Clear timer
clearInterval(timer);
// Set progressbar to 100%
that.setProgressBarTo100();
// Show Download Button
that.downloadBtn.style.display = 'inline-block';
// Insert Chart Data
that.insertChartData(result);
// Insert Table Data
that.insertTableData(result);
}
});
that.dataDisplayed = true;
}
},
showErrorDiv: function(errorTxt){
if (!this.errors){
this.errors = document.createElement("div");
this.errors.className = "qw_errors_div";
this.errors.textContent = errorTxt;
this.$alistToolbar.append(this.errors);
}
},
// Insert Data to Table
insertTableData: function(json){
let str = '';
let isOdd = ' rowspan="2" ';
for ( let i=1; i<9; i++ ) {
str += '<tr>';
for (let j = 0; j < 8; j++) {
if ((i%2 === 0) && (j==0)){
// do nada
} else {
str += '<td ';
str += ((i % 2 !== 0)&&(j==0)) ? isOdd : '';
str += '> ';
str += json[i][j];
str += '</td>';
}
}
str += '</tr>';
}
this.$qwTbody.html(str);
this.$qwTbody.slideDown('fast', function(){
if ($(this).is(':visible'))
$(this).css('display','table-row-group');
});
// Apply colors on table.
this.tableHover();
},
tableHover: function(){
this.$qwTd = this.$qwTbody.find('td');
var that = this;
this.$qwTd.eq(0).hover( function(){
that.$qwTd.eq(0).css('background-color', '#f5f5f5');
that.$qwTd.eq(0).parent().css('background-color', '#f5f5f5');
that.$qwTd.eq(0).parent().next().css('background-color', '#f5f5f5');
}, function(){
that.$qwTd.eq(0).css('background-color', '');
that.$qwTd.eq(0).parent().css('background-color', '');
that.$qwTd.eq(0).parent().next().css('background-color', '');
});
this.$qwTd.eq(15).hover( function(){
that.$qwTd.eq(15).css('background-color', '#f5f5f5');
that.$qwTd.eq(15).parent().css('background-color', '#f5f5f5');
that.$qwTd.eq(15).parent().next().css('background-color', '#f5f5f5');
}, function(){
that.$qwTd.eq(15).css('background-color', '');
that.$qwTd.eq(15).parent().css('background-color', '');
that.$qwTd.eq(15).parent().next().css('background-color', '');
});
this.$qwTd.eq(30).hover( function(){
that.$qwTd.eq(30).css('background-color', '#f5f5f5');
that.$qwTd.eq(30).parent().css('background-color', '#f5f5f5');
that.$qwTd.eq(30).parent().next().css('background-color', '#f5f5f5');
}, function(){
that.$qwTd.eq(30).css('background-color', '');
that.$qwTd.eq(30).parent().css('background-color', '');
that.$qwTd.eq(30).parent().next().css('background-color', '');
});
this.$qwTd.eq(45).hover( function(){
that.$qwTd.eq(45).css('background-color', '#f5f5f5');
that.$qwTd.eq(45).parent().css('background-color', '#f5f5f5');
that.$qwTd.eq(45).parent().next().css('background-color', '#f5f5f5');
}, function(){
that.$qwTd.eq(45).css('background-color', '');
that.$qwTd.eq(45).parent().css('background-color', '');
that.$qwTd.eq(45).parent().next().css('background-color', '');
});
},
incrementProgress: function(timer){
if (this.progress == 99)
clearInterval(timer);
else
this.progress++;
},
// Insert Data to Chart
insertChartData: function(json){
var posList = [
'left', 'right', 'top', 'bottom',
'inside',
'insideTop', 'insideLeft', 'insideRight', 'insideBottom',
'insideTopLeft', 'insideTopRight', 'insideBottomLeft', 'insideBottomRight'
];
this.qwChart.configParameters = {
rotate: {
min: -90,
max: 90
},
align: {
options: {
left: 'left',
center: 'center',
right: 'right'
}
},
verticalAlign: {
options: {
top: 'top',
middle: 'middle',
bottom: 'bottom'
}
},
position: {
options: echarts.util.reduce(posList, function (map, pos) {
map[pos] = pos;
return map;
}, {})
},
distance: {
min: 0,
max: 100
}
};
this.qwChart.config = {
rotate: 90,
align: 'left',
verticalAlign: 'middle',
position: 'insideBottom',
distance: 15,
onChange: function () {
var labelOption = {
normal: {
rotate: this.qwChart.config.rotate,
align: this.qwChart.config.align,
verticalAlign: this.qwChart.config.verticalAlign,
position: this.qwChart.config.position,
distance: this.qwChart.config.distance
}
};
this.qwChart.setOption({
series: [{
label: labelOption
}, {
label: labelOption
}, {
label: labelOption
}]
});
}
};
var labelOption = {
normal: {
show: true,
position: this.qwChart.config.position,
distance: this.qwChart.config.distance,
align: this.qwChart.config.align,
verticalAlign: this.qwChart.config.verticalAlign,
rotate: this.qwChart.config.rotate,
// formatter: '{c} {name|{a}}',
formatter: '{name|{a}}',
fontSize: 16,
rich: {
name: {
// textBorderColor: '#fff',
// color: '#333',
// color: '#717171',
color: '#525252',
shadowColor: 'transparent',
shadowBlur: 0,
textBorderColor: 'transparent',
textBorderWidth: 0,
textShadowColor: 'transparent',
textShadowBlur: 0
}
}
}
};
option = {
color: ['#007bff', '#00b0f0', 'red', '#e5323e'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['Inactives / Viewers', 'Inactives / Viewers / Less than 1min per day', 'Light no Macro']
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
mark: {show: true},
// dataView: {show: true, readOnly: false},
// magicType: {show: true, type: ['line', 'bar', 'stack', 'tiled']},
restore: {show: true},
saveAsImage: {show: true}
}
},
calculable: true,
xAxis: [
{
type: 'category',
axisTick: {show: false},
data: ['Excel', 'Word', 'PowerPoint', 'All 3 Apps']
}
],
yAxis: [
{
type: 'value',
name: 'Score'
}
],
series: [
{
name: 'Light no Macro',
type: 'bar',
label: labelOption,
color: 'red',
data: [ [3, json[7][7]] ]
},
{
name: 'Inactives / Viewers',
type: 'bar',
barGap: 0,
label: labelOption,
data: [ json[1][7], json[3][7], json[5][7], json[8][7] ]
},
{
name: 'Inactives / Viewers / Less than 1min per day',
type: 'bar',
label: labelOption,
data: [ json[2][7], json[4][7], json[6][7] ]
}
]
};
// Set charts options
this.qwChart.setOption(option);
// Hide Loading
this.qwChart.hideLoading();
},
// Show Main div on submition (only)
showMainDiv: function(){
// Show all contatner div
this.$dataContainer.slideDown('slow');
},
// Sets a new value for the progress bar
setProgressBarValue: function(value){
this.progressBar.style.width = this.returnNumWithPrecent(value);
},
returnNumWithPrecent: function(num){
return num.toString() + '%';
},
setProgressBarTo100: function(){
var that = this;
// Show Download Button
this.progress = 100;
setTimeout(function () {
// Show Download Button
that.progress = 0;
}, 1000);
}
}
// run object
qwData.init();
})();
webApp = function (){ ... };
var Background = (function() {
'use strict';
// placeholder for cached DOM elements
var DOM = {};
/* =================== private methods ================= */
// cache DOM elements
function cacheDom() {
DOM.$background = $('#background');
}
// coordinate async assembly of image element and rendering
function loadImage() {
var baseUrl = 'https://source.unsplash.com/category',
cat = 'nature',
size = '1920x1080';
buildElement(`${baseUrl}/${cat}/${size}`)
.then(render);
}
// assemble the image element
function buildElement(source) {
var deferred = $.Deferred(function (task) {
var image = new Image();
image.onload = function () {
task.resolve(image);
};
image.onerror = function () {
task.reject();
};
image.src = source;
});
return deferred.promise();
}
// render DOM
function render(image) {
DOM.$background
.append(image)
.css('opacity', 1);
}
/* =================== public methods ================== */
// main init method
function init() {
cacheDom();
loadImage();
}
/* =============== export public methods =============== */
return {
init: init
};
}());
var webApp = function (){ ... };
最佳答案
互联网教程的问题之一是它们徘徊在相关性之上,并且很少有作者将它们保持最新。在JS Realm 中,事情进展得非常快,而5年前的行业标准(例如jQuery)现在在您仍然迷迷糊糊时似乎很奇怪。
因此,要实践我为别人遗漏而good的好习惯:
JavaScript模块状态,2018年中,变化迅速,已弃用
一团糟。
首先,您拥有ES 6模块。 ES 6被重命名为ES 2015,并且取出了模块部分,并使其成为一个单独的规范,这意味着浏览器可以符合ES 2015且仍不具有本机模块。但是,三年后,每个具有相关全局市场份额的浏览器(chrome,android chrome,firefox,iOS Safari)至少实现了本机模块系统的基本版本(Edge,Opera等也是如此)。我不清楚,因为我相信规范允许路径更宽容(我们将在稍后再讨论),但这是语法,相对或绝对文件路径,需要扩展名:
import Foo from './foo.js'; // Import default export from foo.js, alias to 'Foo'
import { Foo } from './foo.js'; // Import named export 'Foo' from foo.js
export default function () {}; // exports a function as default, importer aliases
const Foo = class Foo {};
export Foo; // exports named class Foo
require.js
的异步模块定义。尽管它具有一些引人注目的技术优势,但实际上已死了。
require
表达式转换为浏览器可以处理的内容(基本上,通过使用require函数)。 Node的模块有点不适合浏览器,但是在一个标准上的融合要比八千万个竞争性的即席实现更好。人们查看了这三种竞争的模块模式/系统(在您的问题中,一个是AMD,common.js),并说我们可以统一它们。从而
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS-like
module.exports = factory(require('jquery'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.jQuery);
}
}(this, function ($) {
import Foo from 'foo'; // imports default export from foo.js somewhere on PATH
import 'Something.css'; // commonly seen in react apps
import 'logo.svg'; // ditto
关于javascript - 'var webApp = { .. }'和 'var webApp = function (){ .. }'有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50718685/
平时很少在jquery中用到this。查看代码时发现用到了,就调试出this的值,心想原来如此。还是挺有用的。这里总结一下this与$(this)的区别和使用。 $(this)生成的是什么?
使用单例类和应用程序范围的托管 bean 来保存应用程序数据有区别吗? 我需要查找某些 JNDI 资源,例如远程 bean 接口(interface),因此我为自己编写了一个单例来缓存我的引用并且只允
如果您仔细查看包含的图片,您会注意到您可以使用 Eclipse IDE 重构 Groovy 代码并将方法转换为闭包,反之亦然。那么,闭包到底是什么,它与方法有什么不同呢?有人可以举一个使用闭包的好例子
vagrant box repackage有什么区别( docs ) 和 vagrant package ( docs )? 我意识到 vagrant package仅适用于 VirtualBox 提
我想看看是否有人可以解释为什么以下代码适用于 valueOf 但不适用于其他代码。 import java.math.BigDecimal; public class Change { publ
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicates: What is Closures/Lambda in PHP or Javascript in layman te
This question already has answers here: Vagrant, Docker, Puppet, Chef (3个答案) 2年前关闭。 docker和chef有什么共同
以下代码在95%的机器上产生相同的输出,但是在几台机器上却有所不同。在 Debug模式下,输出: Changing from New to Fin OK 但在 Release模式下: Changing
////Creating Object var Obj; // init Object Obj= {}; 它们之间有什么区别两个? 有没有可能把它变成一个单行? 这样使用有什么好处吗?
我想找出定时器服务之间的区别。我应该使用哪个以及何时使用。我正在使用 Jboss 应用服务器。 1) java.ejb.Schedule。 @Schedule注解或配置自xml。 2) javax.e
我发现在 C++ 中可以通过三种不同的方式将对象传递给函数。假设我的类(class)是这样的: class Test { int i; public: Test(int x);
有什么区别。 public class Test { public static void main(String args[]) { String toBeCast = "c
如果我有一列,设置为主索引,设置为INT。 如果我不将其设置为自动递增,而只是将唯一的随机整数插入其中,与自动递增相比,这是否会减慢 future 的查询速度? 如果我在主索引和唯一索引为 INT 的
这两种日期格式有什么区别。第一个给出实际时间,第二个给出时间购买添加时区偏移值。 NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]
如果有一个函数,请说foo: function foo() { console.log('bar'); } 那么在 JavaScript 中,从另一个函数调用一个函数有什么区别,如下所示: f
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
代码是什么: class Time { private: int hours; int minutes; int seconds; pu
我知道这是非常基本的,但有人介意解释一下这两个数组声明之间的区别吗: #include array myints; ...和: int myints[5]; ...以及为什么 myints.size
我学会了如何根据 http://reference.sitepoint.com/css/specificity 计算 css 特异性但是,基于this reference,我不明白伪类(来自c)和伪元
为什么在运行 2) 时会出现额外的空行?对我来说 1 就像 2。那么为什么 2) 中的额外行? 1) export p1=$(cd $(dirname $0) && pwd) #
我是一名优秀的程序员,十分优秀!