返回列表 回复 发帖
javascript 中的  “-,*,/” 都是按数值进行,“+”  就按字符处理,不可想象。
javascript 是一种宽松类型的语言。宽松类型意味着设计者不必显式地定义变量的数据类型。大多数情况下,javascript 将根据需要自动进行转换。例如,如果将一个数值添加到一个字符串,该数值将被系统自动转换为文本。
    在大型的软件开发中,我们最好还是不要享受这种语言的恩赐,原因有很多,主要的有两点:一是它很可能会在不经意间埋下不可预期的 bug;二是这种代码缺乏可移殖性。眼下,我们可以将 showMess 改成:
    function showMess()
    {
        var a=parseInt(numA.value);
        var b=parseInt(numB.value);
        var c=a-b;
        var d=a*b;
        var e=a/b;
        var f=a+b;
        messBox.innerText="A-B="+c+"\n"+
                          "A*B="+d+"\n"+
                          "A/B="+e+"\n"+
                          "A+B="+f;
    }
    尽管如此,showMess 的行为还是很怪异的,在输入框中输入数据时很吃力,我们应该提供一种机制,让用户的操作变得轻松一些。
    在往下走之前,这里有必要讨论一下程序设计的思维模式的问题:
    1.不管是哪一种语言,哪一种软件,解决同一个问题,所使用的语言、软件资源越少越好。
    2.不管遇到什么问题,最好不要往里钻,应该退一步,站得更高一点,看得更远一些。这个不大好理解,比方说:我们被一座金碧辉煌的殿堂所吸引,进到里面后很多人就出不来了,如果我们理智的退出来,站到更高更远的地方,我们将会看到更多的更辉煌的大殿。侠客行里的石破天改成金破天就索然无味了。
    3.程序设计时,不要被语言的规则所束缚,更多的应该遵循人的行为习惯。
    啰嗦了,请大家包容!!!
htm0006.rar (454 Bytes)
New.gif
2014-10-16 09:13

    javascript 是一种基于对象、事件驱动的编程语言,在输入框输入数据时,系统会触发
onchange 事件,如是,我们便可以编写一个函数,捆绑到这个事件上来,其目的是:当用户输入数据后,立马由该函数对输入的数据进行审核并校正,使输入框内的数据总是在可控的范围内,也就是数据的有效性验证:
    function dataVerify(obj,min,def,max,parseNum)
    {
        var n=parseNum(obj.value);
        if(isNaN(n)||n<min||n>max)n=def;
        obj.value=n;
    }
    这里,我们定义了一个 dataVerify 函数,它接收五个参数:
    obj:接受数据审核的对象
    min:输入框内允许的最小值
    def:通不过审核时设定的默认值
    max:输入框内允许的最大值
    parseNum:将文本转换为数值的系统方法(parseInt 或 parseFloat)
    这意味着我们可以将方法(函数)名作为参数在调用和被调用的函数之间进行传递,这一特性在
编制大型和复杂的程序时非常管用,有点像函数式编程。
    当 n=parseNum(obj.value) 将文本转换为数值出现异常时,isNaN(n)返回逻辑真 true,否则,返回逻辑假 false。
    现在,我们在两个输入框的 html 代码中加入 onchange 事件属性:
A=<input id=numA type=text size=16 value=20
   onchange=dataVerify(this,-1000000,20,1000000,parseInt)><br>
B=<input id=numB type=text size=16 value=30
   onchange=dataVerify(this,-1000000,30,1000000,parseFloat)><br>
    这里的 this 表示对象本身(有点像面向对象编程里的 this);对于 numA 我们传递了将文本转换为整型数值的方法 parseInt,而对于 numB 我们传递了将文本转换为浮点型数值的方法
parseFloat,此举并非程序需要,只是体验一下而已。
    相应的 showMess:
    function showMess()
    {
        var a=parseInt(numA.value);
        var b=parseFloat(numB.value);
        var c=a-b;
        var d=a*b;
        var e=a/b;
        var f=a+b;
        messBox.innerText="A-B="+c+"\n"+
                          "A*B="+d+"\n"+
                          "A/B="+e+"\n"+
                          "A+B="+f;
    }
    这里,留一个问题给大家:如果输入框内允许的最大最小值为 +∞-∞,该如何写代码呢?
htm0007.rar (570 Bytes)
htm0008.jpg
2014-10-16 19:06

    就 html 来说,对于 input 元素,我们可以通过 onmousewheel(鼠标滚轮)事件使用 javascript 来提供一种稍为高级一点的数据输入方式:
A=<input id=numA type=text size=16 value=20
  onchange=dataVerify(this,-1000000,20,1000000,parseInt)
  onmousewheel=dataVerify2(event.wheelDelta,10,this,-1000000,20,1000000,parseInt)><br>
