使用iPhone的加速度计滚动网页

时间:2014-05-08 13:29:05

标签: javascript html cordova scroll accelerometer

为学校工作,我正在尝试使用加速计来滚动网页。

我希望能够滚动到页面的顶部和底部。这可以通过倾斜iPhone来实现。

我使用Cordova作为libirarie来访问加速度计。

http://cordova.apache.org/docs/en/3.3.0/cordova_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration

但我被困了。

我总是得到一个未被捕获的typeError,所以我没有得到加速度计的值。

另一个问题是我不知道如何使用加速度计的值并将其用于在网页上滚动。

<header class="meta">
        <h1><i class="fa fa-flask"></i> Use a sensor</h1>
    </header>

    <main>
        <div class="container">
            <section data-route="some-section" class="front-panel">

                <article>
                    <header>
                        <h1>Instructions</h1>
                    </header>
                    <div id="accelerometer">Waiting for accelerometer...</div>                      
                </article>
            </section>

            <section data-route="some-other-section" class="back-panel">
                <figure>
                    <img src="media/some-other-picture.jpg" alt="a picture">
                </figure>

                <header>
                    <h1>Some other section</h1>
                </header>

                <article>
                    <header>
                        <h1>
                            Some other article
                        </h1>
                    </header>
                </article>
            </section>
        </div>
    </main>

    <footer class="meta">
        <nav>
            <ul>
                <li><a href="#/some-section"><i class="fa fa-hand-o-left"></i></a></li>
                <li><a href="#/some-other-section"><i class="fa fa-hand-o-right"></i></a></li>
            </ul>
        </nav>
    </footer>
    <script src="cordova.js"></script>
    <script src="static/js/vendor/routie.min.js"></script>
    <script src="static/js/script.js"></script>

//self-invoking anonymous function

(函数(){     'use strict';

var scrollTop   = document.body.scrollTop,
    el          = document.body,
    els         = document.querySelectorAll('.meta'),
    position    = el.scrollTop,
    oHeight     = el.offsetHeight,
    wHeight     = window.innerHeight,
    $, $$;

//initialize app with an controller object literal
var app = {
    //init method, Cordova is ready to be used
    init: function() {
        this.router();

        accelerometer.begin();

        document.addEventListener('gesturechange', this, false);
        document.addEventListener('scroll', this, false);            

    },

    router: function() {
        routie({
            '/some-section': function() {
                section.toggle('some-section');
            },
            '/some-other-section': function(route) {
                section.toggle('some-other-section');
            }
        });
    },

    handleEvent: function(e) {
        var scroll = el.scrollTop,
            i = 0, 
            l = els.length;

        if (scroll > position && (scroll + wHeight) < oHeight && position > 0) {
            // scrolling Down
            for (;i < l;i++) {
                els[i].classList.add('shrink');
            };
        } else {
            // scrolling Up
            for (;i < l;i++) {
                els[i].classList.remove('shrink');
            };
        }
        position = scroll;
    },

};

var section = {
    toggle: function(route) {
        var panel   = $('[data-route='+ route +']'),
            front   = /front-panel/.test(panel.className);

        this.fp = $('.front-panel');
        this.bp = $('.back-panel');

        this.bp.addEventListener('webkitTransitionEnd',this,false)

        if(!(panel == this.fp)){
            this.fp.classList.add('out');
            this.bp.classList.remove('back-panel');
            this.bp.classList.add('front-panel');
        } else {
            // to do: active navigation
        }
    },

    handleEvent: function() {
        this.fp.classList.remove('out','front-panel');
        this.fp.classList.add('back-panel');
    }
};

// utilities object for common thingies
var utils = {
    init: function() {
        // Shorthand selectors
        $  = this.selectElement, 
        $$ = this.selectElements;
    },
    selectElement: function(el) {
        return document.querySelector(el);
    },
    selectElements: function(el) {
        return document.querySelectorAll(el);
    }
};

var accelerometer = {
    begin: function () {
        //update accleration every 100 of a second
        var options = {
            frequency: 100
        };

        watchID = navigator.accelerometer.watchAcceleration(this.success, debug.fail, options);
    },
    // Stop watching the acceleration
    stop: function () {
        if (watchID) {
            navigator.accelerometer.clearWatch(watchID);
            watchID = null;
        }
    },
    // onSuccess: Get a snapshot of the current acceleration
    success: function (acceleration) {
        var element = document.getElementById('accelerometer');
        element.innerHTML = 'Acceleration X: ' + acceleration.x + '<br />'+
                            'Acceleration Y: ' + acceleration.y + '<br />'+
                            'Acceleration Z: ' + acceleration.z + '<br />'+
                            'Timestamp: '      + acceleration.timestamp + '<br />';
    }
};

var debug = {
    fail: function () {
        alert('onError!');
    }
};    

utils.init();
app.init();

})();

任何帮助都会很棒!

3 个答案:

答案 0 :(得分:1)

看起来有人实现了我的想法。好。但实际上你的代码对我来说看起来并不复杂。 事实上,我在Blackberry Z3设备上实现了这个想法。而且效果很好。 我使用了BB WebWorks HTML5。 这是代码。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>

