浏览代码

滚动条弹窗调整

Luolei 6 年之前
父节点
当前提交
a99d722b95

+ 21 - 9
src/common/components/DropList/index.jsx

@@ -1,5 +1,6 @@
 import React,{Component} from 'react';
 import classNames from 'classnames';
+import ReactDom from "react-dom";
 
 import style from "./index.less";
 /****
@@ -23,6 +24,14 @@ class DropList extends Component{
     let isHide = this.props.show?'':style['hide'];
     return classNames(style['list'],name,isHide);
   }
+  
+  getStyle(){
+    const {left,top} = this.props;
+    return {
+      left:left?left+'px':'',
+      top:top?top+'px':''
+    }
+  }
   handleSelect(e,item){
     e.stopPropagation();
     const {onSelect} = this.props;
@@ -35,15 +44,18 @@ class DropList extends Component{
   }
   render(){
     const {data} = this.props;
-    return <div className={this.getClass()} contentEditable='false'>
-      <ul>
-        {data&&data.map((it)=>{
-          /*return <li onClick={(e)=>this.handleSelect(e,it)} className={it.selected||(it.selected!==false&&+it.defaultSelect===1)?style['selected']:''}>{it.labelPrefix}{it.questionDetailList&&it.questionDetailList.length>0?it.questionDetailList[0].name:it.name}{it.labelSuffix}</li>*/
-          return <li onClick={(e)=>this.handleSelect(e,it)} className={it.selected||(it.selected!==false&&+it.defaultSelect===1)?style['selected']:''}>{it.labelPrefix}{it.name}{it.labelSuffix}</li>
-        })}
-        <li onClick={(e)=>this.handleClear(e)} className='red'>清空选项</li>
-      </ul>
-    </div>
+    const domNode = document.getElementById('root');
+    return ReactDom.createPortal(
+      <div className={this.getClass()} style={this.getStyle()} contentEditable='false'>
+        <ul>
+          {data&&data.map((it)=>{
+            /*return <li onClick={(e)=>this.handleSelect(e,it)} className={it.selected||(it.selected!==false&&+it.defaultSelect===1)?style['selected']:''}>{it.labelPrefix}{it.questionDetailList&&it.questionDetailList.length>0?it.questionDetailList[0].name:it.name}{it.labelSuffix}</li>*/
+            return <li onClick={(e)=>this.handleSelect(e,it)} className={it.selected||(it.selected!==false&&+it.defaultSelect===1)?style['selected']:''}>{it.labelPrefix}{it.name}{it.labelSuffix}</li>
+          })}
+          <li onClick={(e)=>this.handleClear(e)} className='red'>清空选项</li>
+        </ul>
+      </div>
+    ,domNode)
   }
 }
 

+ 1 - 2
src/common/components/EditableSpan/index.jsx

@@ -1,7 +1,7 @@
 import React,{Component} from 'react';
 import style from './index.less';
 import config from "@config/index";
-import {filterArr,isIE} from '@utils/tools.js';
+import {filterArr,isIE,getPageCoordinate} from '@utils/tools.js';
 import Notify from '../Notify/index.js';
 
 import $ from 'jquery';
@@ -196,7 +196,6 @@ class EditableSpan extends Component{
       },this);
     }
   }
