admin管理员组

文章数量:1332395

I have a function written to open / close a div using a placeholder for a hyperlink.

<a class="button" onclick="show('click-drop')">Open</a>

The onclick event then opens the div.

I have this onclick to close it:

<a class="button" onclick="hide('click-drop')">Close</a>

What I would like to do is have a single placeholder for a hyperlink that switches between the two onclick events. So onclick=show would switch to onclick=hide and vice versa.

I have looked everywhere and cannot find a straightforward solution for my situation.

Revised Question

Here's specifically what I am working with.

function show(target) {
    document.getElementById(target).style.height = '300px';
}
function hide(target) {
    document.getElementById(target).style.height = '0px';
}

<a class="button" onclick="show('click-drop')">Open</a>
<div id="click-drop" style="height:0px">
    <a class="button" onclick="hide('click-drop')">Close</a>
</div>

Click Open and it opens / expands inline height style. Click Close and it closes.

I need to have the onclick toggle, but with Open changing to Close and reverse.

It would be ideal to keep the placement of the links. So the Open link outside the link is hidden until the Close link within the div is clicked.

I appreciate any feedback.

I have a function written to open / close a div using a placeholder for a hyperlink.

<a class="button" onclick="show('click-drop')">Open</a>

The onclick event then opens the div.

I have this onclick to close it:

<a class="button" onclick="hide('click-drop')">Close</a>

What I would like to do is have a single placeholder for a hyperlink that switches between the two onclick events. So onclick=show would switch to onclick=hide and vice versa.

I have looked everywhere and cannot find a straightforward solution for my situation.

Revised Question

Here's specifically what I am working with.

function show(target) {
    document.getElementById(target).style.height = '300px';
}
function hide(target) {
    document.getElementById(target).style.height = '0px';
}

<a class="button" onclick="show('click-drop')">Open</a>
<div id="click-drop" style="height:0px">
    <a class="button" onclick="hide('click-drop')">Close</a>
</div>

Click Open and it opens / expands inline height style. Click Close and it closes.

I need to have the onclick toggle, but with Open changing to Close and reverse.

It would be ideal to keep the placement of the links. So the Open link outside the link is hidden until the Close link within the div is clicked.

I appreciate any feedback.

Share Improve this question edited Nov 18, 2021 at 16:47 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked May 14, 2016 at 23:28 Jarod ThorntonJarod Thornton 4012 gold badges7 silver badges25 bronze badges 2
  • 2 Possible Duplicate: stackoverflow./questions/20997687/… – Stu Furlong Commented May 14, 2016 at 23:34
  • @StuFu I've edited the question. I don't believe it's a duplicate. – Jarod Thornton Commented May 15, 2016 at 0:05
Add a ment  | 

6 Answers 6

Reset to default 2

You could dynamically change the onclick event of the button, but it's already awkward enough that you're using HTML to describe functionality. It would do you even better if you kept all functionality in the JavaScript. Something like this:

var button = document.getElementById("button");
var target = document.getElementById("target");

button.innerHTML = "Close";
button.onclick = function() { hide(target); };

function hide(target) {
  console.log("hiding");
  target.style.display = "none";
  console.log(target);
  button.innerHTML = "Open";
  button.onclick = function() { show(target); };
}

function show(target) {
  target.style.display = "block";
  button.innerHTML = "Close";
  button.onclick = function() { hide(target); };
}
<button id="button">Close</button>
<div id="target">Hello World!</div>

Here is another answer in case you want to use toggle on multiple buttons. This solution uses the button to store the state of its target, and so it uses toggle.call() to modify the value of this within toggle.

It's inspired by jQuery.toggle() and Yuriy Yakym's answer.

for (i = 1; i <= 3; i++) {
  var button = document.getElementById("button"+i),
      target = document.getElementById("target"+i);
  // wrapped in closure because https://stackoverflow./q/8909652/5743988
  (function(_button, _target) {
    _button.onclick = function() {
      toggle.call(_button, _target);
    }
  })(button, target);
}

function toggle(target) {
  this.func = this.func || hide; // if "func" is undefined, assign "hide"
  this.func.call(target); // execute "func"
  this.func = this.func === hide // make "func" call the other thing next time
    ? (this.innerHTML = "Show", show) : (this.innerHTML = "Hide", hide);
}

function hide() {
  this.oldDisplay = window.getComputedStyle(this).display;
  this.style.display = "none"; // better than "height = 0px"
}

function show() {
  this.oldDisplay = this.oldDisplay || "block";
  this.style.display = this.oldDisplay;
}
button, div {
  display: inline-block;
}
<button id="button1">Close</button>
<div id="target1">Hello World!</div>
<br>
<button id="button2">Close</button>
<div id="target2">Hello Again World!</div>
<br>
<button id="button3">Close</button>
<div id="target3">Hello Again Again World!</div>

It's possible to save button's state inside its context. And then, depending on its state call appropriate functions.

function toggle() {
    this.state = !this.state; // false - open; true - closed; default = false (because is not initialized yet)
    this.innerHTML = this.state ? 'Close' : 'Open';
    
    if(this.state) {
        open();
    } else {
        close();
    }
}

function open() {
    alert("Opened");
}

function close() {
    alert("Closed");
}
<a class="button" onclick="toggle.call(this)">Open</a>
<a class="button" onclick="toggle.call(this)">Open</a>
<a class="button" onclick="toggle.call(this)">Open</a>

Either the jQuery toggle or the toggleClass methods should the trick for you.

Edit, per requested, an example:

Say you have a CSS class that looks like this, based on the OP:

.info-box { 
    height: 300px;
}

By using $('#myTarget').toggleClass('info-box'), you will be removing that class or adding it. If you don't have it, you'll add it. If you do have it, you'll remove it. Just like that.

So, a working example I just threw together is here, and it implements toggle() by itself without the need to add any classes, which I believe still acplishes what the OP was seeking resolution for.

https://jsfiddle/bbh9m478/1/

Hope that helps!

I figured out a straightforward solution for this.

When the open link is clicked and the div opens I need the open link to disappear and a close link displayed as a separate element. The same event should work in reverse i.e. close link closes div and displays open link.

While the original code I am working with uses an inline height property to control the open and close, the example below uses display property.

function show(target) {
    document.getElementById(target).style.display = 'block';
}
function hide(target) {
    document.getElementById(target).style.display = 'none';
}
function hideButton() {
    var x = document.getElementById("open");
    x.style.display = "none";
    var x = document.getElementById("close");
    x.style.display = "";
}
function showButton() {
    var x = document.getElementById("open");
    x.style.display = "";
    var x = document.getElementById("close");
    x.style.display = "none";
}

<a class="button" onclick="show('click-drop');hideButton()" id="open">Open</a>

<div id="click-drop" style="display:none">

<a class="button" onclick="hide('click-drop');showButton()" id="close" style="display:none">Close</a>

</div>              

Here it is in the wild - http://iemajen./scripts/mssa/

With this in place I have two more questions.

  1. How would I write this so it uses unobtrusive Javascript to attach behaviour to DOM elements from within the JS solely, meaning separate HTML from JS
  2. How can I write this to be used on multiple divs? I have a dozen divs that will be closed initially and each opened individually using the markup I wrote. I could write it up for each div / unique ids and such, but that seems like more bad practice and I would like to learn the best practice.

Should I just open a new topic for the last question?

After you create your element

var elem = document.querySelector('.js-switch'); var init = new Switchery(elem);

Bind your OnClickMetod to init.switcher like this

$(init.switcher).on('click', OnClickMetod);

本文标签: javascriptSwitch onclick Event onclickStack Overflow