<!-- Including cordova library -->
<script src="cordova.js"></script> 

<script>

//attaching devieready event to the document
document.addEventListener("deviceready", status, false);

//evaluating function when devide is ready
function status()
{
function accelerometerCallback(data)
{
    //displaying actual accelerometer data
    var dy = data.y;
    document.getElementById("ydata").innerHTML = dy;

    //defining a scrolly variable and assigned the accelerometer data
    var scrolly = dy;


    if(dy < -1) //if the phone is tilted upward than normal, scroll the page all the        way to top with great speed.
    {
        window.scrollBy(0,scrolly*100);
    }


    if(dy > 9) // if the phone is tilted downward (almost vertically), scroll the page all the way down with great speed.
    {
        window.scrollBy(0,scrolly*20);
    }

    //scroll the page with human-readable speed (almost slow)
    window.scrollBy(0,scrolly-5);
}

//attaching accelerometer data event to the document
document.addEventListener("deviceaccelerometer", accelerometerCallback);
}
</script>

</head>

<body>
<!-- Displaying the actual accelerometer "y" direction data -->
<h1 id="ydata"></h1>

<!--Add some dummy data to the test how the gravity scrolling works -->
<div style="font-size:36px">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).


Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.

The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.


Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).


Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.

The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.
</div>
</body>
</html>

答案 1 :(得分:0)

我花了3天时间,但是我自己开始工作了,真棒!

//self-invoking anonymous function

(函数(){     &#39;使用严格的&#39;;

var scrollTop   = document.body.scrollTop,
    el          = document.body,
    els         = document.querySelectorAll('.meta'),
    position    = el.scrollTop,
    oHeight     = el.offsetHeight,
    wHeight     = window.innerHeight,
    $, $$;

var watchID = null;

//initialize app with an controller object literal
var app = {
    //initialize method, Cordova is ready to be used
    init: function() {
        this.router();

        document.addEventListener('gesturechange', this, false);
        document.addEventListener('scroll', this, false);
        document.addEventListener("deviceready", accelerometer.ready, false);
    },

    router: function() {
        routie({
            '/some-section': function() {
                section.toggle('some-section');
            },
            '/some-other-section': function(route) {
                section.toggle('some-other-section');
            }
        });
    },

    handleEvent: function(e) {
        var scroll = el.scrollTop,
            i = 0, 
            l = els.length;

        if (scroll > position && (scroll + wHeight) < oHeight && position > 0) {
            // scrolling Down
            for (;i < l;i++) {
                els[i].classList.add('shrink');
            };
        } else {
            // scrolling Up
            for (;i < l;i++) {
                els[i].classList.remove('shrink');
            };
        }
        position = scroll;
    },

};

var section = {
    toggle: function(route) {
        var panel   = $('[data-route='+ route +']'),
            front   = /front-panel/.test(panel.className);

        this.fp = $('.front-panel');
        this.bp = $('.back-panel');

        this.bp.addEventListener('webkitTransitionEnd',this,false)

        if(!(panel == this.fp)){
            this.fp.classList.add('out');
            this.bp.classList.remove('back-panel');
            this.bp.classList.add('front-panel');
        } else {
            // to do: active navigation
        }
    },

    handleEvent: function() {
        this.fp.classList.remove('out','front-panel');
        this.fp.classList.add('back-panel');
    }
};

// utilities object for common thingies
var utils = {
    init: function() {
        // Shorthand selectors
        $  = this.selectElement, 
        $$ = this.selectElements;
    },
    selectElement: function(el) {
        return document.querySelector(el);
    },
    selectElements: function(el) {
        return document.querySelectorAll(el);
    }
};

var accelerometer = {
    ready: function() {
        accelerometer.begin();
    },

    begin: function () {

        //update accleration every 100 of a second
        var options = {
            frequency: 100
        };

        watchID = navigator.accelerometer.watchAcceleration(this.success, debug.fail, options);
    },        
    // Stop watching the acceleration
    stop: function () {
        if (watchID) {
            navigator.accelerometer.clearWatch(watchID);
            watchID = null;
        }
    },
    // onSuccess: Get a snapshot of the current acceleration
    success: function (acceleration) {
        var element = document.getElementById('accelerometer');
        element.innerHTML = 'Acceleration X: ' + acceleration.x + '<br />'+
                            'Acceleration Y: ' + acceleration.y + '<br />'+
                            'Acceleration Z: ' + acceleration.z + '<br />'+
                            'Timestamp: '      + acceleration.timestamp + '<br />';

        //starts scrolling up when the acceleration.y is bigger then 7 and
        //scrolls down when the acceleration.y lower is then 2 AWESOME!!!
       if (acceleration.y > 7.0) {
            window.scrollBy(0, -5);
       } else if (acceleration.y < 2.0) {
            window.scrollBy(0, 5);
       }
    }
};

var debug = {
    fail: function () {
        alert('onError!');
    }
};    

utils.init();
app.init();

})();

答案 2 :(得分:-1)

我不知道加速度计。但我希望make内容可以滚动使用顺畅使用isroll插件并检测单个和多个手指滑动,捏合并回落到鼠标&#39; drags&#39;在桌面上。

iscroll

TouchSwipe

TouchSwipe demo