首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当菜单打开时,应该修复仅滚动侧边菜单div和其他菜单

问当菜单打开时,应该修复仅滚动侧边菜单div和其他菜单
EN

Stack Overflow用户
提问于 2017-03-14 11:16:33
回答 2查看 1.4K关注 0票数 1

我有一个侧边菜单,当它打开时,可以看到身体的一部分。我的侧边菜单可能很长,所以你可以在上面滚动。但当菜单在底部时,你就会在身体上滚动,我不想要这种行为。

类似于Scrolling only content div, others should be fixed,但我使用的是React。当我的侧边菜单关闭时,其他内容应该是可滚动的。将链接中的示例中的内容视为侧边菜单。到目前为止,我使用的是该答案提供的相同技术,但它很难看(有点jQuery):

代码语言:javascript
复制
preventOverflow = (menuOpen) => { // this is called when side menu is toggled
    const body = document.getElementsByTagName('body')[0]; // this should be fixed when side menu is open

    if (menuOpen) {
        body.className += ' overflow-hidden';
    } else {
        body.className = body.className.replace(' overflow-hidden', '');
    }
}

// css
.overflow-hidden {
    overflow-y: hidden;
}

我应该怎么处理Reactjs?

EN

回答 2

Stack Overflow用户

发布于 2017-03-14 11:45:18

ReactJS不能直接访问<body>元素,而这正是需要更改overflow-y样式的元素。因此,虽然您正在做的可能不是最漂亮的代码,但它也不是完全错误的。

我给出的唯一真正的建议是( CSS shudder)在主体上使用内联样式而不是类名,以避免引入声明。只要您的菜单是唯一负责更新overflow-y属性的对象,就没有理由不能对其使用内联样式。将其与?:运算符混和在一起会产生相当简单的代码:

代码语言:javascript
复制
body.style.overflowY = menuOpen ? "hidden" : "";

然后,您可以完全删除.overflow-hidden类。

如果出于某种原因,多个事物正在管理主体的溢出状态,您可能希望坚持使用类名,并为每个管理它的事物分配一个唯一的类名,如下所示:

代码语言:javascript
复制
if (menuOpen) {
    body.className += ' menu-open';
}
else {
    // Use some tricks from jQuery to remove the "menu-open" class more elegantly.
    var className = " " + body.className + " ";
    className = className.replace(" overflow-hidden ", " ").replace(/\s+/, " ");
    className = className.substr(1, className.length - 2);     
}

CSS:

代码语言:javascript
复制
body.menu-open {
    overflow-y: hidden;
}
票数 0
EN

Stack Overflow用户

发布于 2017-03-14 11:57:15

您应该在react中创建一个元组件来更改正文中的内容,以及更改文档标题之类的内容。我不久前做了一个,就是为了我自己。我将在这里添加它。

用法

代码语言:javascript
复制
render() {
    return (
        <div>
             <DocumentMeta bodyClasses={[isMenuOpen ? 'no-scroll' : '']} />
            ... rest of your normal code
        </div>
    )
}

DocumentMeta.jsx

代码语言:javascript
复制
import React from 'react';
import _ from 'lodash';
import withSideEffect from 'react-side-effect';

var HEADER_ATTRIBUTE = "data-react-header";
var TAG_NAMES = {
  META: "meta",
  LINK: "link",
};
var TAG_PROPERTIES = {
  NAME: "name",
  CHARSET: "charset",
  HTTPEQUIV: "http-equiv",
  REL: "rel",
  HREF: "href",
  PROPERTY: "property",
  CONTENT: "content"
};
var getInnermostProperty = (propsList, property) => {
  return _.result(_.find(propsList.reverse(), property), property);
};

