最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using mouse wheel to scroll in Sencha Touch application on desktop - Stack Overflow

programmeradmin3浏览0评论

While looking for how to enable scrolling with the mouse wheel in Sencha Touch, I came across this answer. However, I am relatively new to Sencha Touch and the codebase I was given to maintain that uses it.

The answer says to put it in the initialization block of my application: as far as I can tell, that would be my app.js file that is generated by Sencha Cmd (which has a launch function). However, I'm lost after this. Would I add the first part of the above answer in the launch block? Outside of it? How would I make sure that it is automatically called on every page?

Edit: Here is my app.js file, in case it helps.

Ext.application({
    name: 'App',

    requires: [
        'Ext.MessageBox',
        'Ext.direct.*'
    ],

    models:[
        "..."
    ],

    controllers: [
        '...',
        '...',
        '...'
    ],

    icon: {
        '57': 'resources/icons/Icon.png',
        '72': 'resources/icons/Icon~ipad.png',
        '114': 'resources/icons/[email protected]',
        '144': 'resources/icons/[email protected]'
    },

    isIconPreposed: true,

    startupImage: {
        '320x460': 'resources/startup/320x460.jpg',
        '640x920': 'resources/startup/640x920.png',
        '768x1004': 'resources/startup/768x1004.png',
        '748x1024': 'resources/startup/748x1024.png',
        '1536x2008': 'resources/startup/1536x2008.png',
        '1496x2048': 'resources/startup/1496x2048.png'
    },

    profiles: ['Tablet', 'Phone'],

    launch: function() {

        ...
    }

    ....

});

Edit 2: I am using Sencha Touch 2.3.

While looking for how to enable scrolling with the mouse wheel in Sencha Touch, I came across this answer. However, I am relatively new to Sencha Touch and the codebase I was given to maintain that uses it.

The answer says to put it in the initialization block of my application: as far as I can tell, that would be my app.js file that is generated by Sencha Cmd (which has a launch function). However, I'm lost after this. Would I add the first part of the above answer in the launch block? Outside of it? How would I make sure that it is automatically called on every page?

Edit: Here is my app.js file, in case it helps.

Ext.application({
    name: 'App',

    requires: [
        'Ext.MessageBox',
        'Ext.direct.*'
    ],

    models:[
        "..."
    ],

    controllers: [
        '...',
        '...',
        '...'
    ],

    icon: {
        '57': 'resources/icons/Icon.png',
        '72': 'resources/icons/Icon~ipad.png',
        '114': 'resources/icons/[email protected]',
        '144': 'resources/icons/[email protected]'
    },

    isIconPreposed: true,

    startupImage: {
        '320x460': 'resources/startup/320x460.jpg',
        '640x920': 'resources/startup/640x920.png',
        '768x1004': 'resources/startup/768x1004.png',
        '748x1024': 'resources/startup/748x1024.png',
        '1536x2008': 'resources/startup/1536x2008.png',
        '1496x2048': 'resources/startup/1496x2048.png'
    },

    profiles: ['Tablet', 'Phone'],

    launch: function() {

        ...
    }

    ....

});

Edit 2: I am using Sencha Touch 2.3.

Share Improve this question edited Jul 29, 2017 at 13:58 Cœur 38.8k25 gold badges205 silver badges277 bronze badges asked Mar 5, 2015 at 16:24 filpafilpa 3,6649 gold badges56 silver badges102 bronze badges 1
  • I moved your solution to a Community wiki answer. – Cœur Commented Jul 29, 2017 at 14:00
Add a ment  | 

4 Answers 4

Reset to default 4

The provided code in the other answer is pure Javascript and not ExtJs code, it runs in a global scope so you can add this above Ext.application (outside of ExtJs code, so make it your first bit of JS code that gets run). You could even wrap it inside an Ext.onReady call to make sure ExtJs is also fully loaded before you add it, if needed.

This should work, it might be worth looking over the Sencha forums or even on here for a more elegant and updated solution though.

The OP's answer above works, however it throws errors if trying to scroll over elements that do not have indexOf on their className (like SVG elements). Here is the updated code that first checks for the existence of indexOf.

I've also extended this method to support horizontal mouse scrolling if the browser supports wheelDeltaX and wheelDeltaY. Otherwise it defaults to using the more widely available wheelDelta and only scrolls in the Y direction.

