首页 > 解决方案 > 如何“逆向工程”一个简单的反应组件到纯 jquery

问题描述

以下反应组件在这里:

http://engineering.kapost.com/2018/05/horizo​​ntal-react-component-slider/

反应组件的工作示例:https ://codesandbox.io/s/nkm614n740?from-embed

我一直在试图弄清楚如何将其转换为简化的 jquery 组件/函数,但我无法绕过一些开箱即用的反应功能。

下面是完整的代码:

this.state = {
  marginLeft: 0,
};

renderLeftArrow = () => {
  if (this.state.marginLeft !== 0) {
    return (
      <button className="caret caret-left" onClick={this.handleLeftClicked}>
        {this.props.renderLeftArrow()}
      </button>
    );
  }
  return null;
 }

const remainingWidth = contentWidth - (sliderWidth) - currentMarginLeft;

handleLeftClicked = () => {
  const currentMarginLeft = this.state.marginLeft;
  const sliderWidth = this.slider.offsetWidth;
  let marginLeft;

  if (currentMarginLeft > sliderWidth) {
    marginLeft = currentMarginLeft - sliderWidth;
  } else {
    marginLeft = 0;
  }
   this.setState({ marginLeft });
 }

handleRightClicked = () => {
  const currentMarginLeft = this.state.marginLeft;
  const sliderWidth = this.slider.offsetWidth
  const contentWidth = this.sliderContent.offsetWidth;
  const remainingWidth = contentWidth - (sliderWidth - arrowWidth) - currentMarginLeft;
  let marginLeft;


  if (remainingWidth > 0) {
    if (remainingWidth <= sliderWidth) {
      marginLeft = currentMarginLeft + remainingWidth;
    } else {
      marginLeft = currentMarginLeft + sliderWidth;
    }
  } else {
    marginLeft = currentMarginLeft;
  }
  this.setState({ marginLeft });
 };

componentDidMount() {
 window.addEventListener('resize', this.handleResize());
 this.resetMargin();
}

componentWillUnmount() {
 window.removeEventListener('resize', this.handleResize());
}

以下是我迄今为止通过“逆向工程”实现的目标。看起来它有点工作,但可以使用一些指针......

同样在 JSfiddle

$(".nav-menu").css('margin-left', '0px');
var navWrapper = $("#js-nav-menu-wrapper"),
  sliderWidth = navWrapper.outerWidth(),
  contentWidth = navWrapper.children('.nav-menu').outerWidth(),
  currentMarginLeft = parseFloat(navWrapper.children('.nav-menu').css('margin-left')),
  remainingWidth,
  setMargin;

var updateSlider = function() {


  if ('#js-nav-menu-wrapper') {
    sliderWidth = navWrapper.outerWidth();
    contentWidth = navWrapper.children('.nav-menu').outerWidth();
    currentMarginLeft = parseFloat(navWrapper.children('.nav-menu').css('margin-left'));
    remainingWidth = contentWidth - sliderWidth - currentMarginLeft;

    console.log(remainingWidth);
    return this;

  } else {
    navWrapper.children('.nav-menu').css('margin-left', '0px');
  }
};

var navMenuScrollRight = function() {

  updateSlider();

  if (currentMarginLeft > sliderWidth) {
    setMargin = currentMarginLeft - sliderWidth;
  } else {
    setMargin = 0;
  }

  navWrapper.children('.nav-menu').css({
    marginLeft: setMargin
  });

};

var navMenuScrollLeft = function() {

  updateSlider();

  if (remainingWidth > 0) {
    if (remainingWidth <= sliderWidth) {
      setMargin = currentMarginLeft + remainingWidth;
    } else {
      setMargin = currentMarginLeft + sliderWidth;
    }
  } else {
    setMargin = currentMarginLeft;
  }

  navWrapper.children('.nav-menu').css({
    marginLeft: setMargin
  });

};


$('#js-scroll-right').click(function() {

  navMenuScrollRight();

  event.preventDefault();
});

$('#js-scroll-left').click(function() {

  navMenuScrollLeft();

  event.preventDefault();
});
.main-menu {
  flex: 1;
  display: flex;
  align-items: stretch;
  overflow: initial;
  -ms-overflow-style: -ms-autohiding-scrollbar;
  transition: 1s all;
}

.nav-menu-wrapper {
  -webkit-box-flex: 0;
  -ms-flex: 0 1 100%;
  display: flex;
  flex: 0 1 100%;
  width: 0;
  overflow: hidden;
}

.nav-menu {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  -ms-flex: 0 1 100%;
  flex: 0 1 100%;
  transition: margin 0.5s ease-out 0s;
  list-style: none;
}

.nav-menu li {
  display: inline-flex;
  align-items: center;
  padding: 1rem;
  min-width: 100px;
  border: 1px solid #f3f3f3; 
}

.nav-padel-left,
.nav-padel-right {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width:50px;
  border: 1px solid;
  background-color: skyblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="main-menu">
  <div id="js-scroll-left" class="nav-padel-left"><<</div>
  <div id="js-nav-menu-wrapper" class="nav-menu-wrapper">
    <ul class="nav-menu js-nav-built" style="margin-left: 0px;">
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
      <li>Item 4</li>
      <li>Item 5</li>
      <li>Item 6</li>
      <li>Item 7</li>
      <li>Item 8</li>
      <li>Item 9</li>
      <li>Item 10</li>
      <li>Item 11</li>
      <li>Item 12</li>
      <li>Item 13</li>
      <li>Item 14</li>
      <li>Item 15</li>
    </ul>
  </div>
  <div id="js-scroll-right" class="nav-padel-left">>></div>
</div>

标签: javascriptjqueryreactjs

解决方案


好的,所以你的逻辑在我修复的某些点上颠倒了。一些注意事项:

  • 我不确定if ('#js-nav-menu-wrapper') {应该做什么,但它总是会评估为真。如果这是您出于某种原因确实想要检查的内容,请重新检查。

  • 大多数初始化变量都是不必要的,因为它们会在第一次updateSlider被调用时设置它们的值

这不是一个完整的版本,最后你应该在任一侧达到最大量时隐藏箭头,并在离开极端时再次显示它们。

$(".nav-menu").css('margin-left', '0px');
var navWrapper = $("#js-nav-menu-wrapper"),
  sliderWidth = navWrapper.outerWidth(),
  contentWidth = navWrapper.children('.nav-menu').outerWidth(),
  currentMarginLeft = parseFloat(navWrapper.children('.nav-menu').css('margin-left')),
  setMargin;

var max = (navWrapper.children('.nav-menu').outerWidth() - sliderWidth) * -1;

var updateSlider = function() {
  sliderWidth = navWrapper.outerWidth();
  contentWidth = navWrapper.children('.nav-menu').outerWidth();
  currentMarginLeft = parseFloat(navWrapper.children('.nav-menu').css('margin-left'));
};

var navMenuScrollRight = function() {

  updateSlider();

  if (currentMarginLeft * -1 + sliderWidth < contentWidth ) {
    setMargin = Math.max(currentMarginLeft - sliderWidth, max);
  } else {
    setMargin = currentMarginLeft;
  }

  navWrapper.children('.nav-menu').css({
    marginLeft: setMargin
  });

};

var navMenuScrollLeft = function() {

  updateSlider();

  if (currentMarginLeft < 0) {
    setMargin = Math.min(currentMarginLeft + sliderWidth, 0);
  } else {
    setMargin = currentMarginLeft;
  }

  navWrapper.children('.nav-menu').css({
    marginLeft: setMargin
  });

};


$('#js-scroll-right').click(function(e) {

  navMenuScrollRight();

  e.preventDefault();
});

$('#js-scroll-left').click(function(e) {

  navMenuScrollLeft();

  e.preventDefault();
});

从这里开始应该不难完成。祝你好运

小提琴链接:


推荐阅读