B=<input id=numB type=text size=16 value=30
  onchange=dataVerify(this,-1000000,30,1000000,parseFloat)
  onmousewheel=dataVerify2(event.wheelDelta,0.1,this,-1000000,20,1000000,parseFloat)><br>
    系统触发各种鼠标事件后,会建立一个名为 event 的对象记录下鼠标的各种状态,鼠标向前滚动时 event.wheelDelta 大于零,反之小于零。这里的代码设定 numA 的变化幅度为±10,numB 的变化幅度为±0.1。这样,可以将 dataVerify2 写成如下的样子:
    function dataVerify2(d,dn,obj,min,def,max,parseNum)
    {
        var n=parseNum(obj.value)+dn*Math.abs(d)/d;
        if(isNaN(n)||n<min||n>max)n=def;
        obj.value=n;
    }
    这里 Math.abs 是 javascript 的内置对象 Math 的求绝对值的方法,所以,Math.abs(d)/d,将取值 1 或 -1,这样,代码就实现了输入框内的数值随着鼠标的滚动朝相应的方向变化。
htm0008.rar (638 Bytes)
比较一下 dataVerify 和 dataVerify2:
    function dataVerify(obj,min,def,max,parseNum)
    {
        var n=parseNum(obj.value);
        if(isNaN(n)||n<min||n>max)n=def;
        obj.value=n;
    }
    function dataVerify2(d,dn,obj,min,def,max,parseNum)
    {
        var n=parseNum(obj.value)+dn*Math.abs(d)/d;
        if(isNaN(n)||n<min||n>max)n=def;
        obj.value=n;
    }
    两个函数可以并作一个:
    function dataVerify(d,dn,obj,min,def,max,parseNum)
    {
        var n=parseNum(obj.value)+dn*Math.abs(d)/d;
        if(isNaN(n)||n<min||n>max)n=def;
        obj.value=n;
    }
    修改一下 numA 和 numB:
A=<input id=numA type=text size=16 value=20
      onchange=dataVerify(1,0,this,-1000000,20,1000000,parseInt)
  onmousewheel=dataVerify(event.wheelDelta,10,this,-1000000,20,1000000,parseInt)><br>
B=<input id=numB type=text size=16 value=30
      onchange=dataVerify(1,0,this,-1000000,30,1000000,parseFloat)
  onmousewheel=dataVerify(event.wheelDelta,0.1,this,-1000000,20,1000000,parseFloat)><br>
    当触发 onchange 事件并执行 dataVerify 时,dn*Math.abs(d)/d 恒等于零。
    至此,我们终于写出了一个颇具价值的 javascript 函数 dataVerify。这可是一劳永逸的业绩,在后面的复分形编程中,有着一大堆的参数,少了这段代码将是很难想像的。当然,我们可以把这个dataVerify 函数写得更复杂一些,功能更强大一些。
htm0009.rar (633 Bytes)
关于数据的输入,到现在暂且告一段落,接下来讨论作图,也即 html5 的画布 canvas。
    在此之前,我们稍事休息,有两个问题在这里说明一下:
    一、这里的讨论有一个默认的前提,那就是各位朋友应该对编程语言具备一定的知识,这种知识的来源有两个途径,首先,所有的编程语言都有相通的地方;其次,对于 html、css、javascript 这三种语言的细节,应该先作些功课,我手上倒是有些资料,打了个包,260 MB,可我不知道怎么传,如有需要,给个邮箱地址。
    二、解释一下本贴的主题“几何画板下的编程思考”。
    前面提到过,几何画板作为很多算法的形象演练,是个绝妙的工具,比方说,hilbert 曲线的制作,除了原生的字符串重写系统,其他的诸如,迭代、递归、矩阵都可以,但不怎么轻松。然而在几何画板里,通过逆向思维,把 hilbert 曲线的过程倒过来,竟然找到了一种既简单又巧妙的方法。各位老师的画板作品,更是让我心动,虽然弄不明白其中的数学原理,却使我明白了一个道理,我们原来编的程序都是那么生硬,是因为没有在数据可视化上下功夫。
    下面就是受几何画板的启发编写的万花曲线规(须在 ie10 下运行),如果可以继续的话,后面将以它为蓝本进行讨论。
htm0010.jpg
2014-10-17 02:02

万花曲线规html.rar (2.18 KB)
感谢您的精彩文章,受益匪浅。
想索取您的资料,留个邮箱——1043622345@qq.com
谢谢!
赞一个!很有意义的研究,不过几何画板对javascript的支持比较有限吧,如果是在GerGebra上研究javascript会强大的多。
金狐工作室:http://www.jinhu.me
再看了一遍,发现并不是几何画板支持javascript,而是单纯的javascript语言实现几何画板的部分效果。
而GerGebra是原生支持javascript并可以输出网页文件的,可以说做数学网络课件GerGebra是最佳选择。
金狐工作室:http://www.jinhu.me
1# xklppp
不错。有意的工作。
不过我也说两点:
第1点:学习js代码最好的地方是网络上的w3cschool(w3c学校),我就是从那里起步的。
第2点:几何画板无法使用编程,这是几何画板的缺陷,同时也是优点,因为编程会让操作抽象化,但编程又可以让画板做更多更细腻的事情,几何画板的作者在这两者间做了选择,他选择了取消编程,采用形象化的操作。GGb可以支持js编程。
最后,对你的工作致敬。
返回列表