-
   render() {
     return <span className={style['editable-span']+(this.props.full?' '+style['full']:'')}
                       contentEditable='true'

+ 2 - 2
src/common/components/NumberPan/index.jsx

@@ -50,8 +50,8 @@ class NumberPan extends Component{
   getStyle(){
     const {left,top,show} = this.props;
     return {
-      left:left?left:'0',
-      top:top?top:'0',
+      left:left?left+'px':'0',
+      top:top?top+'px':'0',
       display:show?'table':'none'        //table onBlur阻止冒泡是为了修复multSpread中数字键盘点击触发最外层数字组件onBlur事件
     }
   }

+ 1 - 1
src/common/js/func.js

@@ -173,7 +173,7 @@ export const getWindowInnerHeight = ()=>{
   }
 };
 export const getWindowInnerWidth = ()=>{
-  let width = document.body.clientWidth || document.documentElement.clientWidth 
+  let width = window.innerWidth || document.body.clientWidth || document.documentElement.clientWidth 
   return width
 };
 

+ 25 - 11
src/components/CheckBody/index.jsx

@@ -3,35 +3,38 @@ import style from './index.less';
 import {Button,InlineTag,ItemBox,EditableSpan,Notify} from '@commonComp';
 import chooseType from '@containers/eleType.js';
 import SearchDrop from '@components/SearchDrop';
-import {getPageCoordinate} from '@utils/tools';
+import {getPageCoordinate,windowEventHandler} from '@utils/tools';
+import $ from "jquery";
 
 class CheckBody extends Component{
   constructor(props){
     super(props);
     this.state={
       boxMark:'4',
-      boxLeft:'0px',
-      boxTop:'0px'
+      boxLeft:0,
+      boxTop:0,
+      tmpScroll:0,
+      tmpTop:0,
     };
     this.handleClick = this.handleClick.bind(this);
     this.handleSearchSelect = this.handleSearchSelect.bind(this);
     this.getData = this.getData.bind(this);
     //this.handleInput = this.handleInput.bind(this);
   }
-  getLabels(boxLeft,boxTop){
+  getLabels(){
     const {data,showArr,saveText,selecteds} = this.props;
     let arr = [],list=[];
     const {boxMark} = this.state;
     if(data){
       list = data;
       arr = list.map((it,i)=>{
-        return chooseType({item:it,boxMark,i,showArr,saveText,selecteds,boxLeft,boxTop});
+        return chooseType({item:it,boxMark,i,showArr,saveText,selecteds});
       });
     }
     return arr;
   }
   handleClick(e){//让搜索框跟随鼠标点击移动
-    //e.stopPropagation();
+    e.stopPropagation();
     const {fetchPushInfos,totalHide} = this.props;
     //fetchPushInfos&&fetchPushInfos();
     this.getData();
@@ -40,12 +43,23 @@ class CheckBody extends Component{
     }
     //若使用e.target,因为是onClick事件中,值可能是itembox的而不是span因此会有bug
     const ele = document.activeElement;
-    const height = ele.offsetHeight;
-
+    if(ele.toString().indexOf('HTMLSpanElement') == -1){     //点击的不是span无法聚焦就不再设置位置
+      return;
+    }
+    const leftL = ele.offsetLeft;      //用焦点元素的左边距替换鼠标点击的左边距,高度还是鼠标点击的位置
     this.setState({
-      boxLeft:getPageCoordinate(e).boxLeft,
-      boxTop:getPageCoordinate(e).boxTop
+      // boxLeft:getPageCoordinate(e).boxLeft,
+      boxLeft:leftL+90,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
     });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
   handleSearchSelect(obj){
    const {questionId,name} = obj;
@@ -71,7 +85,7 @@ class CheckBody extends Component{
     const {boxLeft,boxTop,boxMark} = this.state;
     return  <div className={style['container']}>
       <ItemBox title='查体' handleClick={this.handleClick}>
-        {this.getLabels(boxLeft,boxTop)}
+        {this.getLabels()}
         {searchData && searchData.length>0?<SearchDrop data={searchData} show={!totalHide} left={boxLeft} top={boxTop} onSelect={this.handleSearchSelect}></SearchDrop>:''}
       </ItemBox>
     </div>

+ 25 - 11
src/components/CurrentIll/index.jsx

@@ -4,7 +4,8 @@ import {Button,InlineTag,ItemBox,Notify,Textarea} from '@commonComp';
 import TailInlineTag from '@commonComp/TailInlineTag';
 import chooseType from '@containers/eleType.js';
 import SearchDrop from '@components/SearchDrop';
-import {filterDataArr} from '@utils/tools'
+import {filterDataArr,getPageCoordinate,windowEventHandler} from '@utils/tools'
+import $ from 'jquery';
 
 class CurrentIll extends Component{
   constructor(props){
@@ -16,9 +17,11 @@ class CurrentIll extends Component{
       mainFlag:true,
       mainData:[],
       boxMark:"2",
-      boxLeft:null,
-      boxTop:null,
-      show:true
+      boxLeft:0,
+      boxTop:0,
+      show:true,
+      tmpScroll:0,
+      tmpTop:0,
     }
     this.toggleEditable = this.toggleEditable.bind(this);
     this.handleFocus = this.handleFocus.bind(this);
@@ -80,13 +83,23 @@ class CurrentIll extends Component{
     // e.stopPropagation(); //冒泡到最顶层关闭其他下拉
     //若使用e.target,因为是onClick事件中,值可能是itembox的而不是span因此会有bug
     const ele = document.activeElement;
-    const height = ele.offsetHeight;
-    let boxTop = (+(ele.offsetTop)+height)+'px';
-    let boxLeft = +ele.offsetLeft+90 + 'px';
+    if(ele.toString().indexOf('HTMLSpanElement') == -1){     //点击的不是span无法聚焦就不再设置位置
+      return;
+    }
+    const leftL = ele.offsetLeft;      //用焦点元素的左边距替换鼠标点击的左边距,高度还是鼠标点击的位置
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
-    })
+      // boxLeft:getPageCoordinate(e).boxLeft,
+      boxLeft:leftL+90,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
+    });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
 
   handleSearchSelect(obj){
@@ -112,7 +125,8 @@ class CurrentIll extends Component{
   render(){
     const {fuzhen,type,fetchPushInfos,handleInput,isRead,saveText,searchData,totalHide,showArr,focusIndex,editClear,data} = this.props;
     const {showMoudle,forbidInput,boxMark,boxLeft,boxTop,show} = this.state;
-    const searchFlag = searchData.length>0 ? true : false;
+    const searchFlag = searchData.length > 0 ? true : false;
+
     if(+type===1){      //文本模式
       return <Textarea  title='现病史' boxMark='2'
                         isRead={isRead}

+ 1 - 10
src/components/EMRContainer/index.jsx

@@ -32,18 +32,9 @@ class EMRContainer extends Component {
           this.$cont.current.style.height = height + "px";
           this.$cont.current.style.width = width + "px";
         });
-        // const {initHistoryLastest} = this.props;
-        // let timer = setInterval(()=>{
-        //     let baseDate = store.getState().patInfo.message;
-        //     if(JSON.stringify(baseDate) != '{}') {
-        //         initHistoryLastest();
-        //         clearInterval(timer)
-        //     }
-        // },500)
-
     }
     render() {
-        return <div className={style['EMR-container']} ref={this.$cont}>
+        return <div className={style['EMR-container']} ref={this.$cont} id="addScrollEvent">
             <InfoTitle></InfoTitle>
             <div className={style['inner']}>
                 <MainSuit></MainSuit>

+ 1 - 1
src/components/EMRContainer/index.less

@@ -5,7 +5,7 @@
   // margin-right:@push-width + 10px;
   padding: 0px 0 10px 0 ;
   box-sizing: border-box;
-  position: relative;
+  position: absolute;
   min-width: 700px;
   float: left;
   overflow-y:auto;

+ 24 - 10
src/components/MainSuit/index.jsx

@@ -6,7 +6,8 @@ import SearchDrop from '@components/SearchDrop';
 import CommonSymptom from '@components/CommonSymptom';
 import chooseType from '@containers/eleType.js';
 import config from "@config/index";
-import {isIE} from "@utils/tools.js"
+import {isIE,getPageCoordinate,windowEventHandler} from "@utils/tools.js"
+import $ from 'jquery';
 
 class MainSuit extends Component{
   constructor(props){
@@ -25,7 +26,9 @@ class MainSuit extends Component{
       blurTimer:null,
       inpText:'',
       clearTimer:null,
-      overFlag:false
+      overFlag:false,
+      tmpScroll:0,
+      tmpTop:0,
     };
     this.toggleEditable = this.toggleEditable.bind(this);
     this.handleFocus = this.handleFocus.bind(this);
@@ -132,14 +135,26 @@ class MainSuit extends Component{
 
   handleClick(e){//让搜索框跟随鼠标点击移动
     // e.stopPropagation(); //冒泡到最顶层关闭其他下拉
-    let boxLeft = e.pageX -32 + 'px';
-    // let boxTop = e.pageY - 112 + 'px';
-    let offsetTop = e.target.offsetTop;
-    let boxTop = offsetTop + 28 + 'px';
+    //若使用e.target,因为是onClick事件中,值可能是itembox的而不是span因此会有bug
+    const ele = document.activeElement;
+    console.log(ele.toString())
+    if(ele.toString().indexOf('HTMLSpanElement') == -1){     //点击的不是span无法聚焦就不再设置位置
+      return;
+    }
+    const leftL = ele.offsetLeft;      //用焦点元素的左边距替换鼠标点击的左边距,高度还是鼠标点击的位置
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
-    })
+      // boxLeft:getPageCoordinate(e).boxLeft,
+      boxLeft:leftL+90,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
+    });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
 
   handleChange(e){
@@ -227,7 +242,6 @@ class MainSuit extends Component{
     const {showModule,boxLeft,boxTop,show,symptom,search} = this.state;
     const symptomFlag = CommonSymptoms.length>0 ? true : false;
     const searchFlag = searchData.length>0 ? true : false;
-    
     if(+type===1){      //文本模式
       return <Textarea title='主诉' boxMark='1' isRead={isRead} value={saveText[0]} handlePush={fetchPushInfos} handleInput={handleInput} />;
     }

+ 14 - 3
src/components/NumberDrop/index.jsx

@@ -2,6 +2,7 @@ import React,{Component} from 'react';
 import className from 'classnames';
 import {NumberPan} from '@commonComp';
 import style from './index.less';
+import $ from "jquery";
 import {handleEnter,getPageCoordinate} from '@utils/tools.js';
 /***
  * author:zn@2018-11-19
@@ -21,8 +22,10 @@ class NumberDrop extends Component{
       timer:null,
       hasSelect:false,       //是否点过下拉键盘
       isClosed:false,
-      boxLeft:'0',
-      boxTop:'0'
+      boxLeft:0,
+      boxTop:0,
+      tmpTop:0,
+      tmpScroll:0
     };
     this.$span = React.createRef();
     this.$pre = React.createRef();
@@ -65,8 +68,16 @@ class NumberDrop extends Component{
   handleNumClick(e){      //数字框不可编辑的状态时点击事件,点击将数字框变为可输入且下拉不再显示直到失焦后再次聚集
     this.setState({
       boxLeft:getPageCoordinate(e).boxLeft,
-      boxTop:getPageCoordinate(e).boxTop
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
     });
+    $("#addScrollEvent").scroll(()=>{
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    })
     e.stopPropagation();
     const {show,handleShow,ikey,id,patId,handleHide,value} = this.props;
     const {hasSelect} = this.state;

+ 22 - 9
src/components/OtherHistory/index.jsx

@@ -2,7 +2,8 @@ import React,{Component} from 'react';
 import {Button,InlineTag,ItemBox,Textarea,Notify} from '@commonComp';
 import chooseType from '@containers/eleType.js';
 import SearchDrop from '@components/SearchDrop';
-import {filterDataArr} from '@utils/tools'
+import {filterDataArr,getPageCoordinate,windowEventHandler} from '@utils/tools'
+import $ from 'jquery';
 import style from './index.less';
 
 class OtherHistory extends Component{
@@ -11,8 +12,10 @@ class OtherHistory extends Component{
     this.state = {
       boxMark:'3',
       editable:true,
-      boxLeft:'0px',
-      boxTop:'0px'
+      boxLeft:0,
+      boxTop:0,
+      tmpScroll:0,
+      tmpTop:0
     };
     this.handleClick = this.handleClick.bind(this);
     this.handleSearchSelect = this.handleSearchSelect.bind(this);
@@ -72,13 +75,24 @@ class OtherHistory extends Component{
     //fetchPushInfos&&fetchPushInfos();
     //若使用e.target,因为是onClick事件中,值可能是itembox的而不是span因此会有bug
     const ele = document.activeElement;
-    const height = ele.offsetHeight;
-    let boxTop = (+(ele.offsetTop)+height)+'px';
-    let boxLeft = ele.offsetLeft + 'px';
+
+    if(ele.toString().indexOf('HTMLSpanElement') == -1){     //点击的不是span无法聚焦就不再设置位置
+      return;
+    }
+    const leftL = ele.offsetLeft;      //用焦点元素的左边距替换鼠标点击的左边距,高度还是鼠标点击的位置
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
+      // boxLeft:getPageCoordinate(e).boxLeft,
+      boxLeft:leftL+90,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
     });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
   /*componentWillReceiveProps(next){
     const isRead = this.props;
@@ -95,7 +109,6 @@ class OtherHistory extends Component{
     const {boxTop,boxLeft,boxMark} = this.state;
     const hasData = saveText.join("")||data.length>0;
     const show = showArr&&showArr[boxMark+focusTextIndex+'0'];
-
     if(+type===1){      //文本模式
       return <Textarea title='其他史' boxMark='3'
                        isRead={isRead}

+ 20 - 5
src/components/RadioDrop/index.jsx

@@ -1,5 +1,5 @@
 import React,{Component} from 'react';
-import {handleEnter} from '@utils/tools.js';
+import {handleEnter,getPageCoordinate,windowEventHandler} from '@utils/tools.js';
 import {DropList} from '@commonComp';
 import style from "./index.less";
 import $ from "jquery";
@@ -22,7 +22,11 @@ class RadioDrop extends Component{
     super(props);
     this.state={
       editable:false,
-      timer:null
+      timer:null,
+      boxLeft:0,
+      boxTop:0,
+      tmpScroll:0,
+      tmpTop:0,
     };
     this.$cont = React.createRef();
     this.handleSelect = this.handleSelect.bind(this);
@@ -77,9 +81,20 @@ class RadioDrop extends Component{
         handleShow && handleShow({ikey,id:patId||id});
       }
     },300);
+    
     this.setState({
-      timer
+      timer,
+      boxLeft:getPageCoordinate(e).boxLeft,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
     });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
   componentDidMount(){    //默认值选中
     const {data,ikey,handleSelect} = this.props;
@@ -119,6 +134,7 @@ class RadioDrop extends Component{
   }
   render(){
     const {data,prefix,suffix,placeholder,show,value} = this.props;
+    const {boxLeft,boxTop} = this.state;
     return <div className={style['container']} ref = {this.$cont}>
       {prefix}
       <div className={this.getClass()}
@@ -130,8 +146,7 @@ class RadioDrop extends Component{
         {value||placeholder}
       </div>
       {suffix}
-      <DropList onSelect={this.handleSelect} data={data}
-                show={show}/>
+      <DropList onSelect={this.handleSelect} data={data} left={boxLeft} top={boxTop} show={show}/>
     </div>
   }
 }

+ 2 - 2
src/components/SearchDrop/index.jsx

@@ -41,8 +41,8 @@ class SearchDrop extends Component{
   getStyle(){
     const {left,top} = this.props;
     return {
-      left:left?left:'',
-      top:top?top:''
+      left:left?left+'px':'',
+      top:top?top+'px':''
     }
   }
 

+ 82 - 45
src/components/SpreadDrop/index.jsx

@@ -2,8 +2,9 @@ import React,{Component} from 'react';
 import classNames from 'classnames';
 import config from '@config/index.js';
 import style from './index.less';
-import {deepClone,filterArr,handleEnter,isIE} from '@utils/tools.js';
+import {deepClone,filterArr,handleEnter,isIE,getPageCoordinate,windowEventHandler} from '@utils/tools.js';
 import {Notify} from '@commonComp';
+import ReactDom from "react-dom";
 import {getIds} from '@common/js/func.js';
 import $ from 'jquery';
 /****
@@ -35,8 +36,10 @@ class SpreadDrop extends Component{
       ban:{},  //放'伴'字段
       editable:false,      //双击编辑
       labelVal:'',  //存放标签原有的值--主诉字数限制用
-      boxLeft:null,
-      boxTop:null
+      boxLeft:0,
+      boxTop:0,
+      tmpScroll:0,
+      tmpTop:0,
     };
     this.$div = React.createRef();
     this.handleSelect = this.handleSelect.bind(this);
@@ -53,14 +56,26 @@ class SpreadDrop extends Component{
   }
   handleShow(e){//单击
     e&&e.stopPropagation();
-    let boxLeft = e.pageX -175 + 'px';
-    let offsetTop = e.target.offsetTop;
-    const ht = e.target.offsetHeight;   //如杂音选中文字有多行时,写死会遮挡
-    let boxTop = offsetTop + ht +2 + 'px';
+    // let boxLeft = e.pageX -175 + 'px';
+    // let offsetTop = e.target.offsetTop;
+    // const ht = e.target.offsetHeight;   //如杂音选中文字有多行时,写死会遮挡
+    // let boxTop = offsetTop + ht +2 + 'px';
+    // this.setState({
+    //   boxLeft:boxLeft,
+    //   boxTop:boxTop
+    // })
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
-    })
+      boxLeft:getPageCoordinate(e).boxLeft,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
+    });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
     // window.event? window.event.cancelBubble = true : e.stopPropagation();
      this.setStateInit();      //恢复初始选中状态
     const {ikey,handleShow,placeholder,flag,id,value,tagType,type} = this.props;
@@ -295,8 +310,44 @@ class SpreadDrop extends Component{
     }
     return style['tag'];
   }
+  
+  componentDidMount(){
+    if(isIE()){
+      $(this.$div.current).onIe8Input(function(e){
+        this.onChange(e)
+      },this);
+    }
+  }
+
+  render(){
+    const {placeholder,value,show,data} = this.props;
+    const {editable,boxLeft,boxTop} = this.state;
+    return  <div className={style['container']}
+              onFocus={(e)=>e.stopPropagation()}
+              onBlur={(e)=>e.stopPropagation()}
+              onInput={(e)=>e.stopPropagation()}>
+        <div
+        ref={this.$div}
+        onClick={this.handleShow}
+        className={this.getClass()}
+        contentEditable={editable}
+        onDoubleClick={this.changeToEdit}
+        onBlur={this.handleBlur}
+        onInput={this.onChange}
+        onkeydown={handleEnter}
+        >{value||placeholder}</div>
+          <ListItems data={data} left={boxLeft} 
+            top={boxTop} show={show} handleSelect={this.handleSelect} handleConfirm={this.handleConfirm} handleClear={this.handleClear} {...this.state}></ListItems>
+      </div>
+  }
+}
+
+class ListItems extends Component{
+  constructor(props){
+    super(props);
+  }
   getLabels(){
-    const {data} = this.props;
+    const {data,handleSelect} = this.props;
     let detail = [];
     let isSpecialPos = false;       //是否特殊位置(单行在上面,如无殊)
     let isExclu = false;      //是否与其他互斥
@@ -310,53 +361,39 @@ class SpreadDrop extends Component{
       }else{
         detail = it.questionDetailList;
       }
-      return <ListItem data={detail}
+      return <ListItem datas={detail}
                        isRadio={isRadio}
                        joint={it.joint}
                        listIndex={i}
                        isSpecialPos={isSpecialPos}
                        isExclu={isExclu}
-                       handleClick={this.handleSelect}
-                       {...this.state}></ListItem>;
+                       handleClick={handleSelect}
+                       {...this.props}></ListItem>;
     });
     return list;
   }
-  componentDidMount(){
-    if(isIE()){
-      $(this.$div.current).onIe8Input(function(e){
-        this.onChange(e)
-      },this);
+  getStyle(){
+    const {left,top,show} = this.props;
+    return {
+      left:left?left+'px':'',
+      top:top?top+'px':'',
+      display:show?'block':'none'
     }
   }
-
-  render(){
-    const {placeholder,value,show} = this.props;
-    const {editable,boxLeft,boxTop} = this.state;
-    return <div className={style['container']}
-            onFocus={(e)=>e.stopPropagation()}
-            onBlur={(e)=>e.stopPropagation()}
-            onInput={(e)=>e.stopPropagation()}>
-      <div
-      ref={this.$div}
-      onClick={this.handleShow}
-      className={this.getClass()}
-      contentEditable={editable}
-      onDoubleClick={this.changeToEdit}
-      onBlur={this.handleBlur}
-      onInput={this.onChange}
-      onkeydown={handleEnter}
-      >{value||placeholder}</div>
-      <div className={style["drop-list"]} style={{display:show?'block':'none',top:boxTop,left:boxLeft}} contentEditable="false" onClick={(e)=>{e.stopPropagation();}}>
+  render (){   
+    const {handleClear,handleConfirm} = this.props;
+    const domNode = document.getElementById('root');
+    return ReactDom.createPortal(
+      <div className={style["drop-list"]} style={this.getStyle()} contentEditable="false" onClick={(e)=>{e.stopPropagation();}}>
         {this.getLabels()}
         <div className="oper">
-          <span className={style['clear']} onClick={this.handleClear}>清空选项</span>
-          <span className={style['confirm']} onClick={this.handleConfirm}>确定</span>
+          <span className={style['clear']} onClick={handleClear}>清空选项</span>
+          <span className={style['confirm']} onClick={handleConfirm}>确定</span>
         </div>
       </div>
-    </div>
+    ,domNode)
   }
 }
-
 class ListItem extends Component{
   constructor(props){
     super(props);
@@ -365,6 +402,7 @@ class ListItem extends Component{
     e.stopPropagation();
     // window.event? window.event.cancelBubble = true : e.stopPropagation();
     const {handleClick,isExclu,isRadio,data,exists,noneIds,withs,joint,listIndex} = this.props;
+
     const index=listIndex+''+i;
     //列单选处理
     if(isRadio){
@@ -406,15 +444,14 @@ class ListItem extends Component{
     }
   }
   render(){
-    const {data,isSpecialPos} = this.props;
+    const {datas,isSpecialPos} = this.props;
     const pos = isSpecialPos?style['independent']:'';
     return <ul className={classNames(style['row'],pos)} onBlur={(e)=>e.stopPropagation()}>
-      {data&&data.map((it,i)=>{
+      {datas&&datas.map((it,i)=>{
         return <li onClick={(e)=>this.handleClick(e,it,i)}
                    className={this.getClass(it.id)}>{it.labelPrefix}{it.name}{it.labelSuffix}</li>
       })}
     </ul>;
   }
-
 }
 export default SpreadDrop;

+ 3 - 1
src/containers/eleType.js

@@ -18,7 +18,7 @@ import NumberUnitDrop from '@containers/NumberUnitDrop';
 //单选类型
 export function singleRadio(params){
   const data = params.item;
-  const {i,hideTag,boxMark,showArr} = params;
+  const {i,hideTag,boxMark,showArr,boxTop,boxLeft} = params;
   const showInx = boxMark+i+'0';    //单括号多标签的情况下需要识别同一个标签内多个下拉组件的显示状态
   switch (+data.controlType){
     case 0:
@@ -33,6 +33,8 @@ export function singleRadio(params){
                         boxMark={boxMark}
                         id={data.id}
                         ikey={showInx}
+                        boxTop={boxTop}
+                        boxLeft={boxLeft}
                         hideTag={hideTag}></RadioDrop>;
     case 3:
       return <EditableSpan {...params} value={data.value||data.value==''?data.value:data.name} update={Math.random()}/>;

+ 2 - 1
src/store/reducers/checkBody.js

@@ -10,7 +10,8 @@ const initState = {
                 searchData:[],
                 selecteds:[],
                 focusIndex:'',
-                isEmpty:true      //是否为空白,需要请求数据
+                isEmpty:true,      //是否为空白,需要请求数据
+                showSearchBox:false
           };
 export default function(state=initState,action){
   let res = Object.assign({},state);

+ 17 - 7
src/utils/tools.js

@@ -520,11 +520,20 @@ function preventDefault(event) {
 }
 
 //ie8添加解除事件兼容
-function windowEventHandler(type,func){
-    if(window.addEventListener){
-      window.addEventListener(type, func);
+function windowEventHandler(type,func,dom){
+    let win = dom?dom:window;
+    if(win.addEventListener){
+      win.addEventListener(type, func);
     }else{
-      window.attachEvent('on'+type,func);
+      win.attachEvent('on'+type,func);
+    }
+}
+function windowRemoveEventHandler(type,func,dom){
+    let win = dom?dom:window;
+    if(win.addEventListener){
+      win.removeEventListener(type, func);
+    }else{
+      win.detachEvent('on'+type,func);
     }
 }
 
@@ -622,8 +631,8 @@ function getPageCoordinate(event){
     var x = e.pageX || (e.clientX + scrollX);
     var y = (e.pageY+25) || (e.clientY + scrollY + 25);
     let obj = {
-      boxLeft : x + 'px',
-      boxTop : y +'px'
+      boxLeft : x ,
+      boxTop : y
     }
     return obj;
 }
@@ -651,5 +660,6 @@ module.exports = {
     windowEventHandler,
     isAllClear,
     normalVal,
-    getPageCoordinate
+    getPageCoordinate,
+    windowRemoveEventHandler
 };