var getTitleFromPropsList = (propsList) => {
  var innermostTitle = getInnermostProperty(propsList, "title");
  var innermostTemplate = getInnermostProperty(propsList, "titleTemplate");
  if (innermostTemplate && innermostTitle) {
      return innermostTemplate.replace(/\%s/g, innermostTitle);
  }
  return innermostTitle || "";
};
var getBodyIdFromPropsList = (propsList) => {
  var bodyId = getInnermostProperty(propsList, "bodyId");
  return bodyId;
};
var getBodyClassesFromPropsList = (propsList) => {
  return propsList
    .filter(props => props.bodyClasses && Array.isArray(props.bodyClasses))
    .map(props => props.bodyClasses)
    .reduce((classes, list) => classes.concat(list), []);
};
var getTagsFromPropsList = (tagName, uniqueTagIds, propsList) => {
  // Calculate list of tags, giving priority innermost component (end of the propslist)
  var approvedSeenTags = {};
  var validTags = _.keys(TAG_PROPERTIES).map(key => TAG_PROPERTIES[key]);

  var tagList = propsList
    .filter(props => props[tagName] !== undefined)
    .map(props => props[tagName])
    .reverse()
    .reduce((approvedTags, instanceTags) => {
      var instanceSeenTags = {};

      instanceTags.filter(tag => {
        for(var attributeKey in tag) {
          var value = tag[attributeKey].toLowerCase();
          var attributeKey = attributeKey.toLowerCase();

          if (validTags.indexOf(attributeKey) == -1) {
              return false;
          }
          if (!approvedSeenTags[attributeKey]) {
              approvedSeenTags[attributeKey] = [];
          }
          if (!instanceSeenTags[attributeKey]) {
              instanceSeenTags[attributeKey] = [];
          }

          if (!_.has(approvedSeenTags[attributeKey], value)) {
              instanceSeenTags[attributeKey].push(value);
              return true;
          }
          return false;
        }
      })
      .reverse()
      .forEach(tag => approvedTags.push(tag));

      // Update seen tags with tags from this instance
      _.keys(instanceSeenTags).forEach((attr) => {
        approvedSeenTags[attr] = _.union(approvedSeenTags[attr], instanceSeenTags[attr])
      });
      instanceSeenTags = {};
      return approvedTags;
    }, []);
  return tagList;
};
var updateTitle = title => {
  document.title = title || document.title;
};
var updateBodyId = (id) => {
  document.body.setAttribute("id", id);
};
var updateBodyClasses = classes => {
  document.body.className = "";
  classes.forEach(cl => {
    if(!cl || cl == "") return;
    document.body.classList.add(cl);
  });
};
var updateTags = (type, tags) => {
  var headElement = document.head || document.querySelector("head");
  var existingTags = headElement.querySelectorAll(`${type}[${HEADER_ATTRIBUTE}]`);
  existingTags = Array.prototype.slice.call(existingTags);
  // Remove any duplicate tags
  existingTags.forEach(tag => tag.parentNode.removeChild(tag));

  if (tags && tags.length) {
    tags.forEach(tag => {
      var newElement = document.createElement(type);
      for (var attribute in tag) {
        if (tag.hasOwnProperty(attribute)) {
            newElement.setAttribute(attribute, tag[attribute]);
        }
      }
      newElement.setAttribute(HEADER_ATTRIBUTE, "true");
      headElement.insertBefore(newElement, headElement.firstChild);
    });
  }
};
var generateTagsAsString = (type, tags) => {
  var html = tags.map(tag => {
  var attributeHtml = Object.keys(tag)
    .map((attribute) => {
        const encodedValue = HTMLEntities.encode(tag[attribute], {
            useNamedReferences: true
        });
        return `${attribute}="${encodedValue}"`;
    })
    .join(" ");
    return `<${type} ${attributeHtml} ${HEADER_ATTRIBUTE}="true" />`;
  });
  return html.join("\n");
};

var reducePropsToState = (propsList) => ({
  title: getTitleFromPropsList(propsList),
  metaTags: getTagsFromPropsList(TAG_NAMES.META, [TAG_PROPERTIES.NAME, TAG_PROPERTIES.CHARSET, TAG_PROPERTIES.HTTPEQUIV, TAG_PROPERTIES.CONTENT], propsList),
  linkTags: getTagsFromPropsList(TAG_NAMES.LINK, [TAG_PROPERTIES.REL, TAG_PROPERTIES.HREF], propsList),
  bodyId: getBodyIdFromPropsList(propsList),
  bodyClasses: getBodyClassesFromPropsList(propsList),
});
var handleClientStateChange = ({title, metaTags, linkTags, bodyId, bodyClasses}) => {
  updateTitle(title);
  updateTags(TAG_NAMES.LINK, linkTags);
  updateTags(TAG_NAMES.META, metaTags);
  updateBodyId(bodyId);
  updateBodyClasses(bodyClasses)
};
var mapStateOnServer = ({title, metaTags, linkTags}) => ({
  title: HTMLEntities.encode(title),
  meta: generateTagsAsString(TAG_NAMES.META, metaTags),
  link: generateTagsAsString(TAG_NAMES.LINK, linkTags)
});

var DocumentMeta = React.createClass({
  propTypes: {
    title: React.PropTypes.string,
    titleTemplate: React.PropTypes.string,
    meta: React.PropTypes.arrayOf(React.PropTypes.object),
    link: React.PropTypes.arrayOf(React.PropTypes.object),
    children: React.PropTypes.oneOfType([
        React.PropTypes.object,
        React.PropTypes.array
    ]),
    bodyClasses: React.PropTypes.array,
  },
  render() {
    if (Object.is(React.Children.count(this.props.children), 1)) {
        return React.Children.only(this.props.children);
    } else if (React.Children.count(this.props.children) > 1) {
        return (
            <span>
                {this.props.children}
            </span>
        );
    }
    return null;
  },
});
DocumentMeta = withSideEffect(reducePropsToState, handleClientStateChange, mapStateOnServer)(DocumentMeta);
module.exports = DocumentMeta;

这个组件可能会根据您的情况稍作更改(withSideEffect同时用于客户端和服务器端呈现...如果你不使用服务器端渲染,那么它可能不是完全必要的),但如果你想在客户端渲染,组件将会工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42777171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档