如何使鼠标滚动不作用于特定文章?

时间:2019-03-02 20:35:01

标签: javascript jquery

作为示例,我将一个HTML网站上传到了测试域。这是它的地址:http://test.ooo-pnu.ru/

全屏站点,由三个块组成,用于演示。您可以使用鼠标滚轮或在触摸设备上滑动来滚动它们。

JS代码对此负责:

// ------------- VARIABLES ------------- //
var ticking = false;
var isFirefox = (/Firefox/i.test(navigator.userAgent));
var isIe = (/MSIE/i.test(navigator.userAgent)) || (/Trident.*rv\:11\./i.test(navigator.userAgent));
var scrollSensitivitySetting = 30; //Increase/decrease this number to change sensitivity to trackpad gestures (up = less sensitive; down = more sensitive) 
var slideDurationSetting = 600; //Amount of time for which slide is "locked"
var currentSlideNumber = 0;
var totalSlideNumber = $(".background").length;

// ------------- DETERMINE DELTA/SCROLL DIRECTION ------------- //
function parallaxScroll(evt) {
  if (isFirefox) {
    //Set delta for Firefox
    delta = evt.detail * (-120);
  } else if (isIe) {
    //Set delta for IE
    delta = -evt.deltaY;
  } else {
    //Set delta for all other browsers
    delta = evt.wheelDelta;
  }

  if (ticking != true) {
    if (delta <= -scrollSensitivitySetting) {
      //Down scroll
      ticking = true;
      if (currentSlideNumber !== totalSlideNumber - 1) {
        currentSlideNumber++;
        nextItem();
      }
      slideDurationTimeout(slideDurationSetting);
    }
    if (delta >= scrollSensitivitySetting) {
      //Up scroll
      ticking = true;
      if (currentSlideNumber !== 0) {
        currentSlideNumber--;
      }
      previousItem();
      slideDurationTimeout(slideDurationSetting);
    }
  }
}

// ------------- SET TIMEOUT TO TEMPORARILY "LOCK" SLIDES ------------- //
function slideDurationTimeout(slideDuration) {
  setTimeout(function() {
    ticking = false;
  }, slideDuration);
}

// ------------- ADD EVENT LISTENER ------------- //
var mousewheelEvent = isFirefox ? "DOMMouseScroll" : "wheel";
window.addEventListener(mousewheelEvent, _.throttle(parallaxScroll, 60), false);

// ------------- SLIDE MOTION ------------- //
function nextItem() {
  var $previousSlide = $(".background").eq(currentSlideNumber - 1);
  $previousSlide.removeClass("up-scroll").addClass("down-scroll");
}

function previousItem() {
  var $currentSlide = $(".background").eq(currentSlideNumber);
  $currentSlide.removeClass("down-scroll").addClass("up-scroll");
}


// SWIPE MODE Rodichev Vladimir
// at least 100 px are a swipe
// you can use the value relative to screen size: window.innerWidth * .1
const offset = 100;
let xDown, yDown

window.addEventListener('touchstart', e => {
  const firstTouch = getTouch(e);

  xDown = firstTouch.clientX;
  yDown = firstTouch.clientY;
});

window.addEventListener('touchend', e => {
  if (!yDown) {
    return;
  }

  const {
    clientY: yUp
  } = getTouch(e);
  const yDiff = yDown - yUp;
  const yDiffAbs = Math.abs(yDown - yUp);

  // at least <offset> are a swipe
  if (Math.max(yDiffAbs) < offset ) {
    return;
  }


    if ( yDiff > 0 ) {
      //Up scroll
      ticking = true;
      if (currentSlideNumber !== 0) {
        currentSlideNumber--;
      }
      previousItem();
      slideDurationTimeout(slideDurationSetting);
    } else {
      //Down scroll
      ticking = true;
      if (currentSlideNumber !== totalSlideNumber - 1) {
        currentSlideNumber++;
        nextItem();
      }
      slideDurationTimeout(slideDurationSetting);
    }
});

function getTouch (e) {
  return e.changedTouches[0]
}

我们走到最后一块,在其中插入了测试信息,并回顾了游戏《 Headhunter》,为了进行演示,信息也将使用鼠标滚轮水平滚动。

负责水平滚动块的代码”

function horizontalScroll(e){
  var that = this;
  that.elementWidth = that.elementWidth || getColumnWidth(that);

  var scrollDirection = ( e.wheelDeltaY )? (0 - e.wheelDeltaY) : ( e.detail),
      actualColumn = Math.round( that.scrollLeft / that.elementWidth),
      targetColumn = (scrollDirection > 0 )? actualColumn + 1 : actualColumn - 1;

  if(scrollElementToColumn( that, targetColumn )) e.preventDefault();

}

