0714 NOTE
放大镜效果
.zoomclass{
position: relative;
}
.mini{
width: 450px;
height: 450px;
position: relative;
border: 1px solid #ccc;
left: 100px;
top:100px;
background-size: 100% 100%;
}
.mask{
background-color: rgba(255, 227, 68, 0.3);
position: absolute;
left: 0;
top: 0;
display: none;
}
.zoom{
width: 540px;
height: 540px;
position: absolute;
border: 1px solid #ccc;
display: none;
}
.carousel{
width: 450px;
height: 58px;
position: absolute;
}
.left,.right{
width:22px;
height: 32px;
background-image: url(./img/__sprite.png);
position: absolute;
top:14px;
}
.left{
background-position-x: 0px;
background-position-y: -54px;
}
.right{
background-position-x: -78px;
background-position-y: 0;
right: 0;
}
.maskCon{
position: relative;
width: 380px;
height: 58px;
margin:0px 36px;
overflow: hidden;
}
.maskCon>.imgCon{
position: absolute;
left: 0;
top:0;
transition: all 0.5s;
}
.maskCon>.imgCon>img{
width: 54px;
height: 54px;
border: 2px solid transparent;
margin: 0px 9px;
}
<div class="zoomclass">
<div class="mini">
<div class="mask"></div>
</div>
<div class="zoom"></div>
<div class="carousel">
<div class="left"></div>
<div class="maskCon">
<div class="imgCon"></div>
</div>
<div class="right"></div>
</div>
</div>
var arr=["a_icon.jpg","b_icon.jpg","c_icon.jpg","d_icon.jpg","e_icon.jpg","f_icon.jpg","g_icon.jpg","h_icon.jpg","i_icon.jpg","j_icon.jpg","a_icon.jpg","b_icon.jpg"];
var mini,mask,zoom,prev,carousel,imgCon,left,right,ids;
var loadBool=false,
maskWidth=0,
maskHeight=0,
carouselX=0,
x=0,
y=0;
init();
function init(){
mini=document.querySelector(".mini");
mask=document.querySelector(".mask");
zoom=document.querySelector(".zoom");
carousel=document.querySelector(".carousel");
imgCon=document.querySelector(".imgCon");
left=document.querySelector(".left");
right=document.querySelector(".right");
zoom.style.left=mini.offsetLeft+mini.offsetWidth+"px";
zoom.style.top=mini.offsetTop+"px";
carousel.style.left=mini.offsetLeft+"px";
carousel.style.top=mini.offsetTop+mini.offsetHeight+"px";
mini.addEventListener("mouseenter",mouseHandler)
mini.addEventListener("mouseleave",mouseHandler)
createCarousel();
}
function createCarousel(){
arr.forEach(item=>{
var img=new Image();
img.src="./img/"+item;
imgCon.appendChild(img);
});
imgCon.style.width=arr.length*76+"px"
imgCon.addEventListener("mouseover",carouselMouseHandler);
var evt=new MouseEvent("mouseover",{bubbles:true});
imgCon.children[0].dispatchEvent(evt);
left.addEventListener("click",bnClickhandler);
right.addEventListener("click",bnClickhandler);
}
function carouselMouseHandler(e){
if(e.target.nodeName!=="IMG") return;
if(prev){
prev.style.borderColor="transparent";
}
prev=e.target;
prev.style.borderColor="#e53e41"
var index=Array.from(imgCon.children).indexOf(e.target);
loadImage(arr[index].replace("_icon",""));
}
function loadImage(src){
mini.style.backgroundImage=zoom.style.backgroundImage="url(./img/"+src+")";
var img=new Image();
img.addEventListener("load",loadHandler);
img.src="./img/"+src;
}
function loadHandler(e){
loadBool=true;
this.removeEventListener("load",loadHandler);
maskWidth=540/this.width*450;
maskHeight=540/this.height*450;
Object.assign(mask.style,{
width:maskWidth+"px",
height:maskHeight+"px",
})
}
function mouseHandler(e){
if(!loadBool)return;
if(e.type==="mouseenter"){
zoom.style.display=mask.style.display="block";
mini.addEventListener("mousemove",mouseHandler);
}else if(e.type==="mouseleave"){
zoom.style.display=mask.style.display="none";
mini.removeEventListener("mousemove",mouseHandler);
}else if(e.type==="mousemove"){
var rect=mini.getBoundingClientRect();
x=e.clientX-maskWidth/2-rect.x;
y=e.clientY-maskHeight/2-rect.y;
if(x>450-maskWidth) x=450-maskWidth;
if(y>450-maskHeight) y=450-maskHeight;
if(x<0) x=0;
if(y<0) y=0;
mask.style.left=x+"px";
mask.style.top=y+"px";
var scaleX=540/maskWidth;
var scaleY=540/maskHeight;
zoom.style.backgroundPositionX=-x*scaleX+"px";
zoom.style.backgroundPositionY=-y*scaleY+"px";
}
}
function bnClickhandler(e){
if(ids) return;
if(this===left){
carouselX-=380;
if(carouselX<0) carouselX=0;
}else{
carouselX+=380
if(carouselX>=imgCon.offsetWidth-380) carouselX=imgCon.offsetWidth-380;
}
imgCon.style.left=-carouselX+"px"
setTimeout(function(){
clearTimeout(ids);
ids=undefined;
},500)
}
原位置实现放大镜效果
.zoomclass{
position: relative;
}
.mini{
width: 450px;
height: 450px;
position: absolute;
border: 1px solid #ccc;
background-size: 100% 100%;
}
.mask{
background-color: rgba(255, 227, 68, 0.3);
position: absolute;
left: 0;
top: 0;
display: none;
}
.zoom{
width: 540px;
height: 540px;
position: absolute;
left: 452px;
top: 0;
border: 1px solid #ccc;
display: none;
}
<div class="zoomclass">
<div class="mini">
<div class="mask"></div>
</div>
<div class="zoom"></div>
</div>
var arr=["a.jpg","b.jpg","c.jpg","d.jpg","e.jpg","f.jpg","g.jpg","h.jpg","i.jpg","j.jpg"];
var mini,mask,zoom;
var loadBool=false,
imgWidth=0,
imgHeight=0,
x=0,
y=0;
init();
function init(){
mini=document.querySelector(".mini");
mask=document.querySelector(".mask");
zoom=document.querySelector(".zoom");
loadImage(arr[0]);
mini.addEventListener("mouseenter",mouseHandler)
mini.addEventListener("mouseleave",mouseHandler)
}
function loadImage(src){
mini.style.backgroundImage=zoom.style.backgroundImage="url(./img/"+src+")";
var img=new Image();
img.addEventListener("load",loadHandler);
img.src="./img/"+src;
}
function loadHandler(e){
loadBool=true;
this.removeEventListener("load",loadHandler);
imgWidth=this.width;
imgHeight=this.height;
}
function mouseHandler(e){
if(!loadBool)return;
if(e.type==="mouseenter"){
mini.style.backgroundSize="auto";
mini.addEventListener("mousemove",mouseHandler);
}else if(e.type==="mouseleave"){
mini.style.backgroundSize="100% 100%";
mini.style.backgroundPositionX="0px"
mini.style.backgroundPositionY="0px"
mini.removeEventListener("mousemove",mouseHandler);
}else if(e.type==="mousemove"){
var scaleX=(imgWidth-450)/450;
var scaleY=(imgHeight-450)/450;
mini.style.backgroundPositionX=-e.clientX*scaleX+"px";
mini.style.backgroundPositionY=-e.clientY*scaleY+"px";
}
}
面向对象放大镜效果
"use strict"
import CarouselZoom from "./js/CarouselZoom.js";
var arr=[];
for(var i=97;i<107;i++){
arr.push("./img/"+String.fromCharCode(i)+"_icon.jpg");
}
var carouselZoom=new CarouselZoom(arr);
carouselZoom.appendTo("body");
import Component from "./Component.js";
import Zoom from "./Zoom.js";
import Utils from "./Utils.js";
export default class CarouselZoom extends Component{
carousel;
imgCon;
left;
right;
prev;
arr=[];
zoom;
ids;
carouselX=0;
constructor(arr){
super();
this.elem.innerHTML=`
<div class="carousel">
<div class="left"></div>
<div class="maskCon">
<div class="imgCon"></div>
</div>
<div class="right"></div>
</div>
`
this.elem.style.position="relative"
this.zoom=new Zoom();
CarouselZoom.setCss();
this.carousel=this.elem.querySelector(".carousel");
this.imgCon=this.elem.querySelector(".imgCon");
this.left=this.elem.querySelector(".left");
this.right=this.elem.querySelector(".right");
if(arr && arr.length>0) this.setData(arr);
}
appendTo(parent){
super.appendTo(parent);
this.zoom.insertTo(this.elem,this.elem.firstElementChild);
}
setData(arr){
this.imgCon.innerHTML="";
this.arr=arr;
arr.forEach(item=>{
var img=new Image();
img.src=item;
this.imgCon.appendChild(img);
});
this.imgCon.style.width=arr.length*76+"px"
this.imgCon.addEventListener("mouseover",e=>this.carouselMouseHandler(e));
var evt=new MouseEvent("mouseover",{bubbles:true});
this.imgCon.children[0].dispatchEvent(evt);
this.left.addEventListener("click",e=>this.bnClickhandler(e));
this.right.addEventListener("click",e=>this.bnClickhandler(e));
}
carouselMouseHandler(e){
if(e.target.nodeName!=="IMG") return;
if(this.prev){
this.prev.style.borderColor="transparent";
}
this.prev=e.target;
this.prev.style.borderColor="#e53e41"
var index=Array.from(this.imgCon.children).indexOf(e.target);
this.zoom.setImage(this.arr[index].replace("_icon",""));
}
bnClickhandler(e){
if(this.ids) return;
if(e.currentTarget===this.left){
this.carouselX-=380;
if(this.carouselX<0) this.carouselX=0;
}else{
this.carouselX+=380
if(this.carouselX>=this.imgCon.offsetWidth-380) this.carouselX=this.imgCon.offsetWidth-380;
}
this.imgCon.style.left=-this.carouselX+"px"
setTimeout(()=>{
clearTimeout(this.ids);
this.ids=undefined;
},500)
}
static setCss(){
if(super.setCss()) return ;
Utils.setCss(`.carousel{
width: 450px;
height: 58px;
position: absolute;
}
.left,.right{
width:22px;
height: 32px;
background-image: url(./img/__sprite.png);
position: absolute;
top:14px;
}
.left{
background-position-x: 0px;
background-position-y: -54px;
}
.right{
background-position-x: -78px;
background-position-y: 0;
right: 0;
}
.maskCon{
position: relative;
width: 380px;
height: 58px;
margin:0px 36px;
overflow: hidden;
}
.maskCon>.imgCon{
position: absolute;
left: 0;
top:0;
transition: all 0.5s;
}
.maskCon>.imgCon>img{
width: 54px;
height: 54px;
border: 2px solid transparent;
margin: 0px 9px;
}`)
}
}
import Component from "./Component.js";
import Utils from "./Utils.js";
export default class Zoom extends Component {
origin = false;
loadBool = false;
width = 0;
height = 0;
x = 0;
y = 0;
static WIDTH = 450;
static HEIGHT = 450;
static ZOOM_WIDTH = 540;
static ZOOM_HEIGHT = 540;
constructor(src, origin = false) {
super();
this.origin = origin;
Zoom.setCss();
this.mouseFn = e => this.mouseHandler(e);
var elem;
if (!origin) {
this.elem.innerHTML = `
<div class="mini">
<div class="mask"></div>
</div>
<div class="zoom"></div>
`;
this.mini = this.elem.querySelector(".mini");
this.mask = this.elem.querySelector(".mask");
this.zoom = this.elem.querySelector(".zoom");
this.zoom.style.width = Zoom.ZOOM_WIDTH + "px";
this.zoom.style.height = Zoom.ZOOM_HEIGHT + "px";
elem = this.mini;
} else {
elem = this.elem;
this.elem.className = 'zoomOrigin';
}
elem.style.width = Zoom.WIDTH + "px";
elem.style.height = Zoom.HEIGHT + "px";
elem.addEventListener("mouseenter", this.mouseFn)
elem.addEventListener("mouseleave", this.mouseFn)
if (src && src.toString().trim().length !== 0) this.setImage(src);
}
insertTo(parent,before=undefined) {
super.insertTo(parent,before);
if (!this.origin) {
this.zoom.style.left = this.mini.offsetLeft + this.mini.offsetWidth + "px";
this.zoom.style.top = this.mini.offsetTop + "px";
}
}
appendTo(parent){
super.appendTo(parent);
if (!this.origin) {
this.zoom.style.left = this.mini.offsetLeft + this.mini.offsetWidth + "px";
this.zoom.style.top = this.mini.offsetTop + "px";
}
}
mouseHandler(e) {
if (!this.loadBool) return;
if (e.type === "mouseenter") {
if (this.origin) {
this.elem.style.backgroundSize = "auto";
this.elem.addEventListener("mousemove", this.mouseFn);
} else {
this.zoom.style.display = this.mask.style.display = "block";
this.mini.addEventListener("mousemove", this.mouseFn);
}
} else if (e.type === "mouseleave") {
if (this.origin) {
this.elem.style.backgroundSize = "100% 100%";
this.elem.style.backgroundPositionX = "0px"
this.elem.style.backgroundPositionY = "0px"
} else this.zoom.style.display = this.mask.style.display = "none";
e.currentTarget.removeEventListener("mousemove", this.mouseFn);
} else if (e.type === "mousemove") {
this.x = e.clientX - (this.origin ? 0 : this.width / 2 + this.mini.getBoundingClientRect().x);
this.y = e.clientY - (this.origin ? 0 : this.height / 2 + this.mini.getBoundingClientRect().y);
if (!this.origin) {
if (this.x > Zoom.WIDTH - this.width) this.x = Zoom.WIDTH - this.width;
if (this.y > Zoom.HEIGHT - this.height) this.y = Zoom.HEIGHT - this.height;
if (this.x < 0) this.x = 0;
if (this.y < 0) this.y = 0;
this.mask.style.left = this.x + "px";
this.mask.style.top = this.y + "px";
}
var scaleX = this.origin ? (this.width - Zoom.WIDTH) / Zoom.WIDTH : Zoom.ZOOM_WIDTH / this.width;
var scaleY = this.origin ? (this.height - Zoom.HEIGHT) / Zoom.HEIGHT : Zoom.ZOOM_HEIGHT / this.height;
var elem = this.origin ? this.elem : this.zoom;
elem.style.backgroundPositionX = -this.x * scaleX + "px";
elem.style.backgroundPositionY = -this.y * scaleY + "px";
}
}
setImage(src) {
if (!this.origin) this.mini.style.backgroundImage = this.zoom.style.backgroundImage = "url(" + src + ")";
else this.elem.style.backgroundImage = "url(" + src + ")";
if (this.loadBool) return;
this.loadBool = false;
var img = new Image();
this.loadFn = e => this.loadHandler(e);
img.addEventListener("load", this.loadFn);
img.src = src;
}
loadHandler(e) {
this.loadBool = true;
e.currentTarget.removeEventListener("load", this.loadFn);
this.width = this.origin ? e.currentTarget.width : Zoom.ZOOM_WIDTH / e.currentTarget.width * Zoom.WIDTH;
this.height = this.origin ? e.currentTarget.height : Zoom.ZOOM_HEIGHT / e.currentTarget.height * Zoom.HEIGHT;
if (!this.origin)
Object.assign(this.mask.style, {
width: this.width + "px",
height: this.height + "px",
})
}
static setCss() {
if (super.setCss()) return;
Utils.setCss(`
.mini,.zoomOrigin{
position: relative;
border: 1px solid #ccc;
background-size: 100% 100%;
}
.mask{
background-color: rgba(255, 227, 68, 0.3);
position: absolute;
left: 0;
top: 0;
display: none;
}
.zoom{
position: absolute;
border: 1px solid #ccc;
display: none;
}
`);
}
}
StepNumber
import StepNumber from "./js/StepNumber.js";
var list=[];
for(var i=0;i<10;i++){
let step=new StepNumber();
step.addEventListener("change",changeHandler);
step.appendTo("body");
list.push(step);
}
function changeHandler(e){
var index=list.indexOf(this);
console.log(index,e.step);
}
import Component from "./Component.js";
import Utils from "./Utils.js";
export default class StepNumber extends Component{
input;
ids;
step=1;
constructor() {
super();
this.elem.innerHTML=`
<div disabled>-</div>
<input type='text' value="1">
<div>+</div>
`;
this.elem.className="stepnumber";
this.input=this.elem.querySelector("input");
this.elem.addEventListener("click",e=>this.clickHandler(e));
this.input.addEventListener("input",e=>this.inputHandler(e));
StepNumber.setCss();
}
clickHandler(e) {
if(e.target.nodeName==="INPUT" || e.target===e.currentTarget) return;
if(e.target.textContent==="-"){
this.setStep(this.step-1);
console.log(this.step);
}else{
this.setStep(this.step+1);
}
console.log(this);
this.dispatch()
}
inputHandler(e){
this.input.value=this.input.value.replace(/\D/g,"");
if(this.ids) return;
this.ids=setTimeout(()=>{
console.log("a:"+this.ids);
clearTimeout(this.ids);
this.ids=undefined;
console.log("c"+this.ids);
this.setStep(this.input.value);
this.dispatch();
},500);
}
dispatch(){
var evt=new Event("change");
evt.step=this.step;
this.dispatchEvent(evt);
}
setStep(_step){
_step=String(_step).replace(/\D/g,"");
_step=~~_step;
this.elem.querySelectorAll("[disabled]").forEach(item=>{
item.removeAttribute("disabled");
})
if(!_step) _step=1;
if(_step>99) _step=99;
if(_step===1) this.elem.firstElementChild.setAttribute("disabled","");
if(_step===99) this.elem.lastElementChild.setAttribute("disabled","");
this.step=_step;
this.input.value=_step;
}
static setCss(){
if(super.setCss()) return;
Utils.setCss(`.stepnumber{
width: 84px;
height: 22px;
position: relative;
}
.stepnumber>div{
width: 17px;
height: 20px;
border: 1px solid #ccc;
text-align: center;
font-size: 14px;
line-height: 20px;
float: left;
user-select: none;
}
.stepnumber>input{
float: left;
width: 42px;
height: 18px;
border: none;
text-align: center;
outline: none;
border-top: 1px solid #CCC;
border-bottom: 1px solid #CCC;
}
.stepnumber>div[disabled]{
color: #CCC;
cursor: not-allowed;
}`)
}
}