Note that you can embed this code in a function and simply call it during the launch of your app. No need to put it at the top of the app.js file.

        var mouseWheelHandler = function (e) {
            var e = window.event || e,
                el = e.target,
                cmp,
                offset,
                scroller,
                deltaY,
                deltaX,
                _results = [];
            e.preventDefault(); // prevent scrolling when in iframe
            while (el !== document.body) {
                if (el && el.className && el.className.indexOf && el.className.indexOf('x-container') >= 0) {
                    cmp = Ext.getCmp(el.id);
                    if (cmp && typeof cmp.getScrollable == 'function' && cmp.getScrollable()) {
                        scroller = cmp.getScrollable().getScroller();

                        if (scroller) {
                            deltaY = e.detail ? e.detail * (-120) : e.hasOwnProperty('wheelDeltaY') ? e.wheelDeltaY : e.wheelDelta;
                            deltaX = e.detail ? e.detail * (-120) : e.hasOwnProperty('wheelDeltaX') ? e.wheelDeltaX : 0; 
                            offset = {x: -deltaX * 0.5, y: -deltaY * 0.5};
                            scroller.fireEvent('scrollstart', scroller, scroller.position.x, scroller.position.y, e);
                            scroller.scrollBy(offset.x, offset.y);
                            scroller.snapToBoundary();
                            scroller.fireEvent('scrollend', scroller, scroller.position.x + offset.x, scroller.position.y - offset.y);
                            break;
                        }
                    }
                }
                _results.push(el = el.parentNode);
            }
            return _results;
        };

        if (document.addEventListener) {
            // IE9, Chrome, Safari, Opera
            document.addEventListener('mousewheel', mouseWheelHandler, false);
            // Firefox
            document.addEventListener('DOMMouseScroll', mouseWheelHandler, false);
        }
        else {
            // IE 6/7/8
            document.attachEvent('onmousewheel', mouseWheelHandler);
        }
    }

Thanks user991710 and Scriptable for your answer. In my case i added the entire code within the Ext.onReady event because it didn't work in the app.js.

Below is how i have incorporated the code in the Ext.onReady in the default.js

      onReady: function() {
        if (this.getAutoRender()) {
            this.render();
        }
        if (Ext.browser.name == 'ChromeiOS') {
            this.setHeight('-webkit-calc(100% - ' + ((window.outerHeight - window.innerHeight) / 2) + 'px)');
        }

        /* code ten behoeve van mousescroll in Chrome situatie */
        var mouseWheelHandler = function (e) {
            var e = window.event || e,
el = e.target,
cmp,
offset,
scroller,
delta,
_results = [];
            e.preventDefault(); // prevent scrolling when in iframe
            while (el !== document.body) {
                if (el && el.className && el.className.indexOf('x-container') >= 0) {
                    cmp = Ext.getCmp(el.id);
                    if (cmp && typeof cmp.getScrollable == 'function' && cmp.getScrollable()) {
                        scroller = cmp.getScrollable().getScroller();
                        if (scroller) {
                            delta = e.detail ? e.detail * (-120) : e.wheelDelta;
                            offset = { x: 0, y: -delta * 0.5 };
                            scroller.fireEvent('scrollstart', scroller, scroller.position.x, scroller.position.y, e);
                            scroller.scrollBy(offset.x, offset.y);
                            scroller.snapToBoundary();
                            scroller.fireEvent('scrollend', scroller, scroller.position.x, scroller.position.y - offset.y);
                            break;
                        }
                    }
                }
                _results.push(el = el.parentNode);
            }
            return _results;
        };

        if (document.addEventListener) {
            // IE9, Chrome, Safari, Opera
            document.addEventListener('mousewheel', mouseWheelHandler, false);
            // Firefox
            document.addEventListener('DOMMouseScroll', mouseWheelHandler, false);
        }
        else {
            // IE 6/7/8
            document.attachEvent('onmousewheel', mouseWheelHandler);
        }
        /*einde code ten behoeve van muisscroll in Chrome modus */
    },

Solution by OP.

In my app.js file (the one generated by Sencha Cmd), I added the following code at the very top of the file, before my Ext.application definition:

var mouseWheelHandler = function (e) {
    var e = window.event || e,
        el = e.target,
        cmp,
        offset,
        scroller,
        delta,
        _results = [];
    e.preventDefault(); // prevent scrolling when in iframe
    while (el !== document.body) {
        if (el && el.className && el.className.indexOf('x-container') >= 0) {
            cmp = Ext.getCmp(el.id);
            if (cmp && typeof cmp.getScrollable == 'function' && cmp.getScrollable()) {
                scroller = cmp.getScrollable().getScroller();
                if (scroller) {
                    delta = e.detail ? e.detail*(-120) : e.wheelDelta;
                    offset = { x:0, y: -delta*0.5 };
                    scroller.fireEvent('scrollstart', scroller, scroller.position.x, scroller.position.y, e);
                    scroller.scrollBy(offset.x, offset.y);
                    scroller.snapToBoundary();
                    scroller.fireEvent('scrollend', scroller, scroller.position.x, scroller.position.y-offset.y);
                    break;
                }
            }
        }
    _results.push(el = el.parentNode);
    }
    return _results;
};

if (document.addEventListener) {
    // IE9, Chrome, Safari, Opera
    document.addEventListener('mousewheel', mouseWheelHandler, false);
    // Firefox
    document.addEventListener('DOMMouseScroll', mouseWheelHandler, false);
}

Credit to the above code goes to user m.dostal on the Sencha Touch forums. If you happen across this solution, please upvote user Scriptable below as he helped me find the correct solution.

发布评论

评论列表(0)

  1. 暂无评论