function getColumnWidth(that){
  var style = window.getComputedStyle(that, null);
  var columnWidth = parseFloat( style.columnWidth || style.MozColumnWidth || style.webkitColumnWidth );
  var columnGap = parseFloat( style.columnGap || style.MozColumnGap || style.webkitColumnGap );
  return columnWidth + columnGap;
}

function scrollElementToColumn(that, columnIndex){
  that.elementWidth = that.elementWidth || getColumnWidth(that);

  var expectedPlaceToScroll = Math.round(columnIndex * that.elementWidth),
      distanceToScroll = Math.abs( that.scrollLeft - expectedPlaceToScroll ),
      defaultScrollShift = 30,
      savedScrollLeft = that.scrollLeft,
      scrollShift = ( defaultScrollShift < distanceToScroll )? defaultScrollShift : distanceToScroll ;

  if(that.scrollLeft < expectedPlaceToScroll){
    that.scrollLeft = that.scrollLeft + scrollShift;
  }else if(that.scrollLeft > expectedPlaceToScroll){
    that.scrollLeft = that.scrollLeft - scrollShift;
  }

  if(that.scrollLeft !== expectedPlaceToScroll && savedScrollLeft !== that.scrollLeft ){
    that.actuallyMoving = setTimeout( function(){scrollElementToColumn( that, columnIndex )}, 10);
    return true;
  }

  if( that.actuallyMoving ) clearTimeout(that.actuallyMoving);
  return false;
}


document.addEventListener("DOMContentLoaded", function() {
  var elems = document.getElementsByClassName('mario');
  var i;
  for(i = 0, nb = elems.length; i < nb; i++){
    if (elems[i].addEventListener) {
      elems[i].addEventListener("mousewheel", horizontalScroll, false);// IE9, Chrome, Safari, Opera
      elems[i].addEventListener("DOMMouseScroll", horizontalScroll, false);// Firefox
    } else elems[i].attachEvent("onmousewheel", horizontalScroll);// IE 6/7/8
  }

  window.addEventListener('resize', function(e){
    console.log('resizing, i saw you !');
    for(i = 0, nb = elems.length; i < nb; i++){
      elems[i].elementWidth = getColumnWidth(elems[i]);
    }
  });
});

其中内容水平滚动的文章:

<article class="mario">

当鼠标滚轮在最后一个块中的内容上滚动时,如何使屏幕同时滚动?在这种情况下,您需要一个解决方案,以便也可以绕屏。到目前为止,我的想法是,当光标指向光标时,滚动屏幕在文章上不起作用,只有内容滚动有效,我们将光标从文章上移开,然后再次进行屏幕滚动。

在index.js中进行的更改:

// ------------- VARIABLES ------------- //
var isHorizontal = false;
var ticking = false;
var isFirefox = (/Firefox/i.test(navigator.userAgent));
var isIe = (/MSIE/i.test(navigator.userAgent)) || (/Trident.*rv\:11\./i.test(navigator.userAgent));
var scrollSensitivitySetting = 30; //Increase/decrease this number to change sensitivity to trackpad gestures (up = less sensitive; down = more sensitive) 
var slideDurationSetting = 600; //Amount of time for which slide is "locked"
var currentSlideNumber = 0;
var totalSlideNumber = $(".background").length;

// ------------- DETERMINE DELTA/SCROLL DIRECTION ------------- //
function parallaxScroll(evt) {
  if(isHorisontal) {
    isHorisontal = false;
    return;
  }
  if (isFirefox) {
    //Set delta for Firefox
    delta = evt.detail * (-120);
  } else if (isIe) {
    //Set delta for IE
    delta = -evt.deltaY;
  } else {
    //Set delta for all other browsers
    delta = evt.wheelDelta;
  }

  if (ticking != true) {
    if (delta <= -scrollSensitivitySetting) {
      //Down scroll
      ticking = true;
      if (currentSlideNumber !== totalSlideNumber - 1) {
        currentSlideNumber++;
        nextItem();
      }
      slideDurationTimeout(slideDurationSetting);
    }
    if (delta >= scrollSensitivitySetting) {
      //Up scroll
      ticking = true;
      if (currentSlideNumber !== 0) {
        currentSlideNumber--;
      }
      previousItem();
      slideDurationTimeout(slideDurationSetting);
    }
  }
}

// ------------- SET TIMEOUT TO TEMPORARILY "LOCK" SLIDES ------------- //
function slideDurationTimeout(slideDuration) {
  setTimeout(function() {
    ticking = false;
  }, slideDuration);
}

// ------------- ADD EVENT LISTENER ------------- //
var mousewheelEvent = isFirefox ? "DOMMouseScroll" : "wheel";
window.addEventListener(mousewheelEvent, _.throttle(parallaxScroll, 60), false);

// ------------- SLIDE MOTION ------------- //
function nextItem() {
  var $previousSlide = $(".background").eq(currentSlideNumber - 1);
  $previousSlide.removeClass("up-scroll").addClass("down-scroll");
}

