js的dom操作之js实现自定义提示框,提示文字图片和短菜单

Posted 智商不够_熬夜来凑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js的dom操作之js实现自定义提示框,提示文字图片和短菜单相关的知识,希望对你有一定的参考价值。

【使用场景如下】

自己的博客网站想实现以下功能:①弹出文字提示②弹出图片提示③弹出标题及图片提示④弹出简短的菜单。

鼠标onmouseover时触发,只需引入js,无需其他附件,使用时new一个就ok了。

标题+图片
菜单提示

 

图片提示

【实现代码】主要是涉及js的基础操作(dom操作)等

使用时的代码(就这么简单):

//引入主tipper.js
<script src="js/tipper.js"></script>
<script>    
 //手机浏览
      var data=type:'text',data:'手机扫码浏览',bgColor:'#333';
       //var data=type:'menu',data:['菜单一','菜单二'],title:'扫码手机查看',bgColor:'#333';
       bindTipper("hint",null,data,function(res)
          var id=res.tipBox.getAttribute("id");
          //生成二维码
          var qrcode = new QRCode(id, 
      	    text: window.location.href,
      	    width: 128,
      	    height: 128,
      	    colorDark : "#000000",
      	    colorLight : "#ffffff",
      	    correctLevel : QRCode.CorrectLevel.H
      	   );
      	res.resize()//调整位置高度
       )
//提示菜单
       var data=type:'menu',data:['菜单一','菜单二'],title:'扫码手机查看',bgColor:'#333';
       bindTipper("more",null,data,function(res)
       );
//图片
       var data=type:'both',data:'./img/logo.png',title:'HI,你好橘子',bgColor:'#333';
       bindTipper("loginBox",null,data,function(res)
       );
</script>

问题一:js生成的dom如何监听点击事件

把生成的dom传回 ,可监听点击事件,如以下返回的res中包含了所有创建的dom,

var data=type:'both',data:'./img/logo.png',title:'HI,你好橘子',bgColor:'#333';
       bindTipper("loginBox",null,data,function(res)
        //res=>tipBox,imgBox...
        var tipBox=res.tipBox;
        tipBox.oncllick=function(e)
        //do something
        
);

问题二:本认为最难的是after和before等伪元素的操作

 要根据元素位置来判断小三角的方向,所以要通过js操作伪元素的样式。这么一来,感觉有点困难,甚至都想到用addRule和

deleteRule,如此麻烦,还不如引入css文件!又违背了初衷--‘只需引入js’,那么,就动态将样式添加到body中吧!

tipper.js,可根据自己需求改写

/**
 * @author Mr.chen
 * 文字提示:tipper('id',type:'text',data:'文字内容',bgColor:'#ffffff',color:'#000')
 * 图片提示:tipper('id',type:'image',data:'imgUrl',bgColor:'#ffffff',color:'#000',width:'80',height:'80')
 * 文字+图片提示:tipper('id',type:'both',data:'imgUrl',title:'提示名称',bgColor:'#ffffff',color:'#000',width:'80',height:'80')
 * 短菜单:tipper(dom,type:'menu',data:['菜单一','菜单二'],bgColor:'#ffffff',color:'#000')
 */
var tipper=function(id,data,callback)
	var returnDom=;//要返回的元素
	var tipsL=document.getElementsByClassName("tips"),$e;
	var imgBox,titleBox;
	if(tipsL.length>=1)//页面是否存在该tip,存在则消除
		for(var i=0;i<tipsL.length;i++)
			tipsL[i].remove()
		
	
	//默认背景样式
	data.bgColor==undefined?data.bgColor='#3377aa':'';
	data.color==undefined?data.color='#ffffff':'';
	//console.log(id)
	if(id&&id.nodeType)//传入的是dom
		//console.log('传入的是dom')
		$e=id;
	else
		$e=document.getElementById(id);
	
	var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;
	var x=$e.getBoundingClientRect().left;
	var y=$e.getBoundingClientRect().top;
	var width=$e.clientWidth;
	var height=$e.clientHeight;
	/*console.log(x,y)
	console.log(width,height)*/
	var that=this,tipBox=document.createElement("div");
	tipBox.setAttribute("class","tips");
	tipBox.setAttribute("id","tipBox");
	tipBox.style.position="absolute";
	tipBox.style.zIndex='1000';
	tipBox.style.top=scrollTop+(y-30)+'px';
	tipBox.style.background=data.bgColor;
	tipBox.style.left=x+(width/2)+'px';
	tipBox.style.padding='5px';
	tipBox.style.textAlign='center';
	//tipBox.style.border='1px #DBDBDB solid';
	tipBox.style.borderRadius='4px';
	tipBox.style.color=data.color;
	switch(data.type)
		case 'text':
			tipBox.innerhtml=data.data;
			document.body.append(tipBox);
			break;
		case 'image':
			imgBox=document.createElement("img");
			data.width==null?data.width='80':'';data.height==null?data.height='80':'';
			imgBox.style.width=data.width+'px';
			imgBox.style.height=data.height+'px';
			imgBox.src=data.data;
			document.body.append(tipBox);
			tipBox.append(imgBox);
			returnDom.imgBox=imgBox;
			break;
		case 'both':
			//title
			titleBox=document.createElement("div");
			titleBox.style.width='100%';
			titleBox.style.height='30px';
			titleBox.style.lineHeight='30px';
			titleBox.style.textAlign='center';
			titleBox.innerHTML=data.title;
			tipBox.append(titleBox);
			//img
			imgBox=document.createElement("img");
			data.width==null?data.width='80':'';data.height==null?data.height='80':'';
			imgBox.style.width=data.width+'px';
			imgBox.style.height=data.height+'px';
			imgBox.src=data.data;
			document.body.append(tipBox);
			tipBox.append(imgBox);
			returnDom.imgBox=imgBox;
			break;
		case 'menu':
			if(Array.isArray(data.data))
			  var list=data.data,dom,domList=[];
              for(var i=0;i<list.length;i++)
            	  dom=document.createElement("span");
            	  dom.innerHTML=list[i];
            	  dom.style.width='100%';
            	  dom.style.padding='5px';
            	  dom.setAttribute("data-title",list[i]);
            	  dom.setAttribute("class",'menuHover');
            	  if((i+1)<list.length)
            		  dom.classList.add('spanMenu');
            	  
            	  domList.push(dom)
                  tipBox.append(dom);
              
              returnDom.domList=domList;
              document.body.append(tipBox);
			else
				//alert('请输入对应的类型!')
				return;
			
			break;
			default:
				return false;
				break;
	
	returnDom.tipBox=tipBox;
	var tipBoxHeight=tipBox.getBoundingClientRect().height;
	//判断箭头方向
	function getDirection()
		var pageHeight=document.documentElement.clientHeight;//网页高度
		y=$e.getBoundingClientRect().top;
		//console.log("网页高度"+pageHeight,"元素顶部高度"+y)
		var leftY=pageHeight-y;
		tipBoxHeight=tipBox.getBoundingClientRect().height;
		/*console.log(leftY,tipBox.getBoundingClientRect().height)
		console.log(tipBox.getBoundingClientRect().height)*/
		if(leftY<(tipBoxHeight+20))
			return false;
		else
			return true;
		
	
	//调整倒三角位置
	var halfWidth=tipBox.clientWidth/2;//tipBox.getBoundingClientRect().width
	var tipBoxX=tipBox.getBoundingClientRect().left;
	//console.log(scrollTop-tipBoxHeight)
	var spanMenu='.menuHover:hovercolor:red;cursor:pointer.spanMenu::aftercontent:"";height:8px;background:'+data.color+';margin-left:5px;padding-left:1px';
	var triangeleUp='.triangeleUp::beforeposition: absolute;z-index:11;width: 0px;height: 0px;content: "";'+
	 'border-width:0px 10px 10px 10px;top:-10px;'+
    'border-style: solid;border-color:transparent transparent '+data.bgColor+'  ;left:'+(halfWidth*1-5)+'px';
	var triangeleDown='.triangeleDown::afterposition: absolute;z-index:11;width: 0px;height: 0px;content: "";'+
	 'border-width:10px ;bottom:-20px;'+
   'border-style: solid;border-color:'+data.bgColor+' transparent transparent transparent;left:'+(halfWidth*1-5)+'px';

	//动态加入样式
	setStyle(spanMenu);
	setStyle(triangeleUp);
	setStyle(triangeleDown);
    tipBox.style.left=(tipBoxX-halfWidth)+'px';
	var up=getDirection();
	if(!up)
		tipBox.style.top=(scrollTop+(y-tipBoxHeight))+'px';
		tipBox.classList.add("triangeleDown");
		tipBox.classList.remove("triangeleUp");
		//document.styleSheets[0].addRule('#tipBox::after', triangeleDown);
	else
		tipBox.style.top=(scrollTop+y+height)+'px';
		tipBox.classList.add("triangeleUp");
		tipBox.classList.remove("triangeleDown");
		//document.styleSheets[0].addRule('#tipBox::after', triangeleUp);
	
    // 浏览器窗口变化后需要做的事情
	window.onresize = function() 
		//clearStyle();
		tipBox.remove()
	
	document.onclick=function()
		//clearStyle();
		tipBox.remove()
	
	function clearStyle()
		  /*var rulArr=document.styleSheets[0].cssRules;
		    if(rulArr.length>=0)
		    	console.log('删除动态添加的伪元素样式')
		    	for(var i=0;i<rulArr.length;i++)
		    		document.styleSheets[0].deleteRule(i)
		    	
		    */
	
	//滚动监听
	window.onscroll = function() 
        resize()
		/*tipBoxHeight=tipBox.getBoundingClientRect().height;
		y=$e.getBoundingClientRect().top;
	    scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
	    var up=getDirection();
		if(!up)
			tipBox.style.top=(scrollTop+(y-tipBoxHeight))+'px';
			tipBox.classList.add("triangeleDown");
			tipBox.classList.remove("triangeleUp");
		else
			tipBox.style.top=(scrollTop+y+height)+'px';
			tipBox.classList.add("triangeleUp");
			tipBox.classList.remove("triangeleDown");
		*/
	
	var resize=function()
		tipBoxHeight=tipBox.getBoundingClientRect().height;
		y=$e.getBoundingClientRect().top;
	    scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
	    var up=getDirection();
		if(!up)
			tipBox.style.top=(scrollTop+(y-tipBoxHeight))+'px';
			tipBox.classList.add("triangeleDown");
			tipBox.classList.remove("triangeleUp");
		else
			tipBox.style.top=(scrollTop+y+height)+'px';
			tipBox.classList.add("triangeleUp");
			tipBox.classList.remove("triangeleDown");
		
	
	//点击提示栏消除提示
	tipBox.onclick = function()
		//clearStyle();
		tipBox.remove();
	

	//动态添加样式
	function setStyle(str)
		const styleStr=str;
		var style = document.createElement("style");
		style.type = "text/css";
		try
		  style.appendChild(document.createTextNode(styleStr));
		catch(ex)
		  style.styleSheet.cssText = styleStr;//针对IE
		
		var head = document.getElementsByTagName("head")[0];
		head.appendChild(style);
	
	returnDom.resize=resize
	return callback(returnDom)


function bindTipper($id,$e,data,callback)
	var tip,bi;
	var binder=document.getElementById($id);
	if(binder==null)
		binder=document.getElementsByClassName($id);
	
	console.log(binder)
	for(var i=0;i<binder.length;i++)
		/*console.log('传入的dom:')
		console.log(bi)*/
		binder[i].onmouseover=function(e)
			/*console.log(e.currentTarget)
			console.log('方法的dom:')
			console.log(binder[i])*/
			tip=new tipper(e.currentTarget,data,function(res)
				return callback(res)
			);
		
		/*binder[i].onmouseout=function(e)
			tip.tipBox.remove();
		*/
	
	//return callback(tip)

 

以上是关于js的dom操作之js实现自定义提示框,提示文字图片和短菜单的主要内容,如果未能解决你的问题,请参考以下文章

js到一定时间进行弹窗提示,确定到分

ElementUI中table表格自定义表头Tooltip文字提示

怎么用js实现选中文字自动弹出一个工具条?像百度文库那样。

自定义的提示框

js之BOM和DOM

dcat-admin行操作自定义弹框页面