简体   繁体   中英

Dom node insertion/removal without mutation observers

I'm building a Tour component in React whose purpose is to introduce the user to the web app's interface. Parts of the "Tour" involve validating the user's actions, (eg if the current step involves opening a modal, once the user does so, the "Tour" should progress otherwise it should show an error if the user tries to progress by clicking 'Next').

For this I need to detect changes in the DOM, (eg a modal being opened or a div with a specific class appearing) . I've had some ideas about wiring up an 'onNext' function that progresses the tutorial once the user interacts with certain target elements (eg 'Open Modal' button), but this seems like a hack, I want to govern the progression of the tour only by the actual elements present in the DOM not by listening for clicks that will result in the necessary elements showing up eventually.

One of the big constraints is avoiding MutationObservers in addition to usage of jQuery . With that said, I'm interested in hunches about how to validate the dom, how would one use pure javascript and the dom to determine the addition and removal of elements?

I think you're best served by implementing a Flux architecture to handle this. Redux is a good fit.

Create a Redux Reducer for your tour progression. The state of this reducer should be a key that corresponds to the current step of the tour that the user is within.

All components used in the tour should have access to this tour state as a prop. Use this prop to determine functionality. Ie for your example of a dialog that must be opened, the code might look like this, within a relevant component;

openModal(){
    if(this.props.tourStep == 'prompt_modal_open'){
        ActionCreator.progressTourStep();
    }
    // code for actually opening the modal goes here
},

someOtherAction(){
    if(this.props.tourStep == 'prompt_modal_open'){
        //Display error message here
    } else {
        //normal action result here
    }
}

When the user is not taking the tour, simply set tourStep in the reducer to undefined , and any tour related functionality will be turned off.

Alternately, if you want to keep your components clean and "dumb", you can put this logic directly into the action creator with the help of Redux-Thunk;

ActionCreator.openModal = function(){
    return function(dispatch, getState){
        var state = getState();
        if(state.tourStep == 'prompt_modal_open'){
            dispatch({type: 'progress_tour_step'});
        }
        dispatch({type: 'open_modal'});
    }
}

ActionCreator.someOtherAction = function(){
    return function(dispatch, getState){
        var state = getState();
        if(state.tourStep != undefined){
            dispatch({type: 'show_error'});
        } else {
            dispatch({type: 'some_other_action_type'});
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM