管理两个事件监听器的结果

时间:2019-03-14 01:16:36

标签: javascript

我试图取回下拉列表中的选定值,并将其归因于atom.name,以更改原子名称。默认情况下,存在ch2分子,当单击Na时。 Ch2应该替换为Na,但问题是事件侦听器的范围以及管理这两个事件侦听器的能力。负责管理下拉结果的人

var a = document.getElementById('atomDropdown');
a.addEventListener('change', function() {
  console.log(this.value);
}, false);

console.log在这里给出正确的结果, 使用

管理下拉菜单位置的事件监听器
document.body.addEventListener('mouseup', e => {
    let atom = atoms.find(a => distance(a.position, { x: e.pageX, y: e.pageY}) <= a.r)
    atomDropdown.classList.remove('hidden')
    if(atom){
       atomDropdown.style.left = atom.position.x + 'px'
       atomDropdown.style.top = (atom.position.y + atom.r) + 'px'
    }
    console.log(atom.name);
})

没有成功,我想做的就是将atom.name赋予该值。

const canvas = document.createElement('canvas'),
	 context = canvas.getContext('2d'),
	 width = canvas.width = window.innerWidth,
	 height = canvas.height = window.innerHeight,
	 atoms = [],
	 bonds = [],
	 atomDropdown = document.getElementById('atomDropdown')

document.body.appendChild(canvas)

class Atom {
	constructor({ x, y, name }){
		this.position = {}
		this.position.x = x
		this.position.y = y
		this.name = name
		this.r = name.length * 10

		atoms.push(this)
	}

	draw(){
		let { position, name, r } = this,
		    { x, y } = position

		context.fillStyle = '#EEEEEE'
		context.beginPath()
		context.arc(x, y, r, 0, 2 * Math.PI)
		context.fill()


		context.fillStyle = '#000000'
		context.font = '20px sans-serif'
		context.textAlign = 'center'
		context.fillText(name, x, y + 5)
	}
}

class Bond {
	constructor({ atom1, atom2, type }){
		this.atom1 = atom1
		this.atom2 = atom2
		
		bonds.push(this)
	}
	
	draw(){
		let { atom1, atom2 } = this
		
		context.beginPath()
		context.strokeStyle = '#000000'
		context.moveTo(atom1.position.x, atom1.position.y)
		context.lineTo(atom2.position.x, atom2.position.y)
		context.stroke()
	}
}

let hexagon = {
	size: 100,
	x: width/2,
	y: height/2
}

let lastAtom

for (var side = 0; side < 7; side++) {
	let newAtom = new Atom({
		x: hexagon.x + hexagon.size * Math.cos(side * 2 * Math.PI / 6),
		y: hexagon.y + hexagon.size * Math.sin(side * 2 * Math.PI / 6),
		name: 'CH2'
	})
	
	if(lastAtom) new Bond({ atom1: lastAtom, atom2: newAtom })
	if(side == 6) new Bond({ atom1: newAtom, atom2: atoms[0] })
	lastAtom = newAtom
}

function render(){
	context.fillStyle = '#FFFFFF'
	context.fillRect(0,0,width,height)

	bonds.map(b => b.draw())
	atoms.map(a => a.draw())
}

render()

function distance(p1, p2){
	return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))
}
var a = document.getElementById('atomDropdown');
a.addEventListener('change', function() {
  console.log(this.value);
}, false);

document.body.addEventListener('mouseup', e => {
	let atom = atoms.find(a => distance(a.position, { x: e.pageX, y: e.pageY}) <= a.r)
	atomDropdown.classList.remove('hidden')
	if(atom){
	   atomDropdown.style.left = atom.position.x + 'px'
	   atomDropdown.style.top = (atom.position.y + atom.r) + 'px'
	}
	console.log(atom.name);
})
#atomDropdown {
	position: absolute;
	
	&.hidden {
		display: none;
	}
}
<select id="atomDropdown" class="hidden">
	<option>Test1</option>
	<option>Test2</option>
	<option>Test3</option>
</select>

2 个答案:

答案 0 :(得分:1)

似乎想要的行为是更改所单击原子的atom.name的值,并用下拉菜单中的名称替换它。

例如,单击一个CH2原子->从下拉菜单中选择“ Test1”->您单击的原子的this.name值将从“ CH2”更改为“ Test1”。

在这种情况下,问题是如何在atomDropdown的“更改”处理程序中将上一个“鼠标”事件中​​的同一原子作为目标。在这种情况下,您可以在定义中添加新变量:

const canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
atoms = [],
bonds = [],
atomDropdown = document.getElementById('atomDropdown')

var selectedAtom = null

将selectedAtom设置为“ mouseup”处理程序中的原子实例:

document.body.addEventListener('mouseup', e => {
let atom = atoms.find(a => distance(a.position, { x: e.pageX, y: e.pageY}) <= a.r)
atomDropdown.classList.remove('hidden')
if(atom){
   selectedAtom = atom
   atomDropdown.style.left = atom.position.x + 'px'
   atomDropdown.style.top = (atom.position.y + atom.r) + 'px'
}
console.log(atom.name);

})

并在“更改事件”中更新selectedAtom.name:

var a = document.getElementById('atomDropdown');
a.addEventListener('change', function() {
  if (selectedAtom) {
    selectedAtom.name = this.value;
    render(); //added so that the GUI updates when the name value changes
  }
  console.log(this.value);
}, false);

编辑:要立即更新显示在GUI /显示器中的原子名称,还必须在atomDropDown的“ change”事件中更改selectedAtom.name之后调用render()。

答案 1 :(得分:0)

如果我正确地理解了这个问题,那么您正在寻找将下拉菜单的值设置为atom.name吗?

如果是这样,则需要在选项中添加属性“值”,然后可以说类似这样的话:

document.getElementById("atomDropdown").value = atom.name

HTML看起来像这样:

<select id="atomDropdown" class="hidden">
    <option value="Na">Test1</option>
    <option value="Ch2">Test2</option>
    <option value="O2">Test3</option>
</select>