function previousItem() {
  var $currentSlide = $(".background").eq(currentSlideNumber);
  $currentSlide.removeClass("down-scroll").addClass("up-scroll");
}


// SWIPE MODE Rodichev Vladimir
// at least 100 px are a swipe
// you can use the value relative to screen size: window.innerWidth * .1
const offset = 100;
let xDown, yDown

window.addEventListener('touchstart', e => {
  const firstTouch = getTouch(e);

  xDown = firstTouch.clientX;
  yDown = firstTouch.clientY;
});

window.addEventListener('touchend', e => {
  if (!yDown) {
    return;
  }

  const {
    clientY: yUp
  } = getTouch(e);
  const yDiff = yDown - yUp;
  const yDiffAbs = Math.abs(yDown - yUp);

  // at least <offset> are a swipe
  if (Math.max(yDiffAbs) < offset ) {
    return;
  }


    if ( yDiff > 0 ) {
      //Up scroll
      ticking = true;
      if (currentSlideNumber !== 0) {
        currentSlideNumber--;
      }
      previousItem();
      slideDurationTimeout(slideDurationSetting);
    } else {
      //Down scroll
      ticking = true;
      if (currentSlideNumber !== totalSlideNumber - 1) {
        currentSlideNumber++;
        nextItem();
      }
      slideDurationTimeout(slideDurationSetting);
    }
});

function getTouch (e) {
  return e.changedTouches[0]
}

horizo​​ntalscroll.js中的更改:

function horizontalScroll(e){
  isHorisontal = true;
  var that = this;
  that.elementWidth = that.elementWidth || getColumnWidth(that);

  var scrollDirection = ( e.wheelDeltaY )? (0 - e.wheelDeltaY) : ( e.detail),
      actualColumn = Math.round( that.scrollLeft / that.elementWidth),
      targetColumn = (scrollDirection > 0 )? actualColumn + 1 : actualColumn - 1;

  if(scrollElementToColumn( that, targetColumn )) { 
    e.preventDefault(); 
  } else {
    isHorisontal = false;
  }

}

function getColumnWidth(that){
  var style = window.getComputedStyle(that, null);
  var columnWidth = parseFloat( style.columnWidth || style.MozColumnWidth || style.webkitColumnWidth );
  var columnGap = parseFloat( style.columnGap || style.MozColumnGap || style.webkitColumnGap );
  return columnWidth + columnGap;
}

function scrollElementToColumn(that, columnIndex){
  that.elementWidth = that.elementWidth || getColumnWidth(that);

  var expectedPlaceToScroll = Math.round(columnIndex * that.elementWidth),
      distanceToScroll = Math.abs( that.scrollLeft - expectedPlaceToScroll ),
      defaultScrollShift = 30,
      savedScrollLeft = that.scrollLeft,
      scrollShift = ( defaultScrollShift < distanceToScroll )? defaultScrollShift : distanceToScroll ;

  if(that.scrollLeft < expectedPlaceToScroll){
    that.scrollLeft = that.scrollLeft + scrollShift;
  }else if(that.scrollLeft > expectedPlaceToScroll){
    that.scrollLeft = that.scrollLeft - scrollShift;
  }

  if(that.scrollLeft !== expectedPlaceToScroll && savedScrollLeft !== that.scrollLeft ){
    that.actuallyMoving = setTimeout( function(){scrollElementToColumn( that, columnIndex )}, 10);
    return true;
  }

  if( that.actuallyMoving ) clearTimeout(that.actuallyMoving);
  return false;
}


document.addEventListener("DOMContentLoaded", function() {
  var elems = document.getElementsByClassName('mario');
  var i;
  for(i = 0, nb = elems.length; i < nb; i++){
    if (elems[i].addEventListener) {
      elems[i].addEventListener("mousewheel", horizontalScroll, false);// IE9, Chrome, Safari, Opera
      elems[i].addEventListener("DOMMouseScroll", horizontalScroll, false);// Firefox
    } else elems[i].attachEvent("onmousewheel", horizontalScroll);// IE 6/7/8
  }

  window.addEventListener('resize', function(e){
    console.log('resizing, i saw you !');
    for(i = 0, nb = elems.length; i < nb; i++){
      elems[i].elementWidth = getColumnWidth(elems[i]);
    }
  });
});

1 个答案:

答案 0 :(得分:0)

对于您的test website,您可以进行以下调整:

index.js:

var isHorizontal = false; //Global variable

function parallaxScroll(evt) {
  if(isHorizontal) {
    isHorizontal = false;
    return;
  }

horisontalscroll.js:

function horizontalScroll(e){
  isHorizontal = true;    

  // skipped

  if(scrollElementToColumn( that, targetColumn )) { 
    e.preventDefault(); 
  } else {
    isHorizontal = false;
  }