V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
zhaoyafei
V2EX  ›  问与答

求一最简单的js点击一次按钮,下面数字加1 (但是希望关闭页面之后再打开能记住上次的数字)

  •  
  •   zhaoyafei · 2011-04-21 13:28:11 +08:00 · 13664 次点击
    这是一个创建于 4972 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我能完成的之后这几句:
    <input type="submit" value="点我增加数字" onclick="document.getElementById('count').innerHTML=parseInt(document.getElementById('count').innerHTML)+1" >
    <input type="submit" value="点我减少数字" onclick="document.getElementById('count2').innerHTML=parseInt(document.getElementById('count2').innerHTML)-1">
    <span id="count">1</span>
    <span id="count2">100</span>


    怎样把两个按钮改成一个按钮能完成相同的效果并且实现标题括号中说的?
    22 条回复    1970-01-01 08:00:00 +08:00
    icyflash
        1
    icyflash  
       2011-04-21 13:34:16 +08:00
    两个按钮不能减成一个按钮,
    除非:
    1. 增加和减少同时进行
    或2. 另外再加一radiobutton作控制器。。

    括号里的用cookies可以简单实现,但用户清除cookies或cookies失效后就不行了。

    要持久的话,只能在服务端保存
    iloveyou
        2
    iloveyou  
       2011-04-21 13:37:13 +08:00
    细节不想多说,计数存在cookie里面
    dreampuf
        3
    dreampuf  
       2011-04-21 14:43:58 +08:00
    > <script>
    > last = 0, last_itd = -1;
    > function getExpires(andate) {
    > andate = andate || 1*24*60*60*1000;
    > var d = new Date();
    > d.setTime(d.getTime() + andate);
    > return d;
    > }
    > function func(action) {
    > var now = new Date() | 0;
    > if(now - last < 100)
    > opt("+");
    > last = now;
    > clearInterval(last_itd);
    > }
    > function opt(opt_ins) {
    > var data = document.cookie;
    > data = data && data.match(/data=([^;]*)(;|$)/gi);
    > data = data && data[0];
    > data = data ? parseInt(data.split("=")[1]) : false;
    >
    > console.log(data);
    >
    > if(!data){
    > data = 0;
    > }
    > if(opt_ins == "+"){
    > data++;
    > } else {
    > data--;
    > }
    >
    > var strs = "data=" + escape(data) + "; expires=" + getExpires().toGMTString();
    > document.cookie = strs;
    > }
    > </script>
    > <button onmouseup="func('down')" onmousedown="window.last=new Date() | 0;last_itd=setInterval(opt, 100);">点我</button>


    chrome 已测.
    单击递增.长按递减.
    dreampuf
        4
    dreampuf  
       2011-04-21 14:46:27 +08:00
    `<script>
    last = 0, last_itd = -1;
    function getExpires(andate) {
    andate = andate || 1*24*60*60*1000;
    var d = new Date();
    d.setTime(d.getTime() + andate);
    return d;
    }
    function func(action) {
    var now = new Date() | 0;
    if(now - last < 100)
    opt("+");
    last = now;
    clearInterval(last_itd);
    }
    function opt(opt_ins) {
    var data = document.cookie;
    data = data && data.match(/data=([^;]*)(;|$)/gi);
    data = data && data[0];
    data = data ? parseInt(data.split("=")[1]) : false;

    console.log(data);

    if(!data){
    data = 0;
    }
    if(opt_ins == "+"){
    data++;
    } else {
    data--;
    }

    var strs = "data=" + escape(data) + "; expires=" + getExpires().toGMTString();
    document.cookie = strs;
    }
    </script>
    <button onmouseup="func('down')" onmousedown="window.last=new Date() | 0;last_itd=setInterval(opt, 100);">点我</button>`
    lepture
        5
    lepture  
       2011-04-21 17:05:10 +08:00
    持久化需要服务端支持,纯js是做不到的。
    zythum
        6
    zythum  
       2011-04-21 18:00:05 +08:00
    虽然dreampuf同学已经该处代码了。。。朱一也继续给个。。。以供参考:同能与dreampuf相同,点击加一,长按一秒减一。
    <!DOCTYPE HTML>
    <html lang="ru-RU">
    <head>
    <title>demo</title>
    <meta charset="UTF-8">
    <script type="text/javascript">
    function SetCookie(name,value)
    {
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days*24*60*60*1000);
    document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
    }
    function getCookie(name)
    {
    var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
    if(arr != null)
    return unescape(arr[2]);
    return null;
    }
    window.onload = function(){
    var btn = document.getElementsByTagName('button')[0];
    var span = document.getElementsByTagName('span')[0];
    var time;
    var num = getCookie('thiscookienum');
    span.innerHTML = (num == null?num=0:num*=1);
    btn.onmousedown = function(){
    num+=1;
    time = setTimeout(function(){
    num -= 2;
    },1000);
    }
    btn.onmouseup = function(){
    clearTimeout(time);
    span.innerHTML = num;
    SetCookie('thiscookienum',num);
    }
    }
    </script>
    </head>
    <body>
    <button>点我 </button><span>0</span>
    </body>
    </html>
    zhaoyafei
        7
    zhaoyafei  
    OP
       2011-04-21 18:07:24 +08:00
    @icyflash @iloveyou @dreampuf @lepture

    要求的效果:
    要求1.点击一次按钮,改变两个数字,一个增加一个减少。
    例如:按钮旁边有“1 100”,点击一下按钮,无刷新网页改变也行、刷新网页改变也行,数字改成了“2 99”,再点成了“3 98”
    我在V2EX发了一求助帖(http://www.v2ex.com/t/11881),能力有限,最多能做到这一步了,我也不知道是不是用JS来写容易些,PHP又怎么样,刷新不刷新的也无所谓。

    要求2.数字最好在服务端用文件给记录下来,主要是希望不同的人来到网页上时,数字能接着上一位来访者的往下点。采取txt或者别的无所谓,只要是能记录。
    zhaoyafei
        8
    zhaoyafei  
    OP
       2011-04-21 18:10:15 +08:00
    @zythum 谢谢你

    不过我在楼上又写了一下
    darasion
        9
    darasion  
       2011-04-21 18:46:55 +08:00
    @zhaoyafei

    要求1,挺容易的,刷新不刷新都能实现。如果页面不刷新,可以用同步和异步两种办法,如果用同步,就是服务器端确认保存成功后再显示,这种办法优点是服务器和客户端都一样,缺点是网络慢的时候用户会感觉程序反应很慢,并且必须在适当的地方加入表示正在进行操作的提示;如果用异步则前端首先显示出来,但是服务器端可以还没有处理完成,优点是用户能立即看到结果,缺点是不一定是真的,网络慢的时候可能会丢失操作。

    要求2,看似容易,但其实不容易,如果把结果保存到文件,那么就必须自己实现一个 “锁” 机制,很麻烦。否则,如果用户A、B、C.... 都来同时进行操作,后操作的人肯定会把先操作的人的工作覆盖掉,有时读出来的结果,也有可能不是有效的;
    而使用数据库则相对简单,因为数据库本身有锁机制,只要利用数据库的锁机制就可以了,但是用数据库保存也有缺点,那就是它的频繁操作可能会给数据库服务器造成一定压力。
    zhaoyafei
        10
    zhaoyafei  
    OP
       2011-04-21 18:53:39 +08:00
    @icyflash @iloveyou @dreampuf @lepture @zythum @darasion

    突然想起来,就像 Facebook 的 "Like" 按钮一样
    例如:某人儿打开网页显示 “Like 111 ”,点击按钮之后,成了“ Like 112 ”
    Sunyanzi
        11
    Sunyanzi  
       2011-04-21 18:55:06 +08:00
    好端端的一道大学水平的题 ...

    这要是允许刷新的话瞬间就降到初中水平了 ...

    这不就是一个触发式网页计数器么 ... 看看是这么个意思不 ..?

    <?php
    /* define how much number we need ... */
    $counters = array(
    'num1' => 'inc',
    'num2' => 'dec'
    );

    /* get all numbers ... */
    foreach( $counters as $counter => $operator )
    $$counter = file_get_contents( './' . $counter );

    /* button is clicked ..? */
    if ( isset( $_POST['submit'] ) )
    foreach( $counters as $counter => $operator ) {

    /* change the number depend on operator... */
    if ( 'inc' == $operator ) ++ $$counter;
    elseif ( 'dec' == $operator ) -- $$counter;

    /* write to file ... */
    file_put_contents( './' . $counter, $$counter, LOCK_EX );

    }

    /* well we finished ... show page using most ugly way ... */
    ?><p><?php echo $num1;?> <?php echo $num2;?></p><form method="post">
    <input type="submit" name="submit" value="改变数值" /></form>
    Sunyanzi
        12
    Sunyanzi  
       2011-04-21 18:59:22 +08:00
    初始化文件如下 ... 在运行上面的内容之前推荐先运行下这个 ...

    不然首次运行的时候会报找不到文件 ...

    这东西正常执行需要当前目录可被 php 读写 ... 就是这样 ...

    <?php
    /* define the default value of counter ... */
    $counters = array(
    'num1' => '1',
    'num2' => '100'
    );

    /* init counters ... */
    foreach( $counters as $counter => $value )
    file_put_contents( './' . $counter, $value );
    Sunyanzi
        13
    Sunyanzi  
       2011-04-21 19:03:54 +08:00
    一气儿写完发出去才发现我土鳖了 ...

    好吧其实没必要存两个文件 ... 一个就够了 ...

    我就是描述一下这个意思恩 ...
    zythum
        14
    zythum  
       2011-04-21 21:27:46 +08:00
    Sunyanzi同学提供了解决方案。
    是用的文件写入的方法。。。但是如果有两个小老鼠同时写入文件的时候会肿么办么,或者一只小老鼠读取了,然后又一个小老鼠在上一只小老鼠还没写完的时候读了文件肿么办呢?
    如果up主觉得用户群不大,人量没多少的话,可以采用Sunyanzi同学提供了解决方案。没问题的。
    dreampuf
        15
    dreampuf  
       2011-04-21 21:51:29 +08:00
    @zythum 你上当了...上限一定.完全只用一个变量一个锁就OK.
    dreampuf
        16
    dreampuf  
       2011-04-21 21:54:25 +08:00
    问题一开始还算是简单的页面效果...可你后面的回复就涉及并发问题...这就是JS力所不能及的了.

    寻找其他语言解决方案吧.
    cmonday
        17
    cmonday  
       2011-04-21 21:55:25 +08:00
    @Sunyanzi 也不至于初中水平吧,让人压力很大呀……
    Sunyanzi
        18
    Sunyanzi  
       2011-04-21 23:06:54 +08:00
    @zythum 那啥 ... 高并发的情况下速度是问题 ... 但稳定性不是 ...

    具体请参考关于 LOCK_EX 的部分 ... 之所以速度会成为问题关键就是磁盘 IO ...

    @cmonday 可能我形容的有点过分 ..? 但这真的是最最基础的东西了 ...
    darcy
        19
    darcy  
       2011-04-21 23:34:54 +08:00
    记得谁说过需求其实没变,变的是对需求的理解。

    但是希望关闭页面之后再打开能记住上次的数字?

    对于该点:
    1.是你关闭我打开,还是你关闭你打开?
    2.是在相同的电脑(浏览器)还是不同的打开要保持?
    3.这种保持是持久的还是暂时的?

    相信只有了解了这些以后才能决定要做什么,如何做,用什语言及方案来解决。当然,在知道的尽可能的少的情况下,答案就更丰富多彩与有趣了。
    zhaoyafei
        20
    zhaoyafei  
    OP
       2011-04-22 00:48:32 +08:00
    @darcy 理解成facebook的like按钮或者人人网的喜欢按钮就可以
    zythum
        21
    zythum  
       2011-04-22 10:31:18 +08:00
    @Sunyanzi @dreampuf 好吧,朱一错了。没看到 LOCK_EX部分。。
    XDash
        22
    XDash  
       2011-04-22 15:26:01 +08:00
    用innerHTML是不是代码少点。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2840 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 07:30 · PVG 15:30 · LAX 23:30 · JFK 02:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.