您的位置:首页 > Web前端

对于一个小白来说,遇到的前端问题(1)

2017-04-12 10:06 344 查看
目录(?)[+]

1.写在前面

首先要声明一下我的立场,前端是个好东西,我希望我有。但是我之前对于前端确实不太熟悉,最近需要做一个项目,只好赶鸭子上架了。

对于前端还有很多不懂的地方,工期赶得紧,只能先能用再说,没考虑是不是正路子。下面是我最近在工程中所遇到的问题,分享给大家,也是提醒我自己。

2. js的若干问题

对于一位长期从事后端的人来说,JS的运作方式还是给我带来了很多颠覆性认识。 

但是其实主要有这么几个方面问题:

2.1. js是单线程工作

无论是有多少函数,什么样的情况下都是单线程在工作,而像回调函数那种,也不过是类似单线程操作系统中的“中断-响应”机制。

2.2. js的参数使用

js传说是基于对象的,也就是说,任何可操作的主体都是对象,当然也包括js最常见的函数也是对象,应该看过像下面的这种写法:
Fn2();
var Fn2 = function(){
alert("Hello wild!");
}
1
2
3
4
1
2
3
4

一个函数同样可以赋给一个变量。另外js的变量都是弱类型的,使用var可以自动转换,这点在字符型与数字型的变量中特别好用,在参数里不用声明其变量类型。那么这样子,所谓的委托,在js就变成了这样子:
function onBack(num){
alert("姗姗我来迟了");
// 执行num个耳光
}
function dating(hours, callBack){
var SP= 0; // SP,愤怒值
//女猪脚在雪里站了hours个钟头
//循环开始..
SP ++;
//循环结束...
callBack(SP);
}
dating(1, onBack);
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13

2.3. js的分块写与放在一起写

这就相当于是一种作用域区分,如果同名的函数放在同一Script块下,会被覆盖掉一个,而如果分开写,则会被解析成2个不同函数。
<scripttype="text/javascript">
functionHello() {
alert("Hello");
}
Hello();
functionHello() {
alert("Hello World");
}
Hello();
</script>
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10

这时候输出是两次Hello World,而不是Hello Hello World。但是如果像下面这样写的话,就达到了我们预期的效果:
<scripttype="text/javascript">
functionHello() {
alert("Hello");
}
Hello();
</script>
<scripttype="text/javascript">
functionHello() {
alert("Hello World");
}
Hello();
</script>
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12


2.4. js赋值函数执行与定义函数执行

首先我们来看一下赋值函数与定义函数的样子:
//“定义式”函数定义
Fn1();
function Fn1(){
alert("Hello World!");
}
//“赋值式”函数定义
var Fn2 = function(){
alert("Hello wild!");
Fn2();
}
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10

可以看到应该长得挺像的,那么他们有什么区别呢?我在做工程的项目中,发现如果是赋值式函数写错了,其实并不影响整个js,而只会影响这一个函数的输出。这是因为,如果是定义式函数,它会在执行前先编译一遍,而赋值式函数,则只会赋值,而并不会对函数本身进行预编译。

2.5 js的事件绑定问题

js中也有事件,而且确实挺像的,尤其是和C#中的事件特别类似。因为C#中的事件就是委托操作,而Java中大多使用的是监听器来进行,长得不太一样。

js的事件绑定一般就是长这样:
$('#btn').click(function () {
//点击事件发生后要做什么
}
1
2
3
1
2
3

看起来是不是和匿名内部方法一样呢?其实还有另外的事件绑定方法,我们这里就不详细谈了,毕竟我是小白。


3. bootstrap的若干问题

bootstrap可谓是不会前端样式的福音,毕竟bootstrap的意思就是自助。但是在学习上虽然可以节省大量学习的成本,但是毕竟是自助,比起专业来讲,还是差上许多,不过已经可以搭建出比较好的前端样式了。


3.1 bootstrap的栅格系统

bootstrap的最大特色在于栅格系统,这样可以在布局上省下许多功夫。我曾经就是这样以为,只需要使用
class="col-md-x"
就可以很好的来使用,因为一行是12个,每一个控件可以占用指定大小的部分。

但是其实是这样的,所谓的col,其实是column的缩写,既然有列了,当然应该有行了,因此row和col的搭配才能真正运用栅格系统,也就是行和列。但是这两个,都要在.Container中,不然,没有办法自动设置排列和间距。在这点上,我吃了很多苦头。


3.2 bootstrap的折叠样式使用

boostrap的另外一大特色就是丰富的js组件,可以提供一定程度上的动态效果。例如我在工程中用到的折叠样式。折叠样式如下:
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseOne">
点击我进行展开,再次点击我进行折叠。第 1 部分
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
Nihil anim keffiyeh helvetica, craft beer labore wes anderson
cred nesciunt sapiente ea proident. Ad vegan excepteur butcher
vice lomo.
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseTwo">
点击我进行展开,再次点击我进行折叠。第 2 部分
</a>
</h4>
</div>
<div id="collapseTwo" class="panel-collapse collapse">
<div class="panel-body">
Nihil anim keffiyeh helvetica, craft beer labore wes anderson
cred nesciunt sapiente ea proident. Ad vegan excepteur butcher
vice lomo.
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseThree">
点击我进行展开,再次点击我进行折叠。第 3 部分
</a>
</h4>
</div>
<div id="collapseThree" class="panel-collapse collapse">
<div class="panel-body">
Nihil anim keffiyeh helvetica, craft beer labore wes anderson
cred nesciunt sapiente ea proident. Ad vegan excepteur butcher
vice lomo.
</div>
</div>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

这仅仅能展示出最基本的样式,但是如果细心的人可以看到,在第一部分是
class="panel-collapse collapse in"
,而第二、第三部分则是
class="panel-collapse
collapse"
,他们分别对应着两种不同的状态:
class意义
.collapse隐藏内容。
c.collapse.in显示内容。
这只是状态,接下来是方法,分别是:Options、Toggle、Show、Hide,但是我目前还不太会用。我只用到了再往下的事件。事件绑定可以解决一个大问题,那就是在初始化的时候,除了展示的面板,其他面板都是被隐藏的,对于里面的元素操作可能会出现问题,例如我遇到了在里面放置echart的时候,没有办法初始化图表,这时候使用了下面的事件绑定,在面板展开后进行重新初始化图表,就解决了这个问题,它总共有4个事件:
class意义
show.bs.collapse这个是只要点击就执行,执行完再执行面板展开
shown.bs.collapse在CSS完成后执行,也就是面板展开后执行。
hide.bs.collapse这个是只要点击就执行,执行完再折叠面板
hidden.bs.collapse在CSS完成后执行,也就是面板折叠后再执行。
下面给出一个示例:
<script>
$('#collapseexample').on('show.bs.collapse', function () {
alert('嘿,当您展开时会提示本警告');})
</script>
1
2
3
4
1
2
3
4

就是这么简单,当然这也是事件绑定的一种形式,使用的是jQuery的事件绑定,就像下面这样。
$('button').on('click',function(){});
1
1

4. 后端控制前端页面。

说到这,就不得不说这种架构,就是后端如何去控制前端页面,也就是View与Controller的关系。

成熟的话,View是依靠Model生成的,由Controller进行控制。但是通常我们不一定使用MVC架构。最新提出的MVVM(Model-View-ViewModel)架构,则是把M与V中间加一层过渡层,这样C的大部分细节操作从原来的MVP架构中P(Presenter),转移到了VM(ViewModel)中,从而可以使得界面变换更加随意与便捷,为前端开发人员提供了更加自由的开发环境,曾经的P毕竟还是绑定在IView中。二MVVM则彻底把V和P/C分离开来了。

上面说了这么多高大上的话,在我这个并不大的工程中,都用不了,毕竟我自己是小白,那么就选择了最简单的方式,直接用后端来控制前端的输出。

在Aspx中,对于页面前端控件来说,有一些是可以在后端直接获取和运行的,通常的标志就是
runat="server"
但是像表格(table)和列表(ol/ul/li)就没有办法进行操作。当然,可以使用数据绑定,这不是嫌太麻烦么,因此就是用了最笨的办法,输出html源码到页面文件中。

Aspx可以定义全局变量,这样前段后端都可以看到这个全局变量,总共需要两步,第一步是在页面中需要输出的部分写下这个变量,如下示例:
<%=zxInfo%>
1
1

这一点和jsp的输出没什么两样,第二步,则是在后端进行数据绑定:
public partial class Demo : System.Web.UI.Page{
public string zxInfo;
}
this.Page.DataBind();
1
2
3
4
1
2
3
4

这样就把前端和后端通过一个全局变量联系起来了,当然,你也可以使用Session来进行消息传递,这样就省去了绑定的过程: 

后端初始化Session
protected void Page_Load(object sender, EventArgs e)
{
Session["Zx"] = "";
}
1
2
3
4
1
2
3
4

前端使用Session
<%=Session["Zx"]%>
1
1

上面这两种方法里,变量里都是HTML源码,该是tr、td的就是tr、td。

5. jQuery的选择器

jQuery是对js的进一步封装,可以解决不同js引擎对于js解析的不同,而且可以简化编码者对于js的操作。尤其是以选择器为代表的一系列操作,极大的简化了dom结点操作。 

我之前就有疑问选择器里面的内容有什么区别:
$("p") //选取 <p> 元素。
$("p.intro") //选取所有 class="intro" 的 <p> 元素。
$("p#demo") //选取所有 id="demo" 的 <p> 元素。
$("[href]") //选取所有带有 href 属性的元素。
$("[href='#']") //选取所有带有 href 值等于 "#" 的元素。
$("[href!='#']") //选取所有带有 href 值不等于 "#" 的元素。
$("[href$='.jpg']") //选取所有 href 值以 ".jpg" 结尾的元素。
1
2
3
4
5
6
7
1
2
3
4
5
6
7

这都是很常见的选取规则,更具体的,大家可以参考一下这里: 
jquery选择器参考手册

6. canvas的width

canvas这个控件有一个非常奇怪的width,当然在代码上是有style里的width,在外面还有一个width,这两个是不同的。style里面的width是画布的宽度,而外面的width是窗口的大小。但是其实还有第三个width,那就是画本身的width,这第三个是canvas本身不能解决的,但是前两个是可以控制的,如果我们要改style里面的width,它是属于Css的,只需要使用如下代码:
$("canvas").css("width","100px");
1
1

但是如果要修改它本身的width,则需要使用下面这个语句:
$("canvas").attr('width', 100px)
1
1

这两点事不相同的,但是如果是图的宽度不符合条件,那么你需要从图生成的部分开始查起。

7. Ajax的若干问题

7.1 Ajax的跨域调用问题

Ajax的跨域问题由来已久,也是非常常见的问题,通常来讲,Ajax并不能请求别的网站的请求,那如果需要请求一个外部服务的时候,就产生了跨域问题,那么如何解决这个问题呢?

如果非要使用Ajax,使用jsonp可以解决这个问题,但这需要修改服务端代码,但是如果服务的代码是封装好的,你没有办法或者没有权限修改的时候,这时候就需要Jquery-jsonp插件,这个插件可以解决跨域问题而且不用修改服务端代码。

具体的大家可以看一下jsonp的使用

7.2 Ajax中的回调函数

Ajax的回调函数也是一个新事物,我们在前面讲过js是单线程的,那么回调函数其实相当于委托事件,当程序执行完毕后,接下来如何处理返回的结果,就是回调函数所要做的事情,Ajax相当于一个发收过程,发送的事件Ajax自动做好了,不用程序员自己处理,但是收的过程需要自己来进行处理。

这和java与C#不同是因为,js一旦进行Ajax操作,就相当于是异步加载,等同于创建了一个线程,那这时候,主程序就失去了对于这个线程的实际控制权,也就是不会知道它什么时候停止,然后再做相应的事情,而回调函数就是主程序派给Ajax请求的一个接收员,等Ajax请求完毕收到返回值的时候,就由接收员来处理接下来的事情。这应该理解了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