javascript - 如何“逆向工程”一个简单的反应组件到纯 jquery
问题描述
以下反应组件在这里:
http://engineering.kapost.com/2018/05/horizontal-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());
}
以下是我迄今为止通过“逆向工程”实现的目标。看起来它有点工作,但可以使用一些指针......
$(".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>
解决方案
好的,所以你的逻辑在我修复的某些点上颠倒了。一些注意事项:
我不确定
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();
});
从这里开始应该不难完成。祝你好运
推荐阅读
- laravel - Laravel FakeID 问题缺少路由所需的参数
- python - 如何从输出中删除最后一个逗号
- r - 在R中附加来自多个Excel文件的多个工作表
- dart - 无法在 dart 中声明二维列表并向其输入元素
- python - 如何根据 tkinter 应用程序中的用户输入更改标签?
- python - 如何从 sympy 方程中提取多项式和非多项式部分?
- python - 如何使用 3 个函数调用一个类?
- aslr - 如何为我的 wpf .net 核心应用程序启用 DEP 和 ASLR 标志?
- android - 获取要在片段中显示的 ListView (Kotlin)
- laravel-8 - 此路由不支持 GET 方法。支持的方法:POST。